parent
13449605eb
commit
5e6f92f7bc
9 changed files with 280 additions and 2 deletions
@ -0,0 +1,206 @@ |
||||
/* ============================================================
|
||||
* Falkon - Qt web browser |
||||
* Copyright (C) 2019 David Rosca <nowrep@gmail.com> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */ |
||||
#include "ocssupport.h" |
||||
#include "pluginproxy.h" |
||||
#include "datapaths.h" |
||||
#include "networkmanager.h" |
||||
#include "desktopnotificationsfactory.h" |
||||
#include "mainapplication.h" |
||||
|
||||
#include <QDir> |
||||
#include <QBuffer> |
||||
#include <QUrlQuery> |
||||
#include <QNetworkReply> |
||||
|
||||
#include <KArchive/KZip> |
||||
|
||||
Q_GLOBAL_STATIC(OcsSupport, qz_ocs_support) |
||||
|
||||
OcsSupport::OcsSupport(QObject *parent) |
||||
: QObject(parent) |
||||
{ |
||||
} |
||||
|
||||
bool OcsSupport::handleUrl(const QUrl &url) |
||||
{ |
||||
if (url.host() != QL1S("install")) { |
||||
return false; |
||||
} |
||||
|
||||
QUrl fileUrl; |
||||
QString fileType; |
||||
QString fileName; |
||||
|
||||
const auto items = QUrlQuery(url).queryItems(QUrl::FullyDecoded); |
||||
for (const auto &item : items) { |
||||
if (item.first == QL1S("url")) { |
||||
fileUrl = QUrl(item.second); |
||||
} else if (item.first == QL1S("type")) { |
||||
fileType = item.second; |
||||
} else if (item.first == QL1S("filename")) { |
||||
fileName = item.second; |
||||
} |
||||
} |
||||
|
||||
if (!fileType.startsWith(QL1S("falkon_"))) { |
||||
return false; |
||||
} |
||||
|
||||
if (fileType != QL1S("falkon_themes") && fileType != QL1S("falkon_extensions")) { |
||||
qWarning() << "Unsupported type" << fileType; |
||||
return false; |
||||
} |
||||
|
||||
if (!fileUrl.isValid()) { |
||||
qWarning() << "Invalid url" << fileUrl << url; |
||||
return false; |
||||
} |
||||
|
||||
qInfo() << "Downloading" << fileUrl; |
||||
|
||||
QNetworkReply *reply = mApp->networkManager()->get(QNetworkRequest(fileUrl)); |
||||
connect(reply, &QNetworkReply::finished, this, [=]() { |
||||
reply->deleteLater(); |
||||
if (reply->error() != QNetworkReply::NoError) { |
||||
qWarning() << "Error downloading" << fileUrl << reply->error() << reply->errorString(); |
||||
return; |
||||
} |
||||
QBuffer buf; |
||||
buf.setData(reply->readAll()); |
||||
KZip zip(&buf); |
||||
if (!zip.open(QIODevice::ReadOnly)) { |
||||
qWarning() << "Failed to open archive"; |
||||
return; |
||||
} |
||||
QString notifyMessage; |
||||
if (fileType == QL1S("falkon_themes")) { |
||||
installTheme(zip.directory()); |
||||
} else if (fileType == QL1S("falkon_extensions")) { |
||||
installExtension(zip.directory()); |
||||
} |
||||
}); |
||||
|
||||
return true; |
||||
} |
||||
|
||||
// static
|
||||
OcsSupport *OcsSupport::instance() |
||||
{ |
||||
return qz_ocs_support(); |
||||
} |
||||
|
||||
void OcsSupport::installTheme(const KArchiveDirectory *directory) |
||||
{ |
||||
auto showError = []() { |
||||
mApp->desktopNotifications()->showNotification(tr("Installation failed"), tr("Failed to install theme")); |
||||
}; |
||||
|
||||
if (directory->entries().size() != 1) { |
||||
qWarning() << "Invalid archive format"; |
||||
showError(); |
||||
return; |
||||
} |
||||
|
||||
const QString name = directory->entries().at(0); |
||||
const KArchiveEntry *entry = directory->entry(name); |
||||
if (!entry || !entry->isDirectory()) { |
||||
qWarning() << "Invalid archive format"; |
||||
showError(); |
||||
return; |
||||
} |
||||
|
||||
const QString targetDir = DataPaths::path(DataPaths::Config) + QL1S("/themes"); |
||||
QDir().mkpath(targetDir); |
||||
|
||||
if (QFileInfo::exists(targetDir + QL1C('/') + name)) { |
||||
qWarning() << "Theme" << name << "already exists"; |
||||
mApp->desktopNotifications()->showNotification(tr("Installation failed"), tr("Theme is already installed")); |
||||
return; |
||||
} |
||||
|
||||
if (!directory->copyTo(targetDir)) { |
||||
qWarning() << "Failed to copy theme to" << targetDir; |
||||
showError(); |
||||
return; |
||||
} |
||||
|
||||
qInfo() << "Theme installed to" << targetDir; |
||||
|
||||
mApp->desktopNotifications()->showNotification(tr("Theme installed"), tr("Theme was successfully installed")); |
||||
} |
||||
|
||||
void OcsSupport::installExtension(const KArchiveDirectory *directory) |
||||
{ |
||||
auto showError = []() { |
||||
mApp->desktopNotifications()->showNotification(tr("Installation failed"), tr("Failed to install extension")); |
||||
}; |
||||
|
||||
if (directory->entries().size() != 1) { |
||||
qWarning() << "Invalid archive format"; |
||||
showError(); |
||||
return; |
||||
} |
||||
|
||||
const QString name = directory->entries().at(0); |
||||
const KArchiveEntry *entry = directory->entry(name); |
||||
if (!entry || !entry->isDirectory()) { |
||||
qWarning() << "Invalid archive format"; |
||||
showError(); |
||||
return; |
||||
} |
||||
|
||||
QString type; |
||||
const QStringList files = static_cast<const KArchiveDirectory*>(entry)->entries(); |
||||
if (files.contains(QL1S("__init__.py"))) { |
||||
type = QSL("python"); |
||||
} else if (files.contains(QL1S("main.qml"))) { |
||||
type = QSL("qml"); |
||||
} |
||||
|
||||
if (type.isEmpty()) { |
||||
qWarning() << "Unsupported extension type"; |
||||
showError(); |
||||
return; |
||||
} |
||||
|
||||
const QString targetDir = DataPaths::path(DataPaths::Config) + QL1S("/plugins/") + type; |
||||
QDir().mkpath(targetDir); |
||||
|
||||
if (QFileInfo::exists(targetDir + QL1S("/") + name)) { |
||||
qWarning() << "Extension" << name << "already exists"; |
||||
mApp->desktopNotifications()->showNotification(tr("Installation failed"), tr("Extension is already installed")); |
||||
return; |
||||
} |
||||
|
||||
if (!directory->copyTo(targetDir)) { |
||||
qWarning() << "Failed to copy extension to" << targetDir; |
||||
showError(); |
||||
return; |
||||
} |
||||
|
||||
qInfo() << "Extension installed to" << targetDir; |
||||
|
||||
const QString fullId = QSL("%1:%2/%3").arg(type, targetDir, name); |
||||
if (!mApp->plugins()->addPlugin(fullId)) { |
||||
qWarning() << "Failed to add plugin" << fullId; |
||||
showError(); |
||||
return; |
||||
} |
||||
|
||||
mApp->desktopNotifications()->showNotification(tr("Extension installed"), tr("Extension was successfully installed")); |
||||
} |
||||
@ -0,0 +1,40 @@ |
||||
/* ============================================================
|
||||
* Falkon - Qt web browser |
||||
* Copyright (C) 2019 David Rosca <nowrep@gmail.com> |
||||
* |
||||
* This program is free software: you can redistribute it and/or modify |
||||
* it under the terms of the GNU General Public License as published by |
||||
* the Free Software Foundation, either version 3 of the License, or |
||||
* (at your option) any later version. |
||||
* |
||||
* This program is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
* GNU General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU General Public License |
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
* ============================================================ */ |
||||
#pragma once |
||||
|
||||
#include "qzcommon.h" |
||||
|
||||
#include <QObject> |
||||
|
||||
class KArchiveDirectory; |
||||
|
||||
class OcsSupport : public QObject |
||||
{ |
||||
Q_OBJECT |
||||
|
||||
public: |
||||
explicit OcsSupport(QObject *parent = nullptr); |
||||
|
||||
bool handleUrl(const QUrl &url); |
||||
|
||||
static OcsSupport *instance(); |
||||
|
||||
private: |
||||
void installTheme(const KArchiveDirectory *directory); |
||||
void installExtension(const KArchiveDirectory *directory); |
||||
}; |
||||
Loading…
Reference in new issue