29#include <QNetworkReply>
35static DesktopFile readMetaData(
const KArchiveDirectory *directory)
37 const KArchiveEntry *entry = directory->entry(
QSL(
"metadata.desktop"));
38 if (!entry || !entry->isFile()) {
39 qWarning() <<
"No metadata.desktop found";
43 static_cast<const KArchiveFile*
>(entry)->copyTo(tempDir);
54 if (url.host() !=
QL1S(
"install")) {
62 const auto items = QUrlQuery(url).queryItems(QUrl::FullyDecoded);
63 for (
const auto &item : items) {
64 if (item.first ==
QL1S(
"url")) {
65 fileUrl = QUrl(item.second);
66 }
else if (item.first ==
QL1S(
"type")) {
67 fileType = item.second;
68 }
else if (item.first ==
QL1S(
"filename")) {
69 fileName = item.second;
73 if (!fileType.startsWith(
QL1S(
"falkon_"))) {
77 if (fileType !=
QL1S(
"falkon_themes") && fileType !=
QL1S(
"falkon_extensions")) {
78 qWarning() <<
"Unsupported type" << fileType;
82 if (!fileUrl.isValid()) {
83 qWarning() <<
"Invalid url" << fileUrl << url;
87 qInfo() <<
"Downloading" << fileUrl;
89 QNetworkReply *reply =
mApp->networkManager()->get(QNetworkRequest(fileUrl));
90 connect(reply, &QNetworkReply::finished,
this, [=]() {
92 if (reply->error() != QNetworkReply::NoError) {
93 qWarning() <<
"Error downloading" << fileUrl << reply->error() << reply->errorString();
97 buf.setData(reply->readAll());
99 if (!zip.open(QIODevice::ReadOnly)) {
100 qWarning() <<
"Failed to open archive";
103 QString notifyMessage;
104 if (fileType ==
QL1S(
"falkon_themes")) {
105 installTheme(zip.directory());
106 }
else if (fileType ==
QL1S(
"falkon_extensions")) {
107 installExtension(zip.directory());
117 return qz_ocs_support();
120void OcsSupport::installTheme(
const KArchiveDirectory *directory)
122 auto showError = []() {
123 mApp->desktopNotifications()->showNotification(tr(
"Installation failed"), tr(
"Failed to install theme"));
126 if (directory->entries().size() != 1) {
127 qWarning() <<
"Invalid archive format";
132 const QString name = directory->entries().at(0);
133 const KArchiveEntry *entry = directory->entry(name);
134 if (!entry || !entry->isDirectory()) {
135 qWarning() <<
"Invalid archive format";
140 const DesktopFile metaData = readMetaData(
static_cast<const KArchiveDirectory*
>(entry));
143 QDir().mkpath(targetDir);
145 if (QFileInfo::exists(targetDir +
QL1C(
'/') + name)) {
146 qWarning() <<
"Theme" << name <<
"already exists";
147 mApp->desktopNotifications()->showNotification(tr(
"Installation failed"), tr(
"Theme is already installed"));
151 if (!directory->copyTo(targetDir)) {
152 qWarning() <<
"Failed to copy theme to" << targetDir;
157 qInfo() <<
"Theme installed to" << targetDir;
159 mApp->desktopNotifications()->showNotification(tr(
"Theme installed"), tr(
"'%1' was successfully installed").arg(metaData.
name()));
162void OcsSupport::installExtension(
const KArchiveDirectory *directory)
164 auto showError = []() {
165 mApp->desktopNotifications()->showNotification(tr(
"Installation failed"), tr(
"Failed to install extension"));
168 if (directory->entries().size() != 1) {
169 qWarning() <<
"Invalid archive format";
174 const QString name = directory->entries().at(0);
175 const KArchiveEntry *entry = directory->entry(name);
176 if (!entry || !entry->isDirectory()) {
177 qWarning() <<
"Invalid archive format";
182 const DesktopFile metaData = readMetaData(
static_cast<const KArchiveDirectory*
>(entry));
183 const QString extensionType = metaData.
value(
QSL(
"X-Falkon-Type")).toString();
186 if (extensionType ==
QL1S(
"Extension/Python")) {
187 type =
QSL(
"python");
188 }
else if (extensionType ==
QL1S(
"Extension/Qml")) {
192 if (type.isEmpty()) {
193 qWarning() <<
"Unsupported extension type" << extensionType;
199 QDir().mkpath(targetDir);
201 if (QFileInfo::exists(targetDir +
QL1S(
"/") + name)) {
202 qWarning() <<
"Extension" << name <<
"already exists";
203 mApp->desktopNotifications()->showNotification(tr(
"Installation failed"), tr(
"Extension is already installed"));
207 if (!directory->copyTo(targetDir)) {
208 qWarning() <<
"Failed to copy extension to" << targetDir;
213 qInfo() <<
"Extension installed to" << targetDir;
215 const QString fullId =
QSL(
"%1:%2/%3").arg(type, targetDir, name);
216 if (!
mApp->plugins()->addPlugin(fullId)) {
217 qWarning() <<
"Failed to add plugin" << fullId;
222 mApp->desktopNotifications()->showNotification(tr(
"Extension installed"), tr(
"'%1' was successfully installed").arg(metaData.
name()));
static QString path(Path type)
QVariant value(const QString &key, bool localized=false) const
static OcsSupport * instance()
bool handleUrl(const QUrl &url)
OcsSupport(QObject *parent=nullptr)