aboutsummaryrefslogtreecommitdiffstats
path: root/community/discover/0001-Add-support-for-Alpine-Linux-apk-backend.patch
diff options
context:
space:
mode:
Diffstat (limited to 'community/discover/0001-Add-support-for-Alpine-Linux-apk-backend.patch')
-rw-r--r--community/discover/0001-Add-support-for-Alpine-Linux-apk-backend.patch9352
1 files changed, 0 insertions, 9352 deletions
diff --git a/community/discover/0001-Add-support-for-Alpine-Linux-apk-backend.patch b/community/discover/0001-Add-support-for-Alpine-Linux-apk-backend.patch
deleted file mode 100644
index a555380d3ef..00000000000
--- a/community/discover/0001-Add-support-for-Alpine-Linux-apk-backend.patch
+++ /dev/null
@@ -1,9352 +0,0 @@
-From 18813d11b907ed81bfe1ba79ee3efb93fa53a6e1 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Sun, 12 Jan 2020 01:02:39 +0300
-Subject: [PATCH 01/62] Initial support for AlpineAPK backend
-
----
- .../AlpineApkBackend/AlpineApkBackend.cpp | 191 +++++++++++++++
- .../AlpineApkBackend/AlpineApkBackend.h | 66 ++++++
- .../AlpineApkBackend/AlpineApkResource.cpp | 222 ++++++++++++++++++
- .../AlpineApkBackend/AlpineApkResource.h | 77 ++++++
- .../backends/AlpineApkBackend/CMakeLists.txt | 28 +++
- libdiscover/backends/CMakeLists.txt | 11 +
- 6 files changed, 595 insertions(+)
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
- create mode 100644 libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-new file mode 100644
-index 00000000..aa1aacab
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -0,0 +1,191 @@
-+/***************************************************************************
-+ * Copyright © 2019 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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 "AlpineApkBackend.h"
-+#include "AlpineApkResource.h"
-+//#include "DummyReviewsBackend.h"
-+//#include "DummyTransaction.h"
-+//#include "DummySourcesBackend.h"
-+#include <resources/StandardBackendUpdater.h>
-+#include <resources/SourcesModel.h>
-+#include <Transaction/Transaction.h>
-+
-+#include <KAboutData>
-+#include <KLocalizedString>
-+#include <KPluginFactory>
-+#include <KConfigGroup>
-+#include <KSharedConfig>
-+#include <QDebug>
-+#include <QThread>
-+#include <QTimer>
-+#include <QAction>
-+
-+DISCOVER_BACKEND_PLUGIN(AlpineApkBackend)
-+
-+AlpineApkBackend::AlpineApkBackend(QObject* parent)
-+ : AbstractResourcesBackend(parent)
-+ , m_updater(new StandardBackendUpdater(this))
-+ //, m_reviews(new DummyReviewsBackend(this))
-+ , m_fetching(true)
-+ , m_startElements(120)
-+{
-+ QTimer::singleShot(500, this, &AlpineApkBackend::toggleFetching);
-+ //connect(m_reviews, &DummyReviewsBackend::ratingsReady, this, &AbstractResourcesBackend::emitRatingsReady);
-+ connect(m_updater, &StandardBackendUpdater::updatesCountChanged, this, &AlpineApkBackend::updatesCountChanged);
-+
-+ populate(QStringLiteral("Dummy"));
-+ //if (!m_fetching)
-+ // m_reviews->initialize();
-+
-+ //SourcesModel::global()->addSourcesBackend(new DummySourcesBackend(this));
-+}
-+
-+void AlpineApkBackend::populate(const QString& n)
-+{
-+ const int start = m_resources.count();
-+ for(int i=start; i<start+m_startElements; i++) {
-+ const QString name = n+QLatin1Char(' ')+QString::number(i);
-+ AlpineApkResource* res = new AlpineApkResource(name, AbstractResource::Application, this);
-+ res->setSize(100+(m_startElements-i));
-+ res->setState(AbstractResource::State(1+(i%3)));
-+ m_resources.insert(name.toLower(), res);
-+ connect(res, &AlpineApkResource::stateChanged, this, &AlpineApkBackend::updatesCountChanged);
-+ }
-+
-+ for(int i=start; i<start+m_startElements; i++) {
-+ const QString name = QLatin1String("addon")+QString::number(i);
-+ AlpineApkResource* res = new AlpineApkResource(name, AbstractResource::Addon, this);
-+ res->setState(AbstractResource::State(1+(i%3)));
-+ res->setSize(300+(m_startElements-i));
-+ m_resources.insert(name, res);
-+ connect(res, &AlpineApkResource::stateChanged, this, &AlpineApkBackend::updatesCountChanged);
-+ }
-+
-+ for(int i=start; i<start+m_startElements; i++) {
-+ const QString name = QLatin1String("techie")+QString::number(i);
-+ AlpineApkResource* res = new AlpineApkResource(name, AbstractResource::Technical, this);
-+ res->setState(AbstractResource::State(1+(i%3)));
-+ res->setSize(300+(m_startElements-i));
-+ m_resources.insert(name, res);
-+ connect(res, &AlpineApkResource::stateChanged, this, &AlpineApkBackend::updatesCountChanged);
-+ }
-+}
-+
-+void AlpineApkBackend::toggleFetching()
-+{
-+ m_fetching = !m_fetching;
-+// qDebug() << "fetching..." << m_fetching;
-+ emit fetchingChanged();
-+ //if (!m_fetching)
-+ // m_reviews->initialize();
-+}
-+
-+int AlpineApkBackend::updatesCount() const
-+{
-+ return m_updater->updatesCount();
-+}
-+
-+ResultsStream* AlpineApkBackend::search(const AbstractResourcesBackend::Filters& filter)
-+{
-+ QVector<AbstractResource*> ret;
-+ if (!filter.resourceUrl.isEmpty())
-+ return findResourceByPackageName(filter.resourceUrl);
-+ else foreach(AbstractResource* r, m_resources) {
-+ if (r->type() == AbstractResource::Technical && filter.state != AbstractResource::Upgradeable) {
-+ continue;
-+ }
-+
-+ if (r->state() < filter.state)
-+ continue;
-+
-+ if(r->name().contains(filter.search, Qt::CaseInsensitive) || r->comment().contains(filter.search, Qt::CaseInsensitive))
-+ ret += r;
-+ }
-+ return new ResultsStream(QStringLiteral("DummyStream"), ret);
-+}
-+
-+ResultsStream * AlpineApkBackend::findResourceByPackageName(const QUrl& search)
-+{
-+ if(search.isLocalFile()) {
-+ AlpineApkResource* res = new AlpineApkResource(search.fileName(), AbstractResource::Technical, this);
-+ res->setSize(666);
-+ res->setState(AbstractResource::None);
-+ m_resources.insert(res->packageName(), res);
-+ connect(res, &AlpineApkResource::stateChanged, this, &AlpineApkBackend::updatesCountChanged);
-+ return new ResultsStream(QStringLiteral("DummyStream-local"), { res });
-+ }
-+
-+ auto res = search.scheme() == QLatin1String("dummy") ? m_resources.value(search.host().replace(QLatin1Char('.'), QLatin1Char(' '))) : nullptr;
-+ if (!res) {
-+ return new ResultsStream(QStringLiteral("DummyStream"), {});
-+ } else
-+ return new ResultsStream(QStringLiteral("DummyStream"), { res });
-+}
-+
-+AbstractBackendUpdater* AlpineApkBackend::backendUpdater() const
-+{
-+ return m_updater;
-+}
-+
-+AbstractReviewsBackend* AlpineApkBackend::reviewsBackend() const
-+{
-+ //return m_reviews;
-+ return nullptr;
-+}
-+
-+Transaction* AlpineApkBackend::installApplication(AbstractResource* app, const AddonList& addons)
-+{
-+ //return new DummyTransaction(qobject_cast<AlpineApkResource*>(app), addons, Transaction::InstallRole);
-+ return nullptr;
-+}
-+
-+Transaction* AlpineApkBackend::installApplication(AbstractResource* app)
-+{
-+ //return new DummyTransaction(qobject_cast<AlpineApkResource*>(app), Transaction::InstallRole);
-+ return nullptr;
-+}
-+
-+Transaction* AlpineApkBackend::removeApplication(AbstractResource* app)
-+{
-+ //return new DummyTransaction(qobject_cast<AlpineApkResource*>(app), Transaction::RemoveRole);
-+ return nullptr;
-+}
-+
-+void AlpineApkBackend::checkForUpdates()
-+{
-+ if(m_fetching)
-+ return;
-+ toggleFetching();
-+ populate(QStringLiteral("Moar"));
-+ QTimer::singleShot(500, this, &AlpineApkBackend::toggleFetching);
-+ qDebug() << "AlpineApkBackend::checkForUpdates";
-+}
-+
-+QString AlpineApkBackend::displayName() const
-+{
-+ return QStringLiteral("Dummy");
-+}
-+
-+bool AlpineApkBackend::hasApplications() const
-+{
-+ return true;
-+}
-+
-+#include "AlpineApkBackend.moc"
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-new file mode 100644
-index 00000000..96fe234d
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-@@ -0,0 +1,66 @@
-+/***************************************************************************
-+ * Copyright © 2019 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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/>. *
-+ ***************************************************************************/
-+
-+#ifndef AlpineApkBackend_H
-+#define AlpineApkBackend_H
-+
-+#include <resources/AbstractResourcesBackend.h>
-+#include <QVariantList>
-+
-+class DummyReviewsBackend;
-+class StandardBackendUpdater;
-+class AlpineApkResource;
-+class AlpineApkBackend : public AbstractResourcesBackend
-+{
-+Q_OBJECT
-+Q_PROPERTY(int startElements MEMBER m_startElements)
-+public:
-+ explicit AlpineApkBackend(QObject* parent = nullptr);
-+
-+ int updatesCount() const override;
-+ AbstractBackendUpdater* backendUpdater() const override;
-+ AbstractReviewsBackend* reviewsBackend() const override;
-+ ResultsStream* search(const AbstractResourcesBackend::Filters & search) override;
-+ ResultsStream * findResourceByPackageName(const QUrl& search);
-+ QHash<QString, AlpineApkResource*> resources() const { return m_resources; }
-+ bool isValid() const override { return true; } // No external file dependencies that could cause runtime errors
-+
-+ Transaction* installApplication(AbstractResource* app) override;
-+ Transaction* installApplication(AbstractResource* app, const AddonList& addons) override;
-+ Transaction* removeApplication(AbstractResource* app) override;
-+ bool isFetching() const override { return m_fetching; }
-+ void checkForUpdates() override;
-+ QString displayName() const override;
-+ bool hasApplications() const override;
-+
-+public Q_SLOTS:
-+ void toggleFetching();
-+
-+private:
-+ void populate(const QString& name);
-+
-+ QHash<QString, AlpineApkResource*> m_resources;
-+ StandardBackendUpdater* m_updater;
-+ DummyReviewsBackend* m_reviews;
-+ bool m_fetching;
-+ int m_startElements;
-+};
-+
-+#endif // AlpineApkBackend_H
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-new file mode 100644
-index 00000000..d1cceaaa
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-@@ -0,0 +1,222 @@
-+/***************************************************************************
-+ * Copyright © 2019 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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 "AlpineApkResource.h"
-+#include <Transaction/AddonList.h>
-+#include <krandom.h>
-+#include <QDesktopServices>
-+#include <QStringList>
-+#include <QTimer>
-+
-+Q_GLOBAL_STATIC_WITH_ARGS(QVector<QString>, s_icons,
-+ ({ QLatin1String("kdevelop"),
-+ QLatin1String("kalgebra"),
-+ QLatin1String("kmail"),
-+ QLatin1String("akregator"),
-+ QLatin1String("korganizer") }))
-+
-+AlpineApkResource::AlpineApkResource(
-+ QString name,
-+ AbstractResource::Type type,
-+ AbstractResourcesBackend* parent)
-+ : AbstractResource(parent)
-+ , m_name(std::move(name))
-+ , m_state(State::Broken)
-+ , m_iconName((*s_icons)[KRandom::random() % s_icons->size()])
-+ , m_addons({ PackageState(QStringLiteral("a"), QStringLiteral("aaaaaa"), false),
-+ PackageState(QStringLiteral("b"), QStringLiteral("aaaaaa"), false),
-+ PackageState(QStringLiteral("c"), QStringLiteral("aaaaaa"), false)})
-+ , m_type(type)
-+{
-+ const int nofScreenshots = KRandom::random() % 5;
-+ m_screenshots = QList<QUrl>{
-+ QUrl(QStringLiteral("https://screenshots.debian.net/screenshots/000/014/863/large.png")),
-+ QUrl(QStringLiteral("https://c1.staticflickr.com/9/8479/8166397343_b78106f353_k.jpg")),
-+ QUrl(QStringLiteral("https://c2.staticflickr.com/4/3685/9954407993_dad10a6943_k.jpg")),
-+ QUrl(QStringLiteral("https://c1.staticflickr.com/1/653/22527103378_8ce572e1de_k.jpg")),
-+ QUrl(QStringLiteral("https://images.unsplash.com/photo-1528744598421-b7b93e12df15?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60")),
-+ QUrl(QStringLiteral("https://images.unsplash.com/photo-1552385430-53e6f2028760?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80")),
-+ QUrl(QStringLiteral("https://images.unsplash.com/photo-1506810172640-8a9f77cb1472?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80")),
-+
-+ }.mid(nofScreenshots);
-+ m_screenshotThumbnails = m_screenshots;
-+}
-+
-+QList<PackageState> AlpineApkResource::addonsInformation()
-+{
-+ return m_addons;
-+}
-+
-+QString AlpineApkResource::availableVersion() const
-+{
-+ return QStringLiteral("3.0");
-+}
-+
-+QStringList AlpineApkResource::categories()
-+{
-+ return { QStringLiteral("dummy"),
-+ m_name.endsWith(QLatin1Char('3'))
-+ ? QStringLiteral("three")
-+ : QStringLiteral("notthree") };
-+}
-+
-+QString AlpineApkResource::comment()
-+{
-+ return QStringLiteral("A reasonably short comment ") + name();
-+}
-+
-+int AlpineApkResource::size()
-+{
-+ return m_size;
-+}
-+
-+QUrl AlpineApkResource::homepage()
-+{
-+ return QUrl(QStringLiteral("https://kde.org"));
-+}
-+
-+QUrl AlpineApkResource::helpURL()
-+{
-+ return QUrl(QStringLiteral("http://very-very-excellent-docs.lol"));
-+}
-+
-+QUrl AlpineApkResource::bugURL()
-+{
-+ return QUrl(QStringLiteral("file:///dev/null"));
-+}
-+
-+QUrl AlpineApkResource::donationURL()
-+{
-+ return QUrl(QStringLiteral("https://youtu.be/0o8XMlL8rqY"));
-+}
-+
-+QVariant AlpineApkResource::icon() const
-+{
-+ static const QVector<QVariant> icons = {
-+ QStringLiteral("device-notifier"),
-+ QStringLiteral("media-floppy"),
-+ QStringLiteral("drink-beer")
-+ };
-+ return icons[type()];
-+}
-+
-+QString AlpineApkResource::installedVersion() const
-+{
-+ return QStringLiteral("2.3");
-+}
-+
-+QJsonArray AlpineApkResource::licenses()
-+{
-+ return {
-+ QJsonObject {
-+ { QStringLiteral("name"), QStringLiteral("GPL") },
-+ { QStringLiteral("url"), QStringLiteral("https://kde.org") }
-+ }
-+ };
-+}
-+
-+QString AlpineApkResource::longDescription()
-+{
-+ return QStringLiteral("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur ultricies consequat nulla, ut vulputate nulla ultricies ac. Suspendisse lacinia commodo lacus, non tristique mauris dictum vitae. Sed adipiscing augue nec nisi aliquet viverra. Etiam sit amet nulla in tellus consectetur feugiat. Cras in sem tortor. Fusce a nulla at justo accumsan gravida. Maecenas dui felis, lacinia at ornare sed, aliquam et purus. Sed ut sagittis lacus. Etiam dictum pharetra rhoncus. Suspendisse auctor orci ipsum. Pellentesque vitae urna nec felis consequat lobortis dictum in urna. Phasellus a mi ac leo adipiscing varius eget a felis. Cras magna augue, commodo sed placerat vel, tempus vel ligula. In feugiat quam quis est lobortis sed accumsan nunc malesuada. Mauris quis massa sit amet felis tempus suscipit a quis diam.\n\n"
-+
-+ "Aenean quis nulla erat, vel sagittis sem. Praesent vitae mauris arcu. Cras porttitor, ante at scelerisque sodales, nibh felis consectetur orci, ut hendrerit urna urna non urna. Duis eu magna id mi scelerisque adipiscing. Aliquam sed quam in eros sodales accumsan. Phasellus tempus sagittis suscipit. Aliquam rutrum dictum justo ut viverra. Nulla felis sem, molestie sed scelerisque non, consequat vitae nulla. Aliquam ullamcorper malesuada mi, vel vestibulum magna vulputate eget. In hac habitasse platea dictumst. Cras sed lacus dui, vel semper sem. Aenean sodales porta leo vel fringilla.\n\n"
-+
-+ "Ut tempus massa et urna porta non mollis metus ultricies. Duis nec nulla ac metus auctor porta id et mi. Mauris aliquam nibh a ligula malesuada sed tincidunt nibh varius. Sed felis metus, porta et adipiscing non, faucibus id leo. Donec ipsum nibh, hendrerit eget aliquam nec, tempor ut mauris. Suspendisse potenti. Vestibulum scelerisque adipiscing libero tristique eleifend. Donec quis tortor eget elit mollis iaculis ac sit amet nisi. Proin non massa sed nunc rutrum pellentesque. Sed dui lectus, laoreet sed condimentum id, commodo sed urna.\n\n"
-+
-+ "Praesent tincidunt mattis massa mattis porta. Nullam posuere neque at mauris vestibulum vitae elementum leo sodales. Quisque condimentum lectus in libero luctus egestas. Fusce tempor neque ac dui tincidunt eget viverra quam suscipit. In hac habitasse platea dictumst. Etiam metus mi, adipiscing nec suscipit id, aliquet sed sem. Duis urna ligula, ornare sed vestibulum vel, molestie ac nisi. Morbi varius iaculis ligula. Nunc in augue leo, sit amet aliquam elit. Suspendisse rutrum sem diam. Proin eu orci nisl. Praesent porttitor dignissim est, id fermentum arcu venenatis vitae.\n\n"
-+
-+ "Integer in sapien eget quam vulputate lobortis. Morbi nibh elit, elementum vitae vehicula sed, consequat nec erat. Donec placerat porttitor est ut dapibus. Fusce augue orci, dictum et convallis vel, blandit eu tortor. Phasellus non eros nulla. In iaculis nulla fermentum nulla gravida eu mattis purus consectetur. Integer dui nunc, sollicitudin ac tincidunt nec, hendrerit bibendum nunc. Proin sit amet augue ac velit egestas varius. Sed eu ante quis orci vestibulum sagittis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus vitae urna odio, at molestie leo. In convallis neque vel mi dictum convallis lobortis turpis sagittis.\n\n");
-+}
-+
-+QString AlpineApkResource::name() const
-+{
-+ return m_name;
-+}
-+
-+QString AlpineApkResource::origin() const
-+{
-+ return QStringLiteral("DummySource1");
-+}
-+
-+QString AlpineApkResource::packageName() const
-+{
-+ return m_name;
-+}
-+
-+QString AlpineApkResource::section()
-+{
-+ return QStringLiteral("dummy");
-+}
-+
-+AbstractResource::State AlpineApkResource::state()
-+{
-+ return m_state;
-+}
-+
-+void AlpineApkResource::fetchChangelog()
-+{
-+ QString log = longDescription();
-+ log.replace(QLatin1Char('\n'), QLatin1String("<br />"));
-+
-+ emit changelogFetched(log);
-+}
-+
-+void AlpineApkResource::fetchScreenshots()
-+{
-+ Q_EMIT screenshotsFetched(m_screenshotThumbnails, m_screenshots);
-+}
-+
-+void AlpineApkResource::setState(AbstractResource::State state)
-+{
-+ m_state = state;
-+ emit stateChanged();
-+}
-+
-+void AlpineApkResource::setAddons(const AddonList& addons)
-+{
-+ Q_FOREACH (const QString& toInstall, addons.addonsToInstall()) {
-+ setAddonInstalled(toInstall, true);
-+ }
-+ Q_FOREACH (const QString& toRemove, addons.addonsToRemove()) {
-+ setAddonInstalled(toRemove, false);
-+ }
-+}
-+
-+void AlpineApkResource::setAddonInstalled(const QString& addon, bool installed)
-+{
-+ for(auto & elem : m_addons) {
-+ if(elem.name() == addon) {
-+ elem.setInstalled(installed);
-+ }
-+ }
-+}
-+
-+
-+void AlpineApkResource::invokeApplication() const
-+{
-+ QDesktopServices d;
-+ d.openUrl(QUrl(QStringLiteral("https://projects.kde.org/projects/extragear/sysadmin/muon")));
-+}
-+
-+QUrl AlpineApkResource::url() const
-+{
-+ return QUrl(QLatin1String("dummy://")
-+ + packageName().replace(QLatin1Char(' '), QLatin1Char('.')));
-+}
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-new file mode 100644
-index 00000000..f4ecee4a
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-@@ -0,0 +1,77 @@
-+/***************************************************************************
-+ * Copyright © 2019 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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/>. *
-+ ***************************************************************************/
-+
-+#ifndef ALPINEAPKRESOURCE_H
-+#define ALPINEAPKRESOURCE_H
-+
-+#include <resources/AbstractResource.h>
-+
-+class AddonList;
-+class AlpineApkResource : public AbstractResource
-+{
-+Q_OBJECT
-+public:
-+ explicit AlpineApkResource(QString name, AbstractResource::Type type, AbstractResourcesBackend* parent);
-+
-+ QList<PackageState> addonsInformation() override;
-+ QString section() override;
-+ QString origin() const override;
-+ QString longDescription() override;
-+ QString availableVersion() const override;
-+ QString installedVersion() const override;
-+ QJsonArray licenses() override;
-+ int size() override;
-+ QUrl homepage() override;
-+ QUrl helpURL() override;
-+ QUrl bugURL() override;
-+ QUrl donationURL() override;
-+ QStringList categories() override;
-+ AbstractResource::State state() override;
-+ QVariant icon() const override;
-+ QString comment() override;
-+ QString name() const override;
-+ QString packageName() const override;
-+ AbstractResource::Type type() const override { return m_type; }
-+ bool canExecute() const override { return true; }
-+ void invokeApplication() const override;
-+ void fetchChangelog() override;
-+ void fetchScreenshots() override;
-+ QUrl url() const override;
-+ QString author() const override { return QStringLiteral("BananaPerson"); }
-+ void setState(State state);
-+ void setSize(int size) { m_size = size; }
-+ void setAddons(const AddonList& addons);
-+
-+ void setAddonInstalled(const QString& addon, bool installed);
-+ QString sourceIcon() const override { return QStringLiteral("player-time"); }
-+ QDate releaseDate() const override { return {}; }
-+
-+public:
-+ const QString m_name;
-+ AbstractResource::State m_state;
-+ QList<QUrl> m_screenshots;
-+ QList<QUrl> m_screenshotThumbnails;
-+ QString m_iconName;
-+ QList<PackageState> m_addons;
-+ const AbstractResource::Type m_type;
-+ int m_size;
-+};
-+
-+#endif // ALPINEAPKRESOURCE_H
-diff --git a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-new file mode 100644
-index 00000000..8d1f9a57
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-@@ -0,0 +1,28 @@
-+# add_subdirectory(tests) # no tests yet
-+
-+set(alpineapk-backend_SRCS
-+ AlpineApkResource.cpp
-+ AlpineApkBackend.cpp
-+)
-+
-+add_library(alpineapk-backend MODULE ${alpineapk-backend_SRCS})
-+
-+target_link_libraries(alpineapk-backend PRIVATE
-+ Qt5::Core
-+ Qt5::Widgets
-+ KF5::CoreAddons
-+ KF5::ConfigCore
-+ Discover::Common
-+)
-+
-+install(TARGETS alpineapk-backend DESTINATION ${PLUGIN_INSTALL_DIR}/discover)
-+install(FILES alpineapk-backend-categories.xml DESTINATION ${DATA_INSTALL_DIR}/libdiscover/categories)
-+
-+
-+#add_library(DummyNotifier MODULE DummyNotifier.cpp)
-+
-+#target_link_libraries(DummyNotifier Discover::Notifiers)
-+
-+#set_target_properties(DummyNotifier PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/plasma-discover)
-+
-+#install(TARGETS DummyNotifier DESTINATION ${PLUGIN_INSTALL_DIR}/discover-notifier)
-diff --git a/libdiscover/backends/CMakeLists.txt b/libdiscover/backends/CMakeLists.txt
-index 75bafa17..0feb87b7 100644
---- a/libdiscover/backends/CMakeLists.txt
-+++ b/libdiscover/backends/CMakeLists.txt
-@@ -50,4 +50,15 @@ if(BUILD_RpmOstreeBackend)
- add_subdirectory(RpmOstreeBackend)
- endif()
-
-+# Optional library
-+find_package(ApkQt CONFIG)
-+set_package_properties(ApkQt PROPERTIES
-+ DESCRIPTION "C++/Qt interface library for Alpine package keeper"
-+ URL "https://gitlab.com/postmarketOS/libapk-qt"
-+ PURPOSE "Required to build the Alpine APK backend"
-+ TYPE OPTIONAL)
-
-+option(BUILD_AlpineApkBackend "Build Alpine APK support." "ON")
-+if(BUILD_AlpineApkBackend AND ApkQt_FOUND)
-+ add_subdirectory(AlpineApkBackend)
-+endif()
---
-GitLab
-
-
-From 32cbca7002ea7f02e2b9febd6f9b27feb13e8f0d Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Tue, 14 Jan 2020 15:20:35 +0300
-Subject: [PATCH 02/62] don't install categories file
-
----
- libdiscover/backends/AlpineApkBackend/CMakeLists.txt | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-index 8d1f9a57..118f3db7 100644
---- a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-+++ b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-@@ -16,7 +16,7 @@ target_link_libraries(alpineapk-backend PRIVATE
- )
-
- install(TARGETS alpineapk-backend DESTINATION ${PLUGIN_INSTALL_DIR}/discover)
--install(FILES alpineapk-backend-categories.xml DESTINATION ${DATA_INSTALL_DIR}/libdiscover/categories)
-+#install(FILES alpineapk-backend-categories.xml DESTINATION ${DATA_INSTALL_DIR}/libdiscover/categories)
-
-
- #add_library(DummyNotifier MODULE DummyNotifier.cpp)
---
-GitLab
-
-
-From 08bbf82119f443e009e2ed4dc7ef3524272f1c2f Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Tue, 14 Jan 2020 15:30:43 +0300
-Subject: [PATCH 03/62] tidy up cmakelists and add more sources
-
----
- .../AlpineApkSourcesBackend.cpp | 94 +++++++++++++++++++
- .../AlpineApkSourcesBackend.h | 49 ++++++++++
- .../AlpineApkBackend/AlpineApkTransaction.cpp | 88 +++++++++++++++++
- .../AlpineApkBackend/AlpineApkTransaction.h | 46 +++++++++
- .../backends/AlpineApkBackend/CMakeLists.txt | 45 +++++----
- 5 files changed, 305 insertions(+), 17 deletions(-)
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-new file mode 100644
-index 00000000..3f492185
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-@@ -0,0 +1,94 @@
-+/***************************************************************************
-+ * Copyright © 2019 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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 "AlpineApkSourcesBackend.h"
-+#include <QDebug>
-+#include <QAction>
-+
-+AlpineApkSourcesBackend::AlpineApkSourcesBackend(AbstractResourcesBackend * parent)
-+ : AbstractSourcesBackend(parent)
-+ , m_sources(new QStandardItemModel(this))
-+ , m_testAction(new QAction(QIcon::fromTheme(QStringLiteral("kalgebra")), QStringLiteral("DummyAction"), this))
-+{
-+ for (int i = 0; i<10; ++i)
-+ addSource(QStringLiteral("DummySource%1").arg(i));
-+
-+ connect(m_testAction, &QAction::triggered, [](){ qDebug() << "action triggered!"; });
-+ connect(m_sources, &QStandardItemModel::itemChanged, this, [](QStandardItem* item) { qDebug() << "DummySource changed" << item << item->checkState(); });
-+}
-+
-+QAbstractItemModel* AlpineApkSourcesBackend::sources()
-+{
-+ return m_sources;
-+}
-+
-+bool AlpineApkSourcesBackend::addSource(const QString& id)
-+{
-+ if (id.isEmpty())
-+ return false;
-+
-+ QStandardItem* it = new QStandardItem(id);
-+ it->setData(id, AbstractSourcesBackend::IdRole);
-+ it->setData(QVariant(id + QLatin1Char(' ') + id), Qt::ToolTipRole);
-+ it->setCheckable(true);
-+ it->setCheckState(Qt::Checked);
-+ m_sources->appendRow(it);
-+ return true;
-+}
-+
-+QStandardItem * AlpineApkSourcesBackend::sourceForId(const QString& id) const
-+{
-+ for (int i=0, c=m_sources->rowCount(); i<c; ++i) {
-+ const auto it = m_sources->item(i, 0);
-+ if (it->text() == id)
-+ return it;
-+ }
-+ return nullptr;
-+}
-+
-+bool AlpineApkSourcesBackend::removeSource(const QString& id)
-+{
-+ const auto it = sourceForId(id);
-+ if (!it) {
-+ qWarning() << "couldn't find " << id;
-+ return false;
-+ }
-+ return m_sources->removeRow(it->row());
-+}
-+
-+QVariantList AlpineApkSourcesBackend::actions() const
-+{
-+ return QVariantList() << QVariant::fromValue<QObject*>(m_testAction);
-+}
-+
-+bool AlpineApkSourcesBackend::moveSource(const QString& sourceId, int delta)
-+{
-+ int row = sourceForId(sourceId)->row();
-+ auto prevRow = m_sources->takeRow(row);
-+ Q_ASSERT(!prevRow.isEmpty());
-+
-+ const auto destRow = row + delta;
-+ m_sources->insertRow(destRow, prevRow);
-+ if (destRow == 0 || row == 0)
-+ Q_EMIT firstSourceIdChanged();
-+ if (destRow == m_sources->rowCount() - 1 || row == m_sources->rowCount() - 1)
-+ Q_EMIT lastSourceIdChanged();
-+ return true;
-+}
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h
-new file mode 100644
-index 00000000..48a0d829
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h
-@@ -0,0 +1,49 @@
-+/***************************************************************************
-+ * Copyright © 2019 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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/>. *
-+ ***************************************************************************/
-+
-+#ifndef ALPINEAPKSOURCESBACKEND_H
-+#define ALPINEAPKSOURCESBACKEND_H
-+
-+#include <resources/AbstractSourcesBackend.h>
-+#include <QStandardItemModel>
-+
-+class AlpineApkSourcesBackend : public AbstractSourcesBackend
-+{
-+public:
-+ explicit AlpineApkSourcesBackend(AbstractResourcesBackend *parent);
-+
-+ QAbstractItemModel *sources() override;
-+ bool addSource(const QString &id) override;
-+ bool removeSource(const QString &id) override;
-+ QString idDescription() override { return QStringLiteral("Random weird text"); }
-+ QVariantList actions() const override;
-+ bool supportsAdding() const override { return true; }
-+
-+ bool canMoveSources() const override { return true; }
-+ bool moveSource(const QString &sourceId, int delta) override;
-+
-+private:
-+ QStandardItem* sourceForId(const QString &id) const;
-+
-+ QStandardItemModel* m_sources;
-+ QAction* m_testAction;
-+};
-+
-+#endif // ALPINEAPKSOURCESBACKEND_H
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-new file mode 100644
-index 00000000..8b6b72a5
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-@@ -0,0 +1,88 @@
-+/***************************************************************************
-+ * Copyright © 2019 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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 "AlpineApkTransaction.h"
-+#include "AlpineApkBackend.h"
-+#include "AlpineApkResource.h"
-+#include <QTimer>
-+#include <QDebug>
-+#include <KRandom>
-+
-+// #define TEST_PROCEED
-+
-+AlpineApkTransaction::AlpineApkTransaction(AlpineApkResource* app, Role role)
-+ : AlpineApkTransaction(app, {}, role)
-+{
-+}
-+
-+AlpineApkTransaction::AlpineApkTransaction(AlpineApkResource* app, const AddonList& addons, Transaction::Role role)
-+ : Transaction(app->backend(), app, role, addons)
-+ , m_app(app)
-+{
-+ setCancellable(true);
-+ setStatus(DownloadingStatus);
-+ iterateTransaction();
-+}
-+
-+void AlpineApkTransaction::iterateTransaction()
-+{
-+ if (!m_iterate)
-+ return;
-+
-+ if(progress()<100) {
-+ setProgress(qBound(0, progress()+(KRandom::random()%30), 100));
-+ QTimer::singleShot(/*KRandom::random()%*/100, this, &AlpineApkTransaction::iterateTransaction);
-+ } else if (status() == DownloadingStatus) {
-+ setStatus(CommittingStatus);
-+ QTimer::singleShot(/*KRandom::random()%*/100, this, &AlpineApkTransaction::iterateTransaction);
-+ } else {
-+ finishTransaction();
-+ }
-+}
-+
-+void AlpineApkTransaction::proceed()
-+{
-+ finishTransaction();
-+}
-+
-+void AlpineApkTransaction::cancel()
-+{
-+ m_iterate = false;
-+
-+ setStatus(CancelledStatus);
-+}
-+
-+void AlpineApkTransaction::finishTransaction()
-+{
-+ AbstractResource::State newState;
-+ switch(role()) {
-+ case InstallRole:
-+ case ChangeAddonsRole:
-+ newState = AbstractResource::Installed;
-+ break;
-+ case RemoveRole:
-+ newState = AbstractResource::None;
-+ break;
-+ }
-+ m_app->setAddons(addons());
-+ m_app->setState(newState);
-+ setStatus(DoneStatus);
-+ deleteLater();
-+}
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h
-new file mode 100644
-index 00000000..49102dd5
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h
-@@ -0,0 +1,46 @@
-+/***************************************************************************
-+ * Copyright © 2019 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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/>. *
-+ ***************************************************************************/
-+
-+#ifndef ALPINEAPKTRANSACTION_H
-+#define ALPINEAPKTRANSACTION_H
-+
-+#include <Transaction/Transaction.h>
-+
-+class AlpineApkResource;
-+class AlpineApkTransaction : public Transaction
-+{
-+ Q_OBJECT
-+ public:
-+ AlpineApkTransaction(AlpineApkResource* app, Role role);
-+ AlpineApkTransaction(AlpineApkResource* app, const AddonList& list, Role role);
-+
-+ void cancel() override;
-+ void proceed() override;
-+
-+ private Q_SLOTS:
-+ void iterateTransaction();
-+ void finishTransaction();
-+
-+ private:
-+ bool m_iterate = true;
-+ AlpineApkResource* m_app;
-+};
-+
-+#endif // ALPINEAPKTRANSACTION_H
-diff --git a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-index 118f3db7..635009ab 100644
---- a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-+++ b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-@@ -1,28 +1,39 @@
- # add_subdirectory(tests) # no tests yet
-
--set(alpineapk-backend_SRCS
-- AlpineApkResource.cpp
-- AlpineApkBackend.cpp
-+add_library(
-+ alpineapk-backend
-+ MODULE
-+ AlpineApkBackend.cpp
-+ AlpineApkBackend.h
-+ AlpineApkResource.cpp
-+ AlpineApkResource.h
-+ AlpineApkSourcesBackend.cpp
-+ AlpineApkSourcesBackend.h
-+ AlpineApkTransaction.cpp
-+ AlpineApkTransaction.h
- )
-
--add_library(alpineapk-backend MODULE ${alpineapk-backend_SRCS})
--
--target_link_libraries(alpineapk-backend PRIVATE
-- Qt5::Core
-- Qt5::Widgets
-- KF5::CoreAddons
-- KF5::ConfigCore
-- Discover::Common
-+target_link_libraries(
-+ alpineapk-backend
-+ PRIVATE
-+ Qt5::Core
-+ Qt5::Widgets
-+ KF5::CoreAddons
-+ KF5::ConfigCore
-+ Discover::Common
- )
-
--install(TARGETS alpineapk-backend DESTINATION ${PLUGIN_INSTALL_DIR}/discover)
--#install(FILES alpineapk-backend-categories.xml DESTINATION ${DATA_INSTALL_DIR}/libdiscover/categories)
-+install(
-+ TARGETS alpineapk-backend
-+ DESTINATION ${PLUGIN_INSTALL_DIR}/discover
-+)
-
-+# install(FILES alpineapk-backend-categories.xml DESTINATION ${DATA_INSTALL_DIR}/libdiscover/categories)
-
--#add_library(DummyNotifier MODULE DummyNotifier.cpp)
-+# add_library(AlpineApkNotifier MODULE AlpineApkNotifier.cpp)
-
--#target_link_libraries(DummyNotifier Discover::Notifiers)
-+# target_link_libraries(AlpineApkNotifier Discover::Notifiers)
-
--#set_target_properties(DummyNotifier PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/plasma-discover)
-+# set_target_properties(AlpineApkNotifier PROPERTIES INSTALL_RPATH ${CMAKE_INSTALL_FULL_LIBDIR}/plasma-discover)
-
--#install(TARGETS DummyNotifier DESTINATION ${PLUGIN_INSTALL_DIR}/discover-notifier)
-+# install(TARGETS AlpineApkNotifier DESTINATION ${PLUGIN_INSTALL_DIR}/discover-notifier)
---
-GitLab
-
-
-From 64f2f887e35e1f8ca389f9766918a36778fad983 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Tue, 14 Jan 2020 15:34:19 +0300
-Subject: [PATCH 04/62] Make use of new sources/classes
-
----
- .../AlpineApkBackend/AlpineApkBackend.cpp | 18 ++++++++----------
- .../AlpineApkBackend/AlpineApkBackend.h | 9 +++++----
- 2 files changed, 13 insertions(+), 14 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index aa1aacab..1df00d72 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -21,8 +21,9 @@
- #include "AlpineApkBackend.h"
- #include "AlpineApkResource.h"
- //#include "DummyReviewsBackend.h"
--//#include "DummyTransaction.h"
--//#include "DummySourcesBackend.h"
-+#include "AlpineApkTransaction.h"
-+#include "AlpineApkSourcesBackend.h"
-+
- #include <resources/StandardBackendUpdater.h>
- #include <resources/SourcesModel.h>
- #include <Transaction/Transaction.h>
-@@ -54,7 +55,7 @@ AlpineApkBackend::AlpineApkBackend(QObject* parent)
- //if (!m_fetching)
- // m_reviews->initialize();
-
-- //SourcesModel::global()->addSourcesBackend(new DummySourcesBackend(this));
-+ SourcesModel::global()->addSourcesBackend(new AlpineApkSourcesBackend(this));
- }
-
- void AlpineApkBackend::populate(const QString& n)
-@@ -152,20 +153,17 @@ AbstractReviewsBackend* AlpineApkBackend::reviewsBackend() const
-
- Transaction* AlpineApkBackend::installApplication(AbstractResource* app, const AddonList& addons)
- {
-- //return new DummyTransaction(qobject_cast<AlpineApkResource*>(app), addons, Transaction::InstallRole);
-- return nullptr;
-+ return new AlpineApkTransaction(qobject_cast<AlpineApkResource*>(app), addons, Transaction::InstallRole);
- }
-
- Transaction* AlpineApkBackend::installApplication(AbstractResource* app)
- {
-- //return new DummyTransaction(qobject_cast<AlpineApkResource*>(app), Transaction::InstallRole);
-- return nullptr;
-+ return new AlpineApkTransaction(qobject_cast<AlpineApkResource*>(app), Transaction::InstallRole);
- }
-
- Transaction* AlpineApkBackend::removeApplication(AbstractResource* app)
- {
-- //return new DummyTransaction(qobject_cast<AlpineApkResource*>(app), Transaction::RemoveRole);
-- return nullptr;
-+ return new AlpineApkTransaction(qobject_cast<AlpineApkResource*>(app), Transaction::RemoveRole);
- }
-
- void AlpineApkBackend::checkForUpdates()
-@@ -180,7 +178,7 @@ void AlpineApkBackend::checkForUpdates()
-
- QString AlpineApkBackend::displayName() const
- {
-- return QStringLiteral("Dummy");
-+ return QStringLiteral("Alpine APK");
- }
-
- bool AlpineApkBackend::hasApplications() const
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-index 96fe234d..38602348 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-@@ -24,13 +24,14 @@
- #include <resources/AbstractResourcesBackend.h>
- #include <QVariantList>
-
--class DummyReviewsBackend;
-+//class DummyReviewsBackend;
- class StandardBackendUpdater;
- class AlpineApkResource;
- class AlpineApkBackend : public AbstractResourcesBackend
- {
--Q_OBJECT
--Q_PROPERTY(int startElements MEMBER m_startElements)
-+ Q_OBJECT
-+ Q_PROPERTY(int startElements MEMBER m_startElements)
-+
- public:
- explicit AlpineApkBackend(QObject* parent = nullptr);
-
-@@ -58,7 +59,7 @@ private:
-
- QHash<QString, AlpineApkResource*> m_resources;
- StandardBackendUpdater* m_updater;
-- DummyReviewsBackend* m_reviews;
-+ //DummyReviewsBackend* m_reviews;
- bool m_fetching;
- int m_startElements;
- };
---
-GitLab
-
-
-From d427c0a4243d73fff07b169a354d2d24c4fe84fe Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Tue, 14 Jan 2020 16:11:46 +0300
-Subject: [PATCH 05/62] Setup debug logging category
-
----
- .../AlpineApkBackend/AlpineApkBackend.cpp | 8 ++++++
- .../backends/AlpineApkBackend/CMakeLists.txt | 28 +++++++++++++------
- 2 files changed, 28 insertions(+), 8 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index 1df00d72..2f7ac2f9 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -23,6 +23,7 @@
- //#include "DummyReviewsBackend.h"
- #include "AlpineApkTransaction.h"
- #include "AlpineApkSourcesBackend.h"
-+#include "alpineapk_backend_logging.h" // generated by ECM
-
- #include <resources/StandardBackendUpdater.h>
- #include <resources/SourcesModel.h>
-@@ -34,6 +35,7 @@
- #include <KConfigGroup>
- #include <KSharedConfig>
- #include <QDebug>
-+#include <QLoggingCategory>
- #include <QThread>
- #include <QTimer>
- #include <QAction>
-@@ -47,6 +49,12 @@ AlpineApkBackend::AlpineApkBackend(QObject* parent)
- , m_fetching(true)
- , m_startElements(120)
- {
-+#ifndef QT_DEBUG
-+ const_cast<QLoggingCategory &>(LOG_ALPINEAPK()).setEnabled(QtDebugMsg, false);
-+#endif
-+
-+ qCDebug(LOG_ALPINEAPK) << "constructing backend!";
-+
- QTimer::singleShot(500, this, &AlpineApkBackend::toggleFetching);
- //connect(m_reviews, &DummyReviewsBackend::ratingsReady, this, &AbstractResourcesBackend::emitRatingsReady);
- connect(m_updater, &StandardBackendUpdater::updatesCountChanged, this, &AlpineApkBackend::updatesCountChanged);
-diff --git a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-index 635009ab..2bf3da97 100644
---- a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-+++ b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-@@ -1,16 +1,28 @@
- # add_subdirectory(tests) # no tests yet
-
-+set(alpineapkbackend_SRCS
-+ AlpineApkBackend.cpp
-+ AlpineApkBackend.h
-+ AlpineApkResource.cpp
-+ AlpineApkResource.h
-+ AlpineApkSourcesBackend.cpp
-+ AlpineApkSourcesBackend.h
-+ AlpineApkTransaction.cpp
-+ AlpineApkTransaction.h
-+)
-+
-+ecm_qt_declare_logging_category(
-+ alpineapkbackend_SRCS # sources_var
-+ HEADER alpineapk_backend_logging.h
-+ IDENTIFIER LOG_ALPINEAPK
-+ CATEGORY_NAME org.kde.plasma.discover.alpineapk
-+ DEFAULT_SEVERITY Debug
-+)
-+
- add_library(
- alpineapk-backend
- MODULE
-- AlpineApkBackend.cpp
-- AlpineApkBackend.h
-- AlpineApkResource.cpp
-- AlpineApkResource.h
-- AlpineApkSourcesBackend.cpp
-- AlpineApkSourcesBackend.h
-- AlpineApkTransaction.cpp
-- AlpineApkTransaction.h
-+ ${alpineapkbackend_SRCS}
- )
-
- target_link_libraries(
---
-GitLab
-
-
-From d705787a1c29c01fcbce04404dd1fc81cef598a7 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Tue, 14 Jan 2020 20:33:28 +0300
-Subject: [PATCH 06/62] Tidy up backend code and add debug prints
-
----
- .../AlpineApkBackend/AlpineApkBackend.cpp | 58 ++++++++++++-------
- .../AlpineApkBackend/AlpineApkResource.cpp | 1 +
- .../AlpineApkSourcesBackend.cpp | 1 +
- .../AlpineApkBackend/AlpineApkTransaction.cpp | 1 +
- 4 files changed, 40 insertions(+), 21 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index 2f7ac2f9..56d01e61 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -68,6 +68,8 @@ AlpineApkBackend::AlpineApkBackend(QObject* parent)
-
- void AlpineApkBackend::populate(const QString& n)
- {
-+ qCDebug(LOG_ALPINEAPK) << "populate! (" << n << ")";
-+
- const int start = m_resources.count();
- for(int i=start; i<start+m_startElements; i++) {
- const QString name = n+QLatin1Char(' ')+QString::number(i);
-@@ -100,7 +102,7 @@ void AlpineApkBackend::populate(const QString& n)
- void AlpineApkBackend::toggleFetching()
- {
- m_fetching = !m_fetching;
--// qDebug() << "fetching..." << m_fetching;
-+ qCDebug(LOG_ALPINEAPK) << "fetching..." << m_fetching;
- emit fetchingChanged();
- //if (!m_fetching)
- // m_reviews->initialize();
-@@ -108,44 +110,54 @@ void AlpineApkBackend::toggleFetching()
-
- int AlpineApkBackend::updatesCount() const
- {
-+ qCDebug(LOG_ALPINEAPK) << "updatesCount(): " << m_updater->updatesCount();
- return m_updater->updatesCount();
- }
-
- ResultsStream* AlpineApkBackend::search(const AbstractResourcesBackend::Filters& filter)
- {
- QVector<AbstractResource*> ret;
-- if (!filter.resourceUrl.isEmpty())
-+ if (!filter.resourceUrl.isEmpty()) {
- return findResourceByPackageName(filter.resourceUrl);
-- else foreach(AbstractResource* r, m_resources) {
-- if (r->type() == AbstractResource::Technical && filter.state != AbstractResource::Upgradeable) {
-- continue;
-+ } else {
-+ for (AbstractResource* r: qAsConst(m_resources)) {
-+ if (r->type() == AbstractResource::Technical
-+ && filter.state != AbstractResource::Upgradeable) {
-+ continue;
-+ }
-+
-+ if (r->state() < filter.state) {
-+ continue;
-+ }
-+
-+ if(r->name().contains(filter.search, Qt::CaseInsensitive)
-+ || r->comment().contains(filter.search, Qt::CaseInsensitive)) {
-+ ret += r;
-+ }
- }
--
-- if (r->state() < filter.state)
-- continue;
--
-- if(r->name().contains(filter.search, Qt::CaseInsensitive) || r->comment().contains(filter.search, Qt::CaseInsensitive))
-- ret += r;
- }
-- return new ResultsStream(QStringLiteral("DummyStream"), ret);
-+ return new ResultsStream(QStringLiteral("AlpineApkStream"), ret);
- }
-
- ResultsStream * AlpineApkBackend::findResourceByPackageName(const QUrl& search)
- {
-- if(search.isLocalFile()) {
-- AlpineApkResource* res = new AlpineApkResource(search.fileName(), AbstractResource::Technical, this);
-+ if (search.isLocalFile()) {
-+ AlpineApkResource* res = new AlpineApkResource(
-+ search.fileName(), AbstractResource::Technical, this);
- res->setSize(666);
- res->setState(AbstractResource::None);
- m_resources.insert(res->packageName(), res);
- connect(res, &AlpineApkResource::stateChanged, this, &AlpineApkBackend::updatesCountChanged);
-- return new ResultsStream(QStringLiteral("DummyStream-local"), { res });
-+ return new ResultsStream(QStringLiteral("AlpineApkStream-local"), { res });
- }
-
-- auto res = search.scheme() == QLatin1String("dummy") ? m_resources.value(search.host().replace(QLatin1Char('.'), QLatin1Char(' '))) : nullptr;
-+ AlpineApkResource *res = search.scheme() == QLatin1String("dummy")
-+ ? m_resources.value(search.host().replace(QLatin1Char('.'), QLatin1Char(' ')))
-+ : nullptr;
- if (!res) {
- return new ResultsStream(QStringLiteral("DummyStream"), {});
-- } else
-- return new ResultsStream(QStringLiteral("DummyStream"), { res });
-+ }
-+ return new ResultsStream(QStringLiteral("DummyStream"), { res });
- }
-
- AbstractBackendUpdater* AlpineApkBackend::backendUpdater() const
-@@ -155,7 +167,8 @@ AbstractBackendUpdater* AlpineApkBackend::backendUpdater() const
-
- AbstractReviewsBackend* AlpineApkBackend::reviewsBackend() const
- {
-- //return m_reviews;
-+ qCDebug(LOG_ALPINEAPK) << "reviewsBbackend(): we don't support reviews (";
-+ // return m_reviews;
- return nullptr;
- }
-
-@@ -176,12 +189,14 @@ Transaction* AlpineApkBackend::removeApplication(AbstractResource* app)
-
- void AlpineApkBackend::checkForUpdates()
- {
-- if(m_fetching)
-+ if(m_fetching) {
-+ qCDebug(LOG_ALPINEAPK) << "checkForUpdates(): already fetching";
- return;
-+ }
-+ qCDebug(LOG_ALPINEAPK) << "checkForUpdates()!";
- toggleFetching();
- populate(QStringLiteral("Moar"));
- QTimer::singleShot(500, this, &AlpineApkBackend::toggleFetching);
-- qDebug() << "AlpineApkBackend::checkForUpdates";
- }
-
- QString AlpineApkBackend::displayName() const
-@@ -191,6 +206,7 @@ QString AlpineApkBackend::displayName() const
-
- bool AlpineApkBackend::hasApplications() const
- {
-+ qCDebug(LOG_ALPINEAPK) << "hasApplications(), returning true";
- return true;
- }
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-index d1cceaaa..5b4fd15c 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-@@ -19,6 +19,7 @@
- ***************************************************************************/
-
- #include "AlpineApkResource.h"
-+#include "alpineapk_backend_logging.h" // generated by ECM
- #include <Transaction/AddonList.h>
- #include <krandom.h>
- #include <QDesktopServices>
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-index 3f492185..60faa396 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-@@ -19,6 +19,7 @@
- ***************************************************************************/
-
- #include "AlpineApkSourcesBackend.h"
-+#include "alpineapk_backend_logging.h" // generated by ECM
- #include <QDebug>
- #include <QAction>
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-index 8b6b72a5..e3f8d634 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-@@ -21,6 +21,7 @@
- #include "AlpineApkTransaction.h"
- #include "AlpineApkBackend.h"
- #include "AlpineApkResource.h"
-+#include "alpineapk_backend_logging.h" // generated by ECM
- #include <QTimer>
- #include <QDebug>
- #include <KRandom>
---
-GitLab
-
-
-From a30bdd843e68f7ace16fbbb5ea84a28afc1a8f78 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Tue, 28 Jan 2020 18:11:31 +0300
-Subject: [PATCH 07/62] CMake: link Apk backend with apk-qt
-
----
- libdiscover/backends/AlpineApkBackend/CMakeLists.txt | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-index 2bf3da97..45a56eb6 100644
---- a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-+++ b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-@@ -33,6 +33,7 @@ target_link_libraries(
- KF5::CoreAddons
- KF5::ConfigCore
- Discover::Common
-+ apk-qt
- )
-
- install(
---
-GitLab
-
-
-From d0f38b3148432a99f0129cfc0c7afe0c302e0f04 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Tue, 28 Jan 2020 18:12:11 +0300
-Subject: [PATCH 08/62] Fix copyright years
-
----
- libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp | 2 +-
- libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h | 2 +-
- libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp | 2 +-
- libdiscover/backends/AlpineApkBackend/AlpineApkResource.h | 2 +-
- .../backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp | 2 +-
- libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h | 2 +-
- libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp | 2 +-
- libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h | 2 +-
- 8 files changed, 8 insertions(+), 8 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index 56d01e61..778093aa 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -1,5 +1,5 @@
- /***************************************************************************
-- * Copyright © 2019 Alexey Min <alexey.min@gmail.com> *
-+ * Copyright © 2020 Alexey Min <alexey.min@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 *
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-index 38602348..aa520f96 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-@@ -1,5 +1,5 @@
- /***************************************************************************
-- * Copyright © 2019 Alexey Min <alexey.min@gmail.com> *
-+ * Copyright © 2020 Alexey Min <alexey.min@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 *
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-index 5b4fd15c..9348f1ed 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-@@ -1,5 +1,5 @@
- /***************************************************************************
-- * Copyright © 2019 Alexey Min <alexey.min@gmail.com> *
-+ * Copyright © 2020 Alexey Min <alexey.min@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 *
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-index f4ecee4a..a1393ea8 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-@@ -1,5 +1,5 @@
- /***************************************************************************
-- * Copyright © 2019 Alexey Min <alexey.min@gmail.com> *
-+ * Copyright © 2020 Alexey Min <alexey.min@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 *
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-index 60faa396..9ca9862d 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-@@ -1,5 +1,5 @@
- /***************************************************************************
-- * Copyright © 2019 Alexey Min <alexey.min@gmail.com> *
-+ * Copyright © 2020 Alexey Min <alexey.min@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 *
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h
-index 48a0d829..d085f087 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h
-@@ -1,5 +1,5 @@
- /***************************************************************************
-- * Copyright © 2019 Alexey Min <alexey.min@gmail.com> *
-+ * Copyright © 2020 Alexey Min <alexey.min@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 *
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-index e3f8d634..18ba5209 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-@@ -1,5 +1,5 @@
- /***************************************************************************
-- * Copyright © 2019 Alexey Min <alexey.min@gmail.com> *
-+ * Copyright © 2020 Alexey Min <alexey.min@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 *
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h
-index 49102dd5..8739eca1 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h
-@@ -1,5 +1,5 @@
- /***************************************************************************
-- * Copyright © 2019 Alexey Min <alexey.min@gmail.com> *
-+ * Copyright © 2020 Alexey Min <alexey.min@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 *
---
-GitLab
-
-
-From 132fbd9d51a04d5bb1506c379693fa282506e6e1 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Tue, 28 Jan 2020 18:21:21 +0300
-Subject: [PATCH 09/62] Apk sources backend: show real repos URLs (read-only
- now)
-
----
- .../AlpineApkSourcesBackend.cpp | 116 +++++++++++++-----
- .../AlpineApkSourcesBackend.h | 15 +--
- 2 files changed, 92 insertions(+), 39 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-index 9ca9862d..09a86bdf 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-@@ -22,74 +22,126 @@
- #include "alpineapk_backend_logging.h" // generated by ECM
- #include <QDebug>
- #include <QAction>
-+#include <QVector>
-
--AlpineApkSourcesBackend::AlpineApkSourcesBackend(AbstractResourcesBackend * parent)
-+// libapk-qt
-+#include <QtApk.h>
-+
-+AlpineApkSourcesBackend::AlpineApkSourcesBackend(AbstractResourcesBackend *parent)
- : AbstractSourcesBackend(parent)
-- , m_sources(new QStandardItemModel(this))
-- , m_testAction(new QAction(QIcon::fromTheme(QStringLiteral("kalgebra")), QStringLiteral("DummyAction"), this))
-+ , m_sourcesModel(new QStandardItemModel(this))
-+ , m_refreshAction(new QAction(QIcon::fromTheme(QStringLiteral("view-refresh")),
-+ QStringLiteral("Refresh"), this))
- {
-- for (int i = 0; i<10; ++i)
-- addSource(QStringLiteral("DummySource%1").arg(i));
-+ loadSources();
-+ QObject::connect(m_refreshAction, &QAction::triggered,
-+ this, &AlpineApkSourcesBackend::loadSources);
-+
-+ // can be used to track enabling/disabling repo source
-+ // QObject::connect(m_sourcesModel, &QStandardItemModel::itemChanged, this, [](QStandardItem* item) {
-+ // qCDebug(LOG_ALPINEAPK) << "DummySource changed" << item << item->checkState();
-+ // });
-+}
-
-- connect(m_testAction, &QAction::triggered, [](){ qDebug() << "action triggered!"; });
-- connect(m_sources, &QStandardItemModel::itemChanged, this, [](QStandardItem* item) { qDebug() << "DummySource changed" << item << item->checkState(); });
-+QAbstractItemModel *AlpineApkSourcesBackend::sources()
-+{
-+ return m_sourcesModel;
-+}
-+
-+bool AlpineApkSourcesBackend::addSource(const QString &id)
-+{
-+ return addSourceFull(id, QString(), true);
- }
-
--QAbstractItemModel* AlpineApkSourcesBackend::sources()
-+QStandardItem *AlpineApkSourcesBackend::sourceForId(const QString& id) const
- {
-- return m_sources;
-+ for (int i = 0, c = m_sourcesModel->rowCount(); i < c; ++i) {
-+ QStandardItem *it = m_sourcesModel->item(i, 0);
-+ if (it->text() == id) {
-+ return it;
-+ }
-+ }
-+ return nullptr;
- }
-
--bool AlpineApkSourcesBackend::addSource(const QString& id)
-+bool AlpineApkSourcesBackend::addSourceFull(const QString &id, const QString &comment, bool enabled)
- {
-- if (id.isEmpty())
-+ if (id.isEmpty()) {
- return false;
-+ }
-
-- QStandardItem* it = new QStandardItem(id);
-+ qCDebug(LOG_ALPINEAPK) << "AlpineApkSourcesBackend: Adding source:" << id;
-+
-+ QStandardItem *it = new QStandardItem(id);
- it->setData(id, AbstractSourcesBackend::IdRole);
-- it->setData(QVariant(id + QLatin1Char(' ') + id), Qt::ToolTipRole);
-+ it->setData(comment, Qt::ToolTipRole);
- it->setCheckable(true);
-- it->setCheckState(Qt::Checked);
-- m_sources->appendRow(it);
-+ it->setCheckState(enabled ? Qt::Checked : Qt::Unchecked);
-+ // for now, disable editing sources
-+ it->setFlags(it->flags() & ~Qt::ItemIsEnabled);
-+ m_sourcesModel->appendRow(it);
- return true;
- }
-
--QStandardItem * AlpineApkSourcesBackend::sourceForId(const QString& id) const
-+void AlpineApkSourcesBackend::loadSources()
- {
-- for (int i=0, c=m_sources->rowCount(); i<c; ++i) {
-- const auto it = m_sources->item(i, 0);
-- if (it->text() == id)
-- return it;
-+ QVector<QtApk::Repository> repos = QtApk::Database::getRepositories();
-+ m_sourcesModel->clear();
-+ for (const QtApk::Repository &repo: repos) {
-+ addSourceFull(repo.url, repo.comment, repo.enabled);
- }
-- return nullptr;
- }
-
--bool AlpineApkSourcesBackend::removeSource(const QString& id)
-+bool AlpineApkSourcesBackend::removeSource(const QString &id)
- {
-- const auto it = sourceForId(id);
-+ const QStandardItem *it = sourceForId(id);
- if (!it) {
-- qWarning() << "couldn't find " << id;
-+ qCWarning(LOG_ALPINEAPK) << "AlpineApkSourcesBackend: couldn't find " << id;
- return false;
- }
-- return m_sources->removeRow(it->row());
-+ return m_sourcesModel->removeRow(it->row());
-+}
-+
-+QString AlpineApkSourcesBackend::idDescription()
-+{
-+ return QStringLiteral("Enter apk repository URL, for example: "
-+ "http://dl-cdn.alpinelinux.org/alpine/edge/testing/");
- }
-
- QVariantList AlpineApkSourcesBackend::actions() const
- {
-- return QVariantList() << QVariant::fromValue<QObject*>(m_testAction);
-+ static const QVariantList s_actions {
-+ QVariant::fromValue<QObject *>(m_refreshAction),
-+ };
-+ return s_actions;
-+}
-+
-+bool AlpineApkSourcesBackend::supportsAdding() const
-+{
-+ return false; // for now, disable editing sources
-+}
-+
-+bool AlpineApkSourcesBackend::canMoveSources() const
-+{
-+ return false; // for now, disable editing sources
- }
-
- bool AlpineApkSourcesBackend::moveSource(const QString& sourceId, int delta)
- {
- int row = sourceForId(sourceId)->row();
-- auto prevRow = m_sources->takeRow(row);
-- Q_ASSERT(!prevRow.isEmpty());
-+ QList<QStandardItem *> prevRow = m_sourcesModel->takeRow(row);
-+ if (prevRow.isEmpty()) {
-+ return false;
-+ }
-
-- const auto destRow = row + delta;
-- m_sources->insertRow(destRow, prevRow);
-- if (destRow == 0 || row == 0)
-+ const int destRow = row + delta;
-+ m_sourcesModel->insertRow(destRow, prevRow);
-+ if (destRow == 0 || row == 0) {
- Q_EMIT firstSourceIdChanged();
-- if (destRow == m_sources->rowCount() - 1 || row == m_sources->rowCount() - 1)
-+ }
-+ if (destRow == (m_sourcesModel->rowCount() - 1)
-+ || row == (m_sourcesModel->rowCount() - 1)) {
- Q_EMIT lastSourceIdChanged();
-+ }
- return true;
- }
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h
-index d085f087..57894591 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h
-@@ -32,18 +32,19 @@ public:
- QAbstractItemModel *sources() override;
- bool addSource(const QString &id) override;
- bool removeSource(const QString &id) override;
-- QString idDescription() override { return QStringLiteral("Random weird text"); }
-+ QString idDescription() override;
- QVariantList actions() const override;
-- bool supportsAdding() const override { return true; }
--
-- bool canMoveSources() const override { return true; }
-+ bool supportsAdding() const override;
-+ bool canMoveSources() const override;
- bool moveSource(const QString &sourceId, int delta) override;
-
- private:
-- QStandardItem* sourceForId(const QString &id) const;
-+ QStandardItem *sourceForId(const QString &id) const;
-+ bool addSourceFull(const QString &id, const QString &comment, bool enabled);
-+ void loadSources();
-
-- QStandardItemModel* m_sources;
-- QAction* m_testAction;
-+ QStandardItemModel *m_sourcesModel = nullptr;
-+ QAction *m_refreshAction = nullptr;
- };
-
- #endif // ALPINEAPKSOURCESBACKEND_H
---
-GitLab
-
-
-From 6539ebc4b400d5116d89bd2f19b68a3656fbde0b Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Tue, 28 Jan 2020 20:27:31 +0300
-Subject: [PATCH 10/62] Cleanup of AlpipneApkResource.{h,cpp}
-
----
- .../AlpineApkBackend/AlpineApkResource.cpp | 153 ++++++++----------
- .../AlpineApkBackend/AlpineApkResource.h | 34 ++--
- 2 files changed, 88 insertions(+), 99 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-index 9348f1ed..d827e7b3 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-@@ -18,46 +18,18 @@
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-+#include <KRandom>
- #include "AlpineApkResource.h"
- #include "alpineapk_backend_logging.h" // generated by ECM
--#include <Transaction/AddonList.h>
--#include <krandom.h>
--#include <QDesktopServices>
--#include <QStringList>
--#include <QTimer>
--
--Q_GLOBAL_STATIC_WITH_ARGS(QVector<QString>, s_icons,
-- ({ QLatin1String("kdevelop"),
-- QLatin1String("kalgebra"),
-- QLatin1String("kmail"),
-- QLatin1String("akregator"),
-- QLatin1String("korganizer") }))
--
--AlpineApkResource::AlpineApkResource(
-- QString name,
-- AbstractResource::Type type,
-- AbstractResourcesBackend* parent)
-+#include "Transaction/AddonList.h"
-+
-+AlpineApkResource::AlpineApkResource(const QtApk::Package &apkPkg,
-+ AbstractResourcesBackend *parent)
- : AbstractResource(parent)
-- , m_name(std::move(name))
-- , m_state(State::Broken)
-- , m_iconName((*s_icons)[KRandom::random() % s_icons->size()])
-- , m_addons({ PackageState(QStringLiteral("a"), QStringLiteral("aaaaaa"), false),
-- PackageState(QStringLiteral("b"), QStringLiteral("aaaaaa"), false),
-- PackageState(QStringLiteral("c"), QStringLiteral("aaaaaa"), false)})
-- , m_type(type)
--{
-- const int nofScreenshots = KRandom::random() % 5;
-- m_screenshots = QList<QUrl>{
-- QUrl(QStringLiteral("https://screenshots.debian.net/screenshots/000/014/863/large.png")),
-- QUrl(QStringLiteral("https://c1.staticflickr.com/9/8479/8166397343_b78106f353_k.jpg")),
-- QUrl(QStringLiteral("https://c2.staticflickr.com/4/3685/9954407993_dad10a6943_k.jpg")),
-- QUrl(QStringLiteral("https://c1.staticflickr.com/1/653/22527103378_8ce572e1de_k.jpg")),
-- QUrl(QStringLiteral("https://images.unsplash.com/photo-1528744598421-b7b93e12df15?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=500&q=60")),
-- QUrl(QStringLiteral("https://images.unsplash.com/photo-1552385430-53e6f2028760?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=634&q=80")),
-- QUrl(QStringLiteral("https://images.unsplash.com/photo-1506810172640-8a9f77cb1472?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80")),
--
-- }.mid(nofScreenshots);
-- m_screenshotThumbnails = m_screenshots;
-+ , m_state(AbstractResource::State::None)
-+ , m_type(Application)
-+ , m_pkg(apkPkg)
-+{
- }
-
- QList<PackageState> AlpineApkResource::addonsInformation()
-@@ -67,103 +39,87 @@ QList<PackageState> AlpineApkResource::addonsInformation()
-
- QString AlpineApkResource::availableVersion() const
- {
-- return QStringLiteral("3.0");
-+ return m_pkg.version;
- }
-
- QStringList AlpineApkResource::categories()
- {
-- return { QStringLiteral("dummy"),
-- m_name.endsWith(QLatin1Char('3'))
-- ? QStringLiteral("three")
-- : QStringLiteral("notthree") };
-+ return { m_category };
- }
-
- QString AlpineApkResource::comment()
- {
-- return QStringLiteral("A reasonably short comment ") + name();
-+ return m_pkg.description;
- }
-
- int AlpineApkResource::size()
- {
-- return m_size;
-+ return static_cast<int>(m_pkg.size);
- }
-
- QUrl AlpineApkResource::homepage()
- {
-- return QUrl(QStringLiteral("https://kde.org"));
-+ return QUrl::fromUserInput(m_pkg.url);
- }
-
- QUrl AlpineApkResource::helpURL()
- {
-- return QUrl(QStringLiteral("http://very-very-excellent-docs.lol"));
-+ return QUrl();
- }
-
- QUrl AlpineApkResource::bugURL()
- {
-- return QUrl(QStringLiteral("file:///dev/null"));
-+ return QUrl();
- }
-
- QUrl AlpineApkResource::donationURL()
- {
-- return QUrl(QStringLiteral("https://youtu.be/0o8XMlL8rqY"));
-+ return QUrl();
- }
-
- QVariant AlpineApkResource::icon() const
- {
-- static const QVector<QVariant> icons = {
-- QStringLiteral("device-notifier"),
-- QStringLiteral("media-floppy"),
-- QStringLiteral("drink-beer")
-- };
-- return icons[type()];
-+ return QStringLiteral("package-x-generic");
- }
-
- QString AlpineApkResource::installedVersion() const
- {
-- return QStringLiteral("2.3");
-+ return m_pkg.version;
- }
-
- QJsonArray AlpineApkResource::licenses()
- {
- return {
- QJsonObject {
-- { QStringLiteral("name"), QStringLiteral("GPL") },
-- { QStringLiteral("url"), QStringLiteral("https://kde.org") }
-+ { QStringLiteral("name"), m_pkg.license },
-+ { QStringLiteral("url"), QStringLiteral("https://spdx.org/license-list") },
- }
- };
- }
-
- QString AlpineApkResource::longDescription()
- {
-- return QStringLiteral("Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur ultricies consequat nulla, ut vulputate nulla ultricies ac. Suspendisse lacinia commodo lacus, non tristique mauris dictum vitae. Sed adipiscing augue nec nisi aliquet viverra. Etiam sit amet nulla in tellus consectetur feugiat. Cras in sem tortor. Fusce a nulla at justo accumsan gravida. Maecenas dui felis, lacinia at ornare sed, aliquam et purus. Sed ut sagittis lacus. Etiam dictum pharetra rhoncus. Suspendisse auctor orci ipsum. Pellentesque vitae urna nec felis consequat lobortis dictum in urna. Phasellus a mi ac leo adipiscing varius eget a felis. Cras magna augue, commodo sed placerat vel, tempus vel ligula. In feugiat quam quis est lobortis sed accumsan nunc malesuada. Mauris quis massa sit amet felis tempus suscipit a quis diam.\n\n"
--
-- "Aenean quis nulla erat, vel sagittis sem. Praesent vitae mauris arcu. Cras porttitor, ante at scelerisque sodales, nibh felis consectetur orci, ut hendrerit urna urna non urna. Duis eu magna id mi scelerisque adipiscing. Aliquam sed quam in eros sodales accumsan. Phasellus tempus sagittis suscipit. Aliquam rutrum dictum justo ut viverra. Nulla felis sem, molestie sed scelerisque non, consequat vitae nulla. Aliquam ullamcorper malesuada mi, vel vestibulum magna vulputate eget. In hac habitasse platea dictumst. Cras sed lacus dui, vel semper sem. Aenean sodales porta leo vel fringilla.\n\n"
--
-- "Ut tempus massa et urna porta non mollis metus ultricies. Duis nec nulla ac metus auctor porta id et mi. Mauris aliquam nibh a ligula malesuada sed tincidunt nibh varius. Sed felis metus, porta et adipiscing non, faucibus id leo. Donec ipsum nibh, hendrerit eget aliquam nec, tempor ut mauris. Suspendisse potenti. Vestibulum scelerisque adipiscing libero tristique eleifend. Donec quis tortor eget elit mollis iaculis ac sit amet nisi. Proin non massa sed nunc rutrum pellentesque. Sed dui lectus, laoreet sed condimentum id, commodo sed urna.\n\n"
--
-- "Praesent tincidunt mattis massa mattis porta. Nullam posuere neque at mauris vestibulum vitae elementum leo sodales. Quisque condimentum lectus in libero luctus egestas. Fusce tempor neque ac dui tincidunt eget viverra quam suscipit. In hac habitasse platea dictumst. Etiam metus mi, adipiscing nec suscipit id, aliquet sed sem. Duis urna ligula, ornare sed vestibulum vel, molestie ac nisi. Morbi varius iaculis ligula. Nunc in augue leo, sit amet aliquam elit. Suspendisse rutrum sem diam. Proin eu orci nisl. Praesent porttitor dignissim est, id fermentum arcu venenatis vitae.\n\n"
--
-- "Integer in sapien eget quam vulputate lobortis. Morbi nibh elit, elementum vitae vehicula sed, consequat nec erat. Donec placerat porttitor est ut dapibus. Fusce augue orci, dictum et convallis vel, blandit eu tortor. Phasellus non eros nulla. In iaculis nulla fermentum nulla gravida eu mattis purus consectetur. Integer dui nunc, sollicitudin ac tincidunt nec, hendrerit bibendum nunc. Proin sit amet augue ac velit egestas varius. Sed eu ante quis orci vestibulum sagittis. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Phasellus vitae urna odio, at molestie leo. In convallis neque vel mi dictum convallis lobortis turpis sagittis.\n\n");
-+ return m_pkg.description;
- }
-
- QString AlpineApkResource::name() const
- {
-- return m_name;
-+ return m_pkg.name;
- }
-
- QString AlpineApkResource::origin() const
- {
-- return QStringLiteral("DummySource1");
-+ return m_originSoruce;
- }
-
- QString AlpineApkResource::packageName() const
- {
-- return m_name;
-+ return m_pkg.name;
- }
-
- QString AlpineApkResource::section()
- {
-- return QStringLiteral("dummy");
-+ return m_sectionName;
- }
-
- AbstractResource::State AlpineApkResource::state()
-@@ -173,15 +129,13 @@ AbstractResource::State AlpineApkResource::state()
-
- void AlpineApkResource::fetchChangelog()
- {
-- QString log = longDescription();
-- log.replace(QLatin1Char('\n'), QLatin1String("<br />"));
--
-- emit changelogFetched(log);
-+ // QString log = longDescription();
-+ // Q_EMIT changelogFetched(log);
- }
-
- void AlpineApkResource::fetchScreenshots()
- {
-- Q_EMIT screenshotsFetched(m_screenshotThumbnails, m_screenshots);
-+ // Q_EMIT screenshotsFetched(m_screenshotThumbnails, m_screenshots);
- }
-
- void AlpineApkResource::setState(AbstractResource::State state)
-@@ -190,19 +144,36 @@ void AlpineApkResource::setState(AbstractResource::State state)
- emit stateChanged();
- }
-
--void AlpineApkResource::setAddons(const AddonList& addons)
-+void AlpineApkResource::setCategoryName(const QString &categoryName)
-+{
-+ m_category = categoryName;
-+}
-+
-+void AlpineApkResource::setOriginSource(const QString &originSource)
-+{
-+ m_originSoruce = originSource;
-+}
-+
-+void AlpineApkResource::setSection(const QString &sectionName)
-+{
-+ m_sectionName = sectionName;
-+}
-+
-+void AlpineApkResource::setAddons(const AddonList &addons)
- {
-- Q_FOREACH (const QString& toInstall, addons.addonsToInstall()) {
-+ const QStringList addonsToInstall = addons.addonsToInstall();
-+ for (const QString &toInstall : addonsToInstall) {
- setAddonInstalled(toInstall, true);
- }
-- Q_FOREACH (const QString& toRemove, addons.addonsToRemove()) {
-+ const QStringList addonsToRemove = addons.addonsToRemove();
-+ for (const QString &toRemove : addonsToRemove) {
- setAddonInstalled(toRemove, false);
- }
- }
-
--void AlpineApkResource::setAddonInstalled(const QString& addon, bool installed)
-+void AlpineApkResource::setAddonInstalled(const QString &addon, bool installed)
- {
-- for(auto & elem : m_addons) {
-+ for(PackageState &elem : m_addons) {
- if(elem.name() == addon) {
- elem.setInstalled(installed);
- }
-@@ -212,12 +183,26 @@ void AlpineApkResource::setAddonInstalled(const QString& addon, bool installed)
-
- void AlpineApkResource::invokeApplication() const
- {
-- QDesktopServices d;
-- d.openUrl(QUrl(QStringLiteral("https://projects.kde.org/projects/extragear/sysadmin/muon")));
-+ // QDesktopServices d;
-+ // d.openUrl(QUrl(QStringLiteral("https://projects.kde.org/projects/extragear/sysadmin/muon")));
- }
-
- QUrl AlpineApkResource::url() const
- {
-- return QUrl(QLatin1String("dummy://")
-- + packageName().replace(QLatin1Char(' '), QLatin1Char('.')));
-+ return QUrl(QLatin1String("apk://") + packageName());
-+}
-+
-+QString AlpineApkResource::author() const
-+{
-+ return m_pkg.maintainer;
-+}
-+
-+QString AlpineApkResource::sourceIcon() const
-+{
-+ return QStringLiteral("player-time");
-+}
-+
-+QDate AlpineApkResource::releaseDate() const
-+{
-+ return m_pkg.buildTime.date();
- }
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-index a1393ea8..79b100e1 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-@@ -22,13 +22,16 @@
- #define ALPINEAPKRESOURCE_H
-
- #include <resources/AbstractResource.h>
-+#include <QtApkPackage.h>
-
- class AddonList;
-+
- class AlpineApkResource : public AbstractResource
- {
--Q_OBJECT
-+ Q_OBJECT
-+
- public:
-- explicit AlpineApkResource(QString name, AbstractResource::Type type, AbstractResourcesBackend* parent);
-+ explicit AlpineApkResource(const QtApk::Package &apkPkg, AbstractResourcesBackend *parent);
-
- QList<PackageState> addonsInformation() override;
- QString section() override;
-@@ -54,24 +57,25 @@ public:
- void fetchChangelog() override;
- void fetchScreenshots() override;
- QUrl url() const override;
-- QString author() const override { return QStringLiteral("BananaPerson"); }
-- void setState(State state);
-- void setSize(int size) { m_size = size; }
-- void setAddons(const AddonList& addons);
-+ QString author() const override;
-+ QString sourceIcon() const override;
-+ QDate releaseDate() const override;
-
-- void setAddonInstalled(const QString& addon, bool installed);
-- QString sourceIcon() const override { return QStringLiteral("player-time"); }
-- QDate releaseDate() const override { return {}; }
-+ void setState(State state);
-+ void setCategoryName(const QString &categoryName);
-+ void setOriginSource(const QString &originSource);
-+ void setSection(const QString &sectionName);
-+ void setAddons(const AddonList &addons);
-+ void setAddonInstalled(const QString &addon, bool installed);
-
- public:
-- const QString m_name;
- AbstractResource::State m_state;
-- QList<QUrl> m_screenshots;
-- QList<QUrl> m_screenshotThumbnails;
-- QString m_iconName;
-- QList<PackageState> m_addons;
- const AbstractResource::Type m_type;
-- int m_size;
-+ QtApk::Package m_pkg;
-+ QString m_category;
-+ QString m_originSoruce;
-+ QString m_sectionName;
-+ QList<PackageState> m_addons;
- };
-
- #endif // ALPINEAPKRESOURCE_H
---
-GitLab
-
-
-From 276455939f8cf00fa556fafdf44337aa11ae011c Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Tue, 28 Jan 2020 20:32:46 +0300
-Subject: [PATCH 11/62] Cleanup of AlpineApkBackend.{h,cpp}
-
----
- .../AlpineApkBackend/AlpineApkBackend.cpp | 157 ++++++++++--------
- .../AlpineApkBackend/AlpineApkBackend.h | 38 +++--
- 2 files changed, 114 insertions(+), 81 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index 778093aa..f5aa5477 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -25,9 +25,10 @@
- #include "AlpineApkSourcesBackend.h"
- #include "alpineapk_backend_logging.h" // generated by ECM
-
--#include <resources/StandardBackendUpdater.h>
--#include <resources/SourcesModel.h>
--#include <Transaction/Transaction.h>
-+#include "resources/StandardBackendUpdater.h"
-+#include "resources/SourcesModel.h"
-+#include "Transaction/Transaction.h"
-+#include "Category/Category.h"
-
- #include <KAboutData>
- #include <KLocalizedString>
-@@ -42,11 +43,9 @@
-
- DISCOVER_BACKEND_PLUGIN(AlpineApkBackend)
-
--AlpineApkBackend::AlpineApkBackend(QObject* parent)
-+AlpineApkBackend::AlpineApkBackend(QObject *parent)
- : AbstractResourcesBackend(parent)
- , m_updater(new StandardBackendUpdater(this))
-- //, m_reviews(new DummyReviewsBackend(this))
-- , m_fetching(true)
- , m_startElements(120)
- {
- #ifndef QT_DEBUG
-@@ -59,43 +58,59 @@ AlpineApkBackend::AlpineApkBackend(QObject* parent)
- //connect(m_reviews, &DummyReviewsBackend::ratingsReady, this, &AbstractResourcesBackend::emitRatingsReady);
- connect(m_updater, &StandardBackendUpdater::updatesCountChanged, this, &AlpineApkBackend::updatesCountChanged);
-
-- populate(QStringLiteral("Dummy"));
-+ populate();
- //if (!m_fetching)
- // m_reviews->initialize();
-
- SourcesModel::global()->addSourcesBackend(new AlpineApkSourcesBackend(this));
- }
-
--void AlpineApkBackend::populate(const QString& n)
-+QVector<Category *> AlpineApkBackend::category() const
- {
-- qCDebug(LOG_ALPINEAPK) << "populate! (" << n << ")";
--
-- const int start = m_resources.count();
-- for(int i=start; i<start+m_startElements; i++) {
-- const QString name = n+QLatin1Char(' ')+QString::number(i);
-- AlpineApkResource* res = new AlpineApkResource(name, AbstractResource::Application, this);
-- res->setSize(100+(m_startElements-i));
-- res->setState(AbstractResource::State(1+(i%3)));
-- m_resources.insert(name.toLower(), res);
-- connect(res, &AlpineApkResource::stateChanged, this, &AlpineApkBackend::updatesCountChanged);
-- }
-+ static Category *cat = new Category(
-+ QStringLiteral("All applications"), // displayName
-+ QStringLiteral("applications-other"), // icon
-+ { }, // orFilters
-+ { displayName() }, // pluginName
-+ { }, // subCategories
-+ QUrl(), // decoration (what is it?)
-+ false // isAddons
-+ );
-+ return { cat };
-+}
-+
-+void AlpineApkBackend::populate()
-+{
-+ qCDebug(LOG_ALPINEAPK) << "populating resources...";
-
-- for(int i=start; i<start+m_startElements; i++) {
-- const QString name = QLatin1String("addon")+QString::number(i);
-- AlpineApkResource* res = new AlpineApkResource(name, AbstractResource::Addon, this);
-- res->setState(AbstractResource::State(1+(i%3)));
-- res->setSize(300+(m_startElements-i));
-- m_resources.insert(name, res);
-- connect(res, &AlpineApkResource::stateChanged, this, &AlpineApkBackend::updatesCountChanged);
-+ if (m_apkdb.open(QtApk::Database::QTAPK_OPENF_READONLY)) {
-+ m_availablePackages = m_apkdb.getAvailablePackages();
-+ m_installedPackages = m_apkdb.getInstalledPackages();
-+ m_apkdb.close();
- }
-
-- for(int i=start; i<start+m_startElements; i++) {
-- const QString name = QLatin1String("techie")+QString::number(i);
-- AlpineApkResource* res = new AlpineApkResource(name, AbstractResource::Technical, this);
-- res->setState(AbstractResource::State(1+(i%3)));
-- res->setSize(300+(m_startElements-i));
-- m_resources.insert(name, res);
-- connect(res, &AlpineApkResource::stateChanged, this, &AlpineApkBackend::updatesCountChanged);
-+ if (m_availablePackages.size() > 0) {
-+ for (const QtApk::Package &pkg: m_availablePackages) {
-+ AlpineApkResource *res = new AlpineApkResource(pkg, this);
-+ res->setCategoryName(QStringLiteral("all"));
-+ res->setOriginSource(QStringLiteral("apk"));
-+ res->setSection(QStringLiteral("dummy"));
-+ const QString key = pkg.name.toLower();
-+ m_resources.insert(key, res);
-+ connect(res, &AlpineApkResource::stateChanged, this, &AlpineApkBackend::updatesCountChanged);
-+ }
-+ qCDebug(LOG_ALPINEAPK) << " available" << m_availablePackages.size()
-+ << "packages";
-+ }
-+ if (m_installedPackages.size() > 0) {
-+ for (const QtApk::Package &pkg: m_installedPackages) {
-+ const QString key = pkg.name.toLower();
-+ if (m_resources.contains(key)) {
-+ m_resources.value(key)->setState(AbstractResource::Installed);
-+ }
-+ }
-+ qCDebug(LOG_ALPINEAPK) << " installed" << m_installedPackages.size()
-+ << "packages";
- }
- }
-
-@@ -114,22 +129,20 @@ int AlpineApkBackend::updatesCount() const
- return m_updater->updatesCount();
- }
-
--ResultsStream* AlpineApkBackend::search(const AbstractResourcesBackend::Filters& filter)
-+ResultsStream *AlpineApkBackend::search(const AbstractResourcesBackend::Filters &filter)
- {
- QVector<AbstractResource*> ret;
- if (!filter.resourceUrl.isEmpty()) {
- return findResourceByPackageName(filter.resourceUrl);
- } else {
-- for (AbstractResource* r: qAsConst(m_resources)) {
-+ for (AbstractResource *r: qAsConst(m_resources)) {
- if (r->type() == AbstractResource::Technical
- && filter.state != AbstractResource::Upgradeable) {
- continue;
- }
--
- if (r->state() < filter.state) {
- continue;
- }
--
- if(r->name().contains(filter.search, Qt::CaseInsensitive)
- || r->comment().contains(filter.search, Qt::CaseInsensitive)) {
- ret += r;
-@@ -139,52 +152,67 @@ ResultsStream* AlpineApkBackend::search(const AbstractResourcesBackend::Filters&
- return new ResultsStream(QStringLiteral("AlpineApkStream"), ret);
- }
-
--ResultsStream * AlpineApkBackend::findResourceByPackageName(const QUrl& search)
-+ResultsStream *AlpineApkBackend::findResourceByPackageName(const QUrl &searchUrl)
- {
-- if (search.isLocalFile()) {
-- AlpineApkResource* res = new AlpineApkResource(
-- search.fileName(), AbstractResource::Technical, this);
-- res->setSize(666);
-- res->setState(AbstractResource::None);
-- m_resources.insert(res->packageName(), res);
-- connect(res, &AlpineApkResource::stateChanged, this, &AlpineApkBackend::updatesCountChanged);
-- return new ResultsStream(QStringLiteral("AlpineApkStream-local"), { res });
-+// if (search.isLocalFile()) {
-+// AlpineApkResource* res = new AlpineApkResource(
-+// search.fileName(), AbstractResource::Technical, this);
-+// res->setSize(666);
-+// res->setState(AbstractResource::None);
-+// m_resources.insert(res->packageName(), res);
-+// connect(res, &AlpineApkResource::stateChanged, this, &AlpineApkBackend::updatesCountChanged);
-+// return new ResultsStream(QStringLiteral("AlpineApkStream-local"), { res });
-+// }
-+
-+ AlpineApkResource *result = nullptr;
-+
-+ // QUrl("appstream://org.kde.krita.desktop")
-+ // smart workaround for appstream
-+ if (searchUrl.scheme() == QLatin1String("appstream")) {
-+ // remove leading "org.kde."
-+ QString pkgName = searchUrl.host();
-+ if (pkgName.startsWith(QLatin1String("org.kde."))) {
-+ pkgName = pkgName.mid(8);
-+ }
-+ // remove trailing ".desktop"
-+ if (pkgName.endsWith(QLatin1String(".desktop"))) {
-+ pkgName = pkgName.left(pkgName.length() - 8);
-+ }
-+ // now we can search for "krita" package
-+ result = m_resources.value(pkgName);
- }
-
-- AlpineApkResource *res = search.scheme() == QLatin1String("dummy")
-- ? m_resources.value(search.host().replace(QLatin1Char('.'), QLatin1Char(' ')))
-- : nullptr;
-- if (!res) {
-- return new ResultsStream(QStringLiteral("DummyStream"), {});
-+ if (!result) {
-+ return new ResultsStream(QStringLiteral("AlpineApkStream"), {});
- }
-- return new ResultsStream(QStringLiteral("DummyStream"), { res });
-+ return new ResultsStream(QStringLiteral("AlpineApkStream"), { result });
- }
-
--AbstractBackendUpdater* AlpineApkBackend::backendUpdater() const
-+AbstractBackendUpdater *AlpineApkBackend::backendUpdater() const
- {
- return m_updater;
- }
-
--AbstractReviewsBackend* AlpineApkBackend::reviewsBackend() const
-+AbstractReviewsBackend *AlpineApkBackend::reviewsBackend() const
- {
-- qCDebug(LOG_ALPINEAPK) << "reviewsBbackend(): we don't support reviews (";
-+ // qCDebug(LOG_ALPINEAPK) << "reviewsBbackend(): we don't support reviews (";
- // return m_reviews;
- return nullptr;
- }
-
--Transaction* AlpineApkBackend::installApplication(AbstractResource* app, const AddonList& addons)
-+Transaction* AlpineApkBackend::installApplication(AbstractResource *app, const AddonList &addons)
- {
-- return new AlpineApkTransaction(qobject_cast<AlpineApkResource*>(app), addons, Transaction::InstallRole);
-+ return new AlpineApkTransaction(qobject_cast<AlpineApkResource *>(app), addons, Transaction::InstallRole);
- }
-
--Transaction* AlpineApkBackend::installApplication(AbstractResource* app)
-+Transaction* AlpineApkBackend::installApplication(AbstractResource *app)
- {
-- return new AlpineApkTransaction(qobject_cast<AlpineApkResource*>(app), Transaction::InstallRole);
-+ return new AlpineApkTransaction(qobject_cast<AlpineApkResource *>(app), Transaction::InstallRole);
- }
-
--Transaction* AlpineApkBackend::removeApplication(AbstractResource* app)
-+Transaction* AlpineApkBackend::removeApplication(AbstractResource *app)
- {
-- return new AlpineApkTransaction(qobject_cast<AlpineApkResource*>(app), Transaction::RemoveRole);
-+ return new AlpineApkTransaction(qobject_cast<AlpineApkResource *>(app), Transaction::RemoveRole);
- }
-
- void AlpineApkBackend::checkForUpdates()
-@@ -195,18 +223,17 @@ void AlpineApkBackend::checkForUpdates()
- }
- qCDebug(LOG_ALPINEAPK) << "checkForUpdates()!";
- toggleFetching();
-- populate(QStringLiteral("Moar"));
-- QTimer::singleShot(500, this, &AlpineApkBackend::toggleFetching);
-+ // populate(QStringLiteral("Moar"));
-+ QTimer::singleShot(1000, this, &AlpineApkBackend::toggleFetching);
- }
-
- QString AlpineApkBackend::displayName() const
- {
-- return QStringLiteral("Alpine APK");
-+ return QStringLiteral("Alpine APK backend");
- }
-
- bool AlpineApkBackend::hasApplications() const
- {
-- qCDebug(LOG_ALPINEAPK) << "hasApplications(), returning true";
- return true;
- }
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-index aa520f96..624df1c9 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-@@ -24,7 +24,9 @@
- #include <resources/AbstractResourcesBackend.h>
- #include <QVariantList>
-
--//class DummyReviewsBackend;
-+#include <QtApk.h>
-+
-+// class DummyReviewsBackend;
- class StandardBackendUpdater;
- class AlpineApkResource;
- class AlpineApkBackend : public AbstractResourcesBackend
-@@ -33,19 +35,20 @@ class AlpineApkBackend : public AbstractResourcesBackend
- Q_PROPERTY(int startElements MEMBER m_startElements)
-
- public:
-- explicit AlpineApkBackend(QObject* parent = nullptr);
-+ explicit AlpineApkBackend(QObject *parent = nullptr);
-
-+ QVector<Category *> category() const override;
- int updatesCount() const override;
-- AbstractBackendUpdater* backendUpdater() const override;
-- AbstractReviewsBackend* reviewsBackend() const override;
-- ResultsStream* search(const AbstractResourcesBackend::Filters & search) override;
-- ResultsStream * findResourceByPackageName(const QUrl& search);
-- QHash<QString, AlpineApkResource*> resources() const { return m_resources; }
-+ AbstractBackendUpdater *backendUpdater() const override;
-+ AbstractReviewsBackend *reviewsBackend() const override;
-+ ResultsStream *search(const AbstractResourcesBackend::Filters &filter) override;
-+ ResultsStream *findResourceByPackageName(const QUrl &search);
-+ QHash<QString, AlpineApkResource *> resources() const { return m_resources; }
- bool isValid() const override { return true; } // No external file dependencies that could cause runtime errors
-
-- Transaction* installApplication(AbstractResource* app) override;
-- Transaction* installApplication(AbstractResource* app, const AddonList& addons) override;
-- Transaction* removeApplication(AbstractResource* app) override;
-+ Transaction *installApplication(AbstractResource *app) override;
-+ Transaction *installApplication(AbstractResource *app, const AddonList &addons) override;
-+ Transaction *removeApplication(AbstractResource *app) override;
- bool isFetching() const override { return m_fetching; }
- void checkForUpdates() override;
- QString displayName() const override;
-@@ -55,13 +58,16 @@ public Q_SLOTS:
- void toggleFetching();
-
- private:
-- void populate(const QString& name);
-+ void populate();
-
-- QHash<QString, AlpineApkResource*> m_resources;
-- StandardBackendUpdater* m_updater;
-- //DummyReviewsBackend* m_reviews;
-- bool m_fetching;
-- int m_startElements;
-+ QHash<QString, AlpineApkResource *> m_resources;
-+ StandardBackendUpdater *m_updater;
-+ // DummyReviewsBackend* m_reviews;
-+ QtApk::Database m_apkdb;
-+ QVector<QtApk::Package> m_availablePackages;
-+ QVector<QtApk::Package> m_installedPackages;
-+ bool m_fetching = true;
-+ int m_startElements = 0;
- };
-
- #endif // AlpineApkBackend_H
---
-GitLab
-
-
-From beb4fd446747223357f1763e777ca5db44e32929 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Wed, 29 Jan 2020 16:52:32 +0300
-Subject: [PATCH 12/62] WIP on AlpineApkTransaction.{h,cpp}
-
----
- .../AlpineApkBackend/AlpineApkTransaction.cpp | 11 ++++++-----
- .../backends/AlpineApkBackend/AlpineApkTransaction.h | 6 +++---
- 2 files changed, 9 insertions(+), 8 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-index 18ba5209..b4f90df5 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-@@ -28,12 +28,12 @@
-
- // #define TEST_PROCEED
-
--AlpineApkTransaction::AlpineApkTransaction(AlpineApkResource* app, Role role)
-+AlpineApkTransaction::AlpineApkTransaction(AlpineApkResource *app, Role role)
- : AlpineApkTransaction(app, {}, role)
- {
- }
-
--AlpineApkTransaction::AlpineApkTransaction(AlpineApkResource* app, const AddonList& addons, Transaction::Role role)
-+AlpineApkTransaction::AlpineApkTransaction(AlpineApkResource *app, const AddonList &addons, Transaction::Role role)
- : Transaction(app->backend(), app, role, addons)
- , m_app(app)
- {
-@@ -44,11 +44,12 @@ AlpineApkTransaction::AlpineApkTransaction(AlpineApkResource* app, const AddonLi
-
- void AlpineApkTransaction::iterateTransaction()
- {
-- if (!m_iterate)
-+ if (!m_iterate) {
- return;
-+ }
-
-- if(progress()<100) {
-- setProgress(qBound(0, progress()+(KRandom::random()%30), 100));
-+ if(progress() < 100) {
-+ setProgress(qBound(0, progress() + (KRandom::random() % 30), 100));
- QTimer::singleShot(/*KRandom::random()%*/100, this, &AlpineApkTransaction::iterateTransaction);
- } else if (status() == DownloadingStatus) {
- setStatus(CommittingStatus);
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h
-index 8739eca1..63aeef8d 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h
-@@ -28,8 +28,8 @@ class AlpineApkTransaction : public Transaction
- {
- Q_OBJECT
- public:
-- AlpineApkTransaction(AlpineApkResource* app, Role role);
-- AlpineApkTransaction(AlpineApkResource* app, const AddonList& list, Role role);
-+ AlpineApkTransaction(AlpineApkResource *app, Role role);
-+ AlpineApkTransaction(AlpineApkResource *app, const AddonList &list, Role role);
-
- void cancel() override;
- void proceed() override;
-@@ -40,7 +40,7 @@ class AlpineApkTransaction : public Transaction
-
- private:
- bool m_iterate = true;
-- AlpineApkResource* m_app;
-+ AlpineApkResource *m_app;
- };
-
- #endif // ALPINEAPKTRANSACTION_H
---
-GitLab
-
-
-From 38d4444f1a4e5b3c8e76271fdec6273e3c59bc72 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Wed, 29 Jan 2020 17:35:17 +0300
-Subject: [PATCH 13/62] CMake: Add AlpineApkReviewsBackend + its files
-
----
- .../AlpineApkReviewsBackend.cpp | 35 +++++++++++++
- .../AlpineApkReviewsBackend.h | 52 +++++++++++++++++++
- .../backends/AlpineApkBackend/CMakeLists.txt | 2 +
- 3 files changed, 89 insertions(+)
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkReviewsBackend.cpp
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkReviewsBackend.h
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkReviewsBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkReviewsBackend.cpp
-new file mode 100644
-index 00000000..fd7ad47f
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkReviewsBackend.cpp
-@@ -0,0 +1,35 @@
-+/***************************************************************************
-+ * Copyright © 2020 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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 "AlpineApkReviewsBackend.h"
-+#include "AlpineApkBackend.h"
-+#include "resources/AbstractResource.h"
-+
-+AlpineApkReviewsBackend::AlpineApkReviewsBackend(AlpineApkBackend *parent)
-+ : AbstractReviewsBackend(parent)
-+{
-+}
-+
-+void AlpineApkReviewsBackend::fetchReviews(AbstractResource *app, int page)
-+{
-+ Q_UNUSED(page)
-+ static const QVector<ReviewPtr> reviews;
-+ Q_EMIT reviewsReady(app, reviews, false);
-+}
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkReviewsBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkReviewsBackend.h
-new file mode 100644
-index 00000000..435f845b
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkReviewsBackend.h
-@@ -0,0 +1,52 @@
-+/***************************************************************************
-+ * Copyright © 2020 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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/>. *
-+ ***************************************************************************/
-+
-+#ifndef ALPINEAPKREVIEWSBACKEND_H
-+#define ALPINEAPKREVIEWSBACKEND_H
-+
-+#include "ReviewsBackend/AbstractReviewsBackend.h"
-+
-+class AlpineApkBackend;
-+
-+class AlpineApkReviewsBackend : public AbstractReviewsBackend
-+{
-+ Q_OBJECT
-+
-+public:
-+ explicit AlpineApkReviewsBackend(AlpineApkBackend *parent = nullptr);
-+
-+ QString userName() const override { return QStringLiteral("dummy"); }
-+ void login() override {}
-+ void logout() override {}
-+ void registerAndLogin() override {}
-+
-+ Rating *ratingForApplication(AbstractResource *) const override { return nullptr; }
-+ bool hasCredentials() const override { return false; }
-+ void deleteReview(Review *) override {}
-+ void fetchReviews(AbstractResource *app, int page = 1) override;
-+ bool isFetching() const override { return false; }
-+ bool isReviewable() const override { return false; }
-+ void submitReview(AbstractResource *, const QString &, const QString &, const QString &) override {}
-+ void flagReview(Review *, const QString&, const QString&) override {}
-+ void submitUsefulness(Review *, bool) override {}
-+ bool isResourceSupported(AbstractResource *) const override { return false; }
-+};
-+
-+#endif // ALPINEAPKREVIEWSBACKEND_H
-diff --git a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-index 45a56eb6..7d2b86e8 100644
---- a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-+++ b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-@@ -5,6 +5,8 @@ set(alpineapkbackend_SRCS
- AlpineApkBackend.h
- AlpineApkResource.cpp
- AlpineApkResource.h
-+ AlpineApkReviewsBackend.cpp
-+ AlpineApkReviewsBackend.h
- AlpineApkSourcesBackend.cpp
- AlpineApkSourcesBackend.h
- AlpineApkTransaction.cpp
---
-GitLab
-
-
-From bf1e9e0abc37b45c9a05c5dac8bc66050329666b Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Wed, 29 Jan 2020 17:35:43 +0300
-Subject: [PATCH 14/62] AlpineApkBackend: use own reviews backend
-
----
- .../AlpineApkBackend/AlpineApkBackend.cpp | 15 +++++----------
- .../backends/AlpineApkBackend/AlpineApkBackend.h | 4 ++--
- 2 files changed, 7 insertions(+), 12 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index f5aa5477..de93609a 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -20,7 +20,7 @@
-
- #include "AlpineApkBackend.h"
- #include "AlpineApkResource.h"
--//#include "DummyReviewsBackend.h"
-+#include "AlpineApkReviewsBackend.h"
- #include "AlpineApkTransaction.h"
- #include "AlpineApkSourcesBackend.h"
- #include "alpineapk_backend_logging.h" // generated by ECM
-@@ -46,6 +46,7 @@ DISCOVER_BACKEND_PLUGIN(AlpineApkBackend)
- AlpineApkBackend::AlpineApkBackend(QObject *parent)
- : AbstractResourcesBackend(parent)
- , m_updater(new StandardBackendUpdater(this))
-+ , m_reviews(new AlpineApkReviewsBackend(this))
- , m_startElements(120)
- {
- #ifndef QT_DEBUG
-@@ -55,12 +56,9 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
- qCDebug(LOG_ALPINEAPK) << "constructing backend!";
-
- QTimer::singleShot(500, this, &AlpineApkBackend::toggleFetching);
-- //connect(m_reviews, &DummyReviewsBackend::ratingsReady, this, &AbstractResourcesBackend::emitRatingsReady);
- connect(m_updater, &StandardBackendUpdater::updatesCountChanged, this, &AlpineApkBackend::updatesCountChanged);
-
- populate();
-- //if (!m_fetching)
-- // m_reviews->initialize();
-
- SourcesModel::global()->addSourcesBackend(new AlpineApkSourcesBackend(this));
- }
-@@ -117,10 +115,9 @@ void AlpineApkBackend::populate()
- void AlpineApkBackend::toggleFetching()
- {
- m_fetching = !m_fetching;
-+
- qCDebug(LOG_ALPINEAPK) << "fetching..." << m_fetching;
- emit fetchingChanged();
-- //if (!m_fetching)
-- // m_reviews->initialize();
- }
-
- int AlpineApkBackend::updatesCount() const
-@@ -195,9 +192,7 @@ AbstractBackendUpdater *AlpineApkBackend::backendUpdater() const
-
- AbstractReviewsBackend *AlpineApkBackend::reviewsBackend() const
- {
-- // qCDebug(LOG_ALPINEAPK) << "reviewsBbackend(): we don't support reviews (";
-- // return m_reviews;
-- return nullptr;
-+ return m_reviews;
- }
-
- Transaction* AlpineApkBackend::installApplication(AbstractResource *app, const AddonList &addons)
-@@ -221,7 +216,7 @@ void AlpineApkBackend::checkForUpdates()
- qCDebug(LOG_ALPINEAPK) << "checkForUpdates(): already fetching";
- return;
- }
-- qCDebug(LOG_ALPINEAPK) << "checkForUpdates()!";
-+ qCDebug(LOG_ALPINEAPK) << "checkForUpdates() start!";
- toggleFetching();
- // populate(QStringLiteral("Moar"));
- QTimer::singleShot(1000, this, &AlpineApkBackend::toggleFetching);
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-index 624df1c9..f8d3aa69 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-@@ -26,7 +26,7 @@
-
- #include <QtApk.h>
-
--// class DummyReviewsBackend;
-+class AlpineApkReviewsBackend;
- class StandardBackendUpdater;
- class AlpineApkResource;
- class AlpineApkBackend : public AbstractResourcesBackend
-@@ -62,7 +62,7 @@ private:
-
- QHash<QString, AlpineApkResource *> m_resources;
- StandardBackendUpdater *m_updater;
-- // DummyReviewsBackend* m_reviews;
-+ AlpineApkReviewsBackend *m_reviews;
- QtApk::Database m_apkdb;
- QVector<QtApk::Package> m_availablePackages;
- QVector<QtApk::Package> m_installedPackages;
---
-GitLab
-
-
-From 66568f954f32ce86674b72b42095c784c12ae67a Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Wed, 29 Jan 2020 19:53:39 +0300
-Subject: [PATCH 15/62] AlpineApkBackend: some cleanup on updates checking
- functions
-
----
- .../AlpineApkBackend/AlpineApkBackend.cpp | 41 ++++++++++++-------
- .../AlpineApkBackend/AlpineApkBackend.h | 5 ++-
- 2 files changed, 30 insertions(+), 16 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index de93609a..41b2e053 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -55,8 +55,10 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
-
- qCDebug(LOG_ALPINEAPK) << "constructing backend!";
-
-- QTimer::singleShot(500, this, &AlpineApkBackend::toggleFetching);
-- connect(m_updater, &StandardBackendUpdater::updatesCountChanged, this, &AlpineApkBackend::updatesCountChanged);
-+ QTimer::singleShot(1000, this, &AlpineApkBackend::startCheckForUpdates);
-+
-+ QObject::connect(m_updater, &StandardBackendUpdater::updatesCountChanged,
-+ this, &AlpineApkBackend::updatesCountChanged);
-
- populate();
-
-@@ -65,12 +67,14 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
-
- QVector<Category *> AlpineApkBackend::category() const
- {
-+ // single root category
-+ // we could add more, but Alpine apk does not have this concept
- static Category *cat = new Category(
-- QStringLiteral("All applications"), // displayName
-- QStringLiteral("applications-other"), // icon
-- { }, // orFilters
-+ QStringLiteral("All packages"), // displayName
-+ QStringLiteral("package-x-generic"), // icon
-+ {}, // orFilters
- { displayName() }, // pluginName
-- { }, // subCategories
-+ {}, // subCategories
- QUrl(), // decoration (what is it?)
- false // isAddons
- );
-@@ -112,11 +116,23 @@ void AlpineApkBackend::populate()
- }
- }
-
--void AlpineApkBackend::toggleFetching()
-+void AlpineApkBackend::startCheckForUpdates()
- {
-- m_fetching = !m_fetching;
-+ if (m_fetching) {
-+ return;
-+ }
-+ qCDebug(LOG_ALPINEAPK) << "startCheckForUpdates()";
-+
-+ m_fetching = true;
-+ emit fetchingChanged();
-+
-+ // temporary hack - finish updates check in 5 seconds
-+ QTimer::singleShot(5000, this, &AlpineApkBackend::finishCheckForUpdates);
-+}
-
-- qCDebug(LOG_ALPINEAPK) << "fetching..." << m_fetching;
-+void AlpineApkBackend::finishCheckForUpdates()
-+{
-+ m_fetching = false;
- emit fetchingChanged();
- }
-
-@@ -212,14 +228,11 @@ Transaction* AlpineApkBackend::removeApplication(AbstractResource *app)
-
- void AlpineApkBackend::checkForUpdates()
- {
-- if(m_fetching) {
-+ if (m_fetching) {
- qCDebug(LOG_ALPINEAPK) << "checkForUpdates(): already fetching";
- return;
- }
-- qCDebug(LOG_ALPINEAPK) << "checkForUpdates() start!";
-- toggleFetching();
-- // populate(QStringLiteral("Moar"));
-- QTimer::singleShot(1000, this, &AlpineApkBackend::toggleFetching);
-+ startCheckForUpdates();
- }
-
- QString AlpineApkBackend::displayName() const
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-index f8d3aa69..68a47bc9 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-@@ -55,7 +55,8 @@ public:
- bool hasApplications() const override;
-
- public Q_SLOTS:
-- void toggleFetching();
-+ void startCheckForUpdates();
-+ void finishCheckForUpdates();
-
- private:
- void populate();
-@@ -66,7 +67,7 @@ private:
- QtApk::Database m_apkdb;
- QVector<QtApk::Package> m_availablePackages;
- QVector<QtApk::Package> m_installedPackages;
-- bool m_fetching = true;
-+ bool m_fetching = false;
- int m_startElements = 0;
- };
-
---
-GitLab
-
-
-From a1bdcdee0dba5da980732c07cdd576929935e5da Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Wed, 29 Jan 2020 19:54:04 +0300
-Subject: [PATCH 16/62] Add KAuth helper process for privileged operations
-
----
- .../AlpineApkBackend/AlpineApkAuthHelper.cpp | 56 +++++++++++++++++++
- .../AlpineApkBackend/AlpineApkAuthHelper.h | 35 ++++++++++++
- .../backends/AlpineApkBackend/CMakeLists.txt | 26 ++++++++-
- .../org.kde.discover.alpineapkbackend.actions | 5 ++
- 4 files changed, 120 insertions(+), 2 deletions(-)
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
- create mode 100644 libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-new file mode 100644
-index 00000000..6783f35c
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-@@ -0,0 +1,56 @@
-+/***************************************************************************
-+ * Copyright © 2020 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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 <QProcess>
-+#include <QDebug>
-+#include <QJsonDocument>
-+#include <QJsonObject>
-+#include <QJsonArray>
-+#include <QFile>
-+#include <KAuthHelperSupport>
-+
-+#include "AlpineApkAuthHelper.h"
-+
-+using namespace KAuth;
-+
-+AlpineApkAuthHelper::AlpineApkAuthHelper() {}
-+
-+ActionReply AlpineApkAuthHelper::test_action(const QVariantMap &args)
-+{
-+ const QString txt = args[QStringLiteral("txt")].toString();
-+
-+ ActionReply reply = ActionReply::HelperErrorReply();
-+ QByteArray replyData(QByteArrayLiteral("ok"));
-+
-+ QFile f(QStringLiteral("/lol.txt"));
-+ if (f.open(QIODevice::ReadWrite | QIODevice::Text)) {
-+ f.write(txt.toUtf8());
-+ f.close();
-+
-+ reply = ActionReply::SuccessReply();
-+ reply.setData({
-+ { QStringLiteral("reply"), replyData },
-+ });
-+ }
-+
-+ return reply;
-+}
-+
-+KAUTH_HELPER_MAIN("org.kde.discover.alpineapkbackend", AlpineApkAuthHelper)
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-new file mode 100644
-index 00000000..86f7d3dc
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-@@ -0,0 +1,35 @@
-+/***************************************************************************
-+ * Copyright © 2020 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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 <QObject>
-+#include <QVariant>
-+#include <KAuthActionReply>
-+
-+using namespace KAuth;
-+
-+class AlpineApkAuthHelper : public QObject
-+{
-+ Q_OBJECT
-+public:
-+ AlpineApkAuthHelper();
-+
-+public Q_SLOTS:
-+ ActionReply test_action(const QVariantMap &args);
-+};
-diff --git a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-index 7d2b86e8..f67cf84f 100644
---- a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-+++ b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-@@ -1,4 +1,4 @@
--# add_subdirectory(tests) # no tests yet
-+find_package(KF5Auth CONFIG REQUIRED) # Probably should be moved to top CMakeLists
-
- set(alpineapkbackend_SRCS
- AlpineApkBackend.cpp
-@@ -38,12 +38,34 @@ target_link_libraries(
- apk-qt
- )
-
-+# KAuth helper exe
-+add_executable(alpineapk_kauth_helper
-+ AlpineApkAuthHelper.cpp
-+ AlpineApkAuthHelper.h
-+ org.kde.discover.alpineapkbackend.actions
-+)
-+set_source_files_properties(
-+ org.kde.discover.alpineapkbackend.actions
-+ PROPERTIES HEADER_FILE_ONLY ON
-+)
-+target_link_libraries(alpineapk_kauth_helper
-+ Qt5::Core
-+ KF5::AuthCore
-+ apk-qt
-+)
-+
-+kauth_install_actions(org.kde.discover.alpineapkbackend org.kde.discover.alpineapkbackend.actions)
-+kauth_install_helper_files(alpineapk_kauth_helper org.kde.discover.alpineapkbackend root)
-+
- install(
- TARGETS alpineapk-backend
- DESTINATION ${PLUGIN_INSTALL_DIR}/discover
- )
-
--# install(FILES alpineapk-backend-categories.xml DESTINATION ${DATA_INSTALL_DIR}/libdiscover/categories)
-+install(
-+ TARGETS alpineapk_kauth_helper
-+ DESTINATION ${KAUTH_HELPER_INSTALL_DIR}
-+)
-
- # add_library(AlpineApkNotifier MODULE AlpineApkNotifier.cpp)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-new file mode 100644
-index 00000000..ba9ede91
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-@@ -0,0 +1,5 @@
-+[org.kde.discover.alpineapkbackend.test_action]
-+Name=Test Action
-+Description=Just test
-+Policy=auth_admin
-+Persistence=session
---
-GitLab
-
-
-From 992a4f4f3444194feb87ffa9c57f57e16261ae0b Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Wed, 29 Jan 2020 20:41:07 +0300
-Subject: [PATCH 17/62] AlpineApkBackend: WIP on using KAuth helper
-
----
- .../AlpineApkBackend/AlpineApkAuthHelper.cpp | 2 +-
- .../AlpineApkBackend/AlpineApkAuthHelper.h | 2 +-
- .../AlpineApkBackend/AlpineApkBackend.cpp | 34 +++++++++++++++++--
- .../AlpineApkBackend/AlpineApkBackend.h | 3 ++
- .../backends/AlpineApkBackend/CMakeLists.txt | 1 +
- .../org.kde.discover.alpineapkbackend.actions | 2 +-
- 6 files changed, 39 insertions(+), 5 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-index 6783f35c..19236dcb 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-@@ -32,7 +32,7 @@ using namespace KAuth;
-
- AlpineApkAuthHelper::AlpineApkAuthHelper() {}
-
--ActionReply AlpineApkAuthHelper::test_action(const QVariantMap &args)
-+ActionReply AlpineApkAuthHelper::test(const QVariantMap &args)
- {
- const QString txt = args[QStringLiteral("txt")].toString();
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-index 86f7d3dc..947dcb7a 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-@@ -31,5 +31,5 @@ public:
- AlpineApkAuthHelper();
-
- public Q_SLOTS:
-- ActionReply test_action(const QVariantMap &args);
-+ ActionReply test(const QVariantMap &args);
- };
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index 41b2e053..ed016aef 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -35,6 +35,8 @@
- #include <KPluginFactory>
- #include <KConfigGroup>
- #include <KSharedConfig>
-+#include <KAuthExecuteJob>
-+
- #include <QDebug>
- #include <QLoggingCategory>
- #include <QThread>
-@@ -116,6 +118,19 @@ void AlpineApkBackend::populate()
- }
- }
-
-+void AlpineApkBackend::handleKauthHelperReply(KJob *job)
-+{
-+ qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+ KAuth::ExecuteJob* reply = static_cast<KAuth::ExecuteJob *>(job);
-+ const QVariantMap replyData = reply->data();
-+ if (reply->error() == 0) {
-+ qCDebug(LOG_ALPINEAPK) << replyData[QLatin1String("reply")].toString();
-+ } else {
-+ const QString message = replyData.value(QLatin1String("errorString"), reply->errorString()).toString();
-+ qCDebug(LOG_ALPINEAPK) << message;
-+ }
-+}
-+
- void AlpineApkBackend::startCheckForUpdates()
- {
- if (m_fetching) {
-@@ -123,11 +138,26 @@ void AlpineApkBackend::startCheckForUpdates()
- }
- qCDebug(LOG_ALPINEAPK) << "startCheckForUpdates()";
-
-+ // temporary hack - finish updates check in 5 seconds
-+ QTimer::singleShot(5000, this, &AlpineApkBackend::finishCheckForUpdates);
-+
- m_fetching = true;
- emit fetchingChanged();
-
-- // temporary hack - finish updates check in 5 seconds
-- QTimer::singleShot(5000, this, &AlpineApkBackend::finishCheckForUpdates);
-+ KAuth::Action testAction(QStringLiteral("org.kde.discover.alpineapkbackend.test"));
-+ testAction.setHelperId(QStringLiteral("org.kde.discover.alpineapkbackend"));
-+ testAction.setArguments({
-+ { QStringLiteral("txt"), QLatin1String("Wooo!") },
-+ });
-+ if (!testAction.isValid()) {
-+ qCWarning(LOG_ALPINEAPK) << "kauth action is not valid!";
-+ return;
-+ }
-+
-+ KAuth::ExecuteJob *reply = testAction.execute();
-+ QObject::connect(reply, &KAuth::ExecuteJob::result,
-+ this, &AlpineApkBackend::handleKauthHelperReply);
-+ reply->start();
- }
-
- void AlpineApkBackend::finishCheckForUpdates()
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-index 68a47bc9..a533cee3 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-@@ -29,6 +29,8 @@
- class AlpineApkReviewsBackend;
- class StandardBackendUpdater;
- class AlpineApkResource;
-+class KJob;
-+
- class AlpineApkBackend : public AbstractResourcesBackend
- {
- Q_OBJECT
-@@ -55,6 +57,7 @@ public:
- bool hasApplications() const override;
-
- public Q_SLOTS:
-+ void handleKauthHelperReply(KJob *job);
- void startCheckForUpdates();
- void finishCheckForUpdates();
-
-diff --git a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-index f67cf84f..ede3157f 100644
---- a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-+++ b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-@@ -34,6 +34,7 @@ target_link_libraries(
- Qt5::Widgets
- KF5::CoreAddons
- KF5::ConfigCore
-+ KF5::AuthCore
- Discover::Common
- apk-qt
- )
-diff --git a/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-index ba9ede91..3b9a3116 100644
---- a/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-+++ b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-@@ -1,4 +1,4 @@
--[org.kde.discover.alpineapkbackend.test_action]
-+[org.kde.discover.alpineapkbackend.test]
- Name=Test Action
- Description=Just test
- Policy=auth_admin
---
-GitLab
-
-
-From 1b05b5e711e98b69e07bc00c3f8b2c6608c09897 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Sun, 2 Feb 2020 19:08:38 +0300
-Subject: [PATCH 18/62] AlpineApkSourcesBackend: tidy up logging and add I18N
-
----
- .../AlpineApkBackend/AlpineApkSourcesBackend.cpp | 14 +++++++++-----
- 1 file changed, 9 insertions(+), 5 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-index 09a86bdf..b964b40d 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-@@ -20,10 +20,14 @@
-
- #include "AlpineApkSourcesBackend.h"
- #include "alpineapk_backend_logging.h" // generated by ECM
-+
- #include <QDebug>
- #include <QAction>
- #include <QVector>
-
-+// KF5
-+#include <KLocalizedString>
-+
- // libapk-qt
- #include <QtApk.h>
-
-@@ -39,7 +43,7 @@ AlpineApkSourcesBackend::AlpineApkSourcesBackend(AbstractResourcesBackend *paren
-
- // can be used to track enabling/disabling repo source
- // QObject::connect(m_sourcesModel, &QStandardItemModel::itemChanged, this, [](QStandardItem* item) {
-- // qCDebug(LOG_ALPINEAPK) << "DummySource changed" << item << item->checkState();
-+ // qCDebug(LOG_ALPINEAPK) << "source backend: DummySource changed" << item << item->checkState();
- // });
- }
-
-@@ -70,7 +74,7 @@ bool AlpineApkSourcesBackend::addSourceFull(const QString &id, const QString &co
- return false;
- }
-
-- qCDebug(LOG_ALPINEAPK) << "AlpineApkSourcesBackend: Adding source:" << id;
-+ qCDebug(LOG_ALPINEAPK) << "source backend: Adding source:" << id;
-
- QStandardItem *it = new QStandardItem(id);
- it->setData(id, AbstractSourcesBackend::IdRole);
-@@ -96,7 +100,7 @@ bool AlpineApkSourcesBackend::removeSource(const QString &id)
- {
- const QStandardItem *it = sourceForId(id);
- if (!it) {
-- qCWarning(LOG_ALPINEAPK) << "AlpineApkSourcesBackend: couldn't find " << id;
-+ qCWarning(LOG_ALPINEAPK) << "source backend: couldn't find " << id;
- return false;
- }
- return m_sourcesModel->removeRow(it->row());
-@@ -104,8 +108,8 @@ bool AlpineApkSourcesBackend::removeSource(const QString &id)
-
- QString AlpineApkSourcesBackend::idDescription()
- {
-- return QStringLiteral("Enter apk repository URL, for example: "
-- "http://dl-cdn.alpinelinux.org/alpine/edge/testing/");
-+ return i18nc("Adding repo", "Enter apk repository URL, for example: "
-+ "http://dl-cdn.alpinelinux.org/alpine/edge/testing/");
- }
-
- QVariantList AlpineApkSourcesBackend::actions() const
---
-GitLab
-
-
-From 85e37f8afe2d71c3f2fd5a321579353f46e9c54c Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Mon, 3 Feb 2020 03:49:52 +0300
-Subject: [PATCH 19/62] kath helper: add and implement update() and upgrade()
- actions
-
----
- .../AlpineApkBackend/AlpineApkAuthHelper.cpp | 97 +++++++++++++++++++
- .../AlpineApkBackend/AlpineApkAuthHelper.h | 9 ++
- .../org.kde.discover.alpineapkbackend.actions | 24 +++++
- 3 files changed, 130 insertions(+)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-index 19236dcb..4ff5c880 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-@@ -20,14 +20,22 @@
-
- #include <QProcess>
- #include <QDebug>
-+#include <QLoggingCategory>
- #include <QJsonDocument>
- #include <QJsonObject>
- #include <QJsonArray>
- #include <QFile>
-+
- #include <KAuthHelperSupport>
-
- #include "AlpineApkAuthHelper.h"
-
-+#ifdef QT_DEBUG
-+Q_LOGGING_CATEGORY(LOG_AUTHHELPER, "org.kde.discover.alpineapkbackend.authhelper", QtDebugMsg)
-+#else
-+Q_LOGGING_CATEGORY(LOG_AUTHHELPER, "org.kde.discover.alpineapkbackend.authhelper", QtWarningMsg)
-+#endif
-+
- using namespace KAuth;
-
- AlpineApkAuthHelper::AlpineApkAuthHelper() {}
-@@ -39,6 +47,7 @@ ActionReply AlpineApkAuthHelper::test(const QVariantMap &args)
- ActionReply reply = ActionReply::HelperErrorReply();
- QByteArray replyData(QByteArrayLiteral("ok"));
-
-+ // write some text file at the root directory as root, why not
- QFile f(QStringLiteral("/lol.txt"));
- if (f.open(QIODevice::ReadWrite | QIODevice::Text)) {
- f.write(txt.toUtf8());
-@@ -53,4 +62,92 @@ ActionReply AlpineApkAuthHelper::test(const QVariantMap &args)
- return reply;
- }
-
-+ActionReply AlpineApkAuthHelper::update(const QVariantMap &args)
-+{
-+ Q_UNUSED(args)
-+ ActionReply reply = ActionReply::HelperErrorReply();
-+
-+ HelperSupport::progressStep(10);
-+
-+ if (!m_apkdb.open(QtApk::Database::QTAPK_OPENF_READWRITE)) {
-+ reply.setErrorDescription(QStringLiteral("Failed to open database!"));
-+ return reply;
-+ }
-+
-+ bool update_ok = m_apkdb.updatePackageIndex();
-+
-+ if (update_ok) {
-+ int updatesCount = m_apkdb.upgradeablePackagesCount();
-+ reply = ActionReply::SuccessReply();
-+ reply.setData({
-+ { QLatin1String("updatesCount"), updatesCount }
-+ });
-+ } else {
-+ reply.setErrorDescription(QStringLiteral("Repo update failed!"));
-+ reply.setData({
-+ { QLatin1String("errorString"), QStringLiteral("Repo update failed!") }
-+ });
-+ }
-+
-+ m_apkdb.close();
-+ HelperSupport::progressStep(100);
-+
-+ return reply;
-+}
-+
-+ActionReply AlpineApkAuthHelper::add(const QVariantMap &args)
-+{
-+ ActionReply reply = ActionReply::HelperErrorReply();
-+ return reply;
-+}
-+
-+ActionReply AlpineApkAuthHelper::del(const QVariantMap &args)
-+{
-+ ActionReply reply = ActionReply::HelperErrorReply();
-+ return reply;
-+}
-+
-+ActionReply AlpineApkAuthHelper::upgrade(const QVariantMap &args)
-+{
-+ ActionReply reply = ActionReply::HelperErrorReply();
-+
-+ HelperSupport::progressStep(10);
-+
-+ if (!m_apkdb.open(QtApk::Database::QTAPK_OPENF_READWRITE)) {
-+ reply.setErrorDescription(QStringLiteral("Failed to open database!"));
-+ return reply;
-+ }
-+
-+ bool onlySimulate = args.value(QLatin1String("onlySimulate"), false).toBool();
-+ QtApk::Database::DbUpgradeFlags flags = QtApk::Database::QTAPK_UPGRADE_DEFAULT;
-+ if (onlySimulate) {
-+ flags = QtApk::Database::QTAPK_UPGRADE_SIMULATE;
-+ qCDebug(LOG_AUTHHELPER) << "Simulating upgrade run.";
-+ }
-+
-+ QtApk::Changeset changes;
-+ bool upgrade_ok = m_apkdb.upgrade(flags, &changes);
-+
-+ if (upgrade_ok) {
-+ reply = ActionReply::SuccessReply();
-+ QVariantMap replyData;
-+ const QVector<QtApk::ChangesetItem> ch = changes.changes();
-+ QVector<QVariant> chVector;
-+ QVector<QtApk::Package> pkgVector;
-+ for (const QtApk::ChangesetItem &it: ch) {
-+ pkgVector << it.newPackage;
-+ }
-+ replyData.insert(QLatin1String("changes"), QVariant::fromValue(pkgVector));
-+ replyData.insert(QLatin1String("onlySimulate"), onlySimulate);
-+ reply.setData(replyData);
-+ } else {
-+ reply.setErrorDescription(QStringLiteral("Repo upgrade failed!"));
-+ }
-+
-+ m_apkdb.close();
-+ HelperSupport::progressStep(100);
-+
-+ return reply;
-+}
-+
- KAUTH_HELPER_MAIN("org.kde.discover.alpineapkbackend", AlpineApkAuthHelper)
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-index 947dcb7a..5c06e557 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-@@ -22,6 +22,8 @@
- #include <QVariant>
- #include <KAuthActionReply>
-
-+#include <QtApk.h>
-+
- using namespace KAuth;
-
- class AlpineApkAuthHelper : public QObject
-@@ -32,4 +34,11 @@ public:
-
- public Q_SLOTS:
- ActionReply test(const QVariantMap &args);
-+ ActionReply update(const QVariantMap &args);
-+ ActionReply add(const QVariantMap &args);
-+ ActionReply del(const QVariantMap &args);
-+ ActionReply upgrade(const QVariantMap &args);
-+
-+private:
-+ QtApk::Database m_apkdb;
- };
-diff --git a/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-index 3b9a3116..10305a1a 100644
---- a/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-+++ b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-@@ -3,3 +3,27 @@ Name=Test Action
- Description=Just test
- Policy=auth_admin
- Persistence=session
-+
-+[org.kde.discover.alpineapkbackend.update]
-+Name=Update repository index
-+Description=Updates available packages list from repositories
-+Policy=auth_admin
-+Persistence=session
-+
-+[org.kde.discover.alpineapkbackend.upgrade]
-+Name=Upgrade all upgradable packages
-+Description=Upgrade installed packages to latest versions
-+Policy=auth_admin
-+Persistence=session
-+
-+[org.kde.discover.alpineapkbackend.add]
-+Name=Install/upgrade package
-+Description=Installs/upgrades one package
-+Policy=auth_admin
-+Persistence=session
-+
-+[org.kde.discover.alpineapkbackend.del]
-+Name=Remove package
-+Description=Uninstall one package
-+Policy=auth_admin
-+Persistence=session
---
-GitLab
-
-
-From c36853bbfa5312a9fe2e816df7548e353cb142b5 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Mon, 3 Feb 2020 03:51:02 +0300
-Subject: [PATCH 20/62] AlpineApkResource: add availableVersion field
-
-for updates
----
- .../backends/AlpineApkBackend/AlpineApkResource.cpp | 8 ++++++--
- libdiscover/backends/AlpineApkBackend/AlpineApkResource.h | 2 ++
- 2 files changed, 8 insertions(+), 2 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-index d827e7b3..af480b6c 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-@@ -18,7 +18,6 @@
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
--#include <KRandom>
- #include "AlpineApkResource.h"
- #include "alpineapk_backend_logging.h" // generated by ECM
- #include "Transaction/AddonList.h"
-@@ -39,7 +38,7 @@ QList<PackageState> AlpineApkResource::addonsInformation()
-
- QString AlpineApkResource::availableVersion() const
- {
-- return m_pkg.version;
-+ return m_availableVersion;
- }
-
- QStringList AlpineApkResource::categories()
-@@ -180,6 +179,11 @@ void AlpineApkResource::setAddonInstalled(const QString &addon, bool installed)
- }
- }
-
-+void AlpineApkResource::setAvailableVersion(const QString &av)
-+{
-+ m_availableVersion = av;
-+}
-+
-
- void AlpineApkResource::invokeApplication() const
- {
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-index 79b100e1..7140786c 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-@@ -67,11 +67,13 @@ public:
- void setSection(const QString &sectionName);
- void setAddons(const AddonList &addons);
- void setAddonInstalled(const QString &addon, bool installed);
-+ void setAvailableVersion(const QString &av);
-
- public:
- AbstractResource::State m_state;
- const AbstractResource::Type m_type;
- QtApk::Package m_pkg;
-+ QString m_availableVersion;
- QString m_category;
- QString m_originSoruce;
- QString m_sectionName;
---
-GitLab
-
-
-From d5fbfb4b162848dad2b732fe513798f73f9bbd94 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Mon, 3 Feb 2020 03:51:58 +0300
-Subject: [PATCH 21/62] Add AlpineApkUpdater class
-
----
- .../AlpineApkBackend/AlpineApkUpdater.cpp | 286 ++++++++++++++++++
- .../AlpineApkBackend/AlpineApkUpdater.h | 190 ++++++++++++
- .../backends/AlpineApkBackend/CMakeLists.txt | 2 +
- 3 files changed, 478 insertions(+)
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-new file mode 100644
-index 00000000..1dd6cdac
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-@@ -0,0 +1,286 @@
-+/***************************************************************************
-+ * Copyright © 2020 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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 "AlpineApkUpdater.h"
-+#include "AlpineApkResource.h"
-+#include "AlpineApkBackend.h"
-+#include "alpineapk_backend_logging.h"
-+#include "utils.h"
-+
-+#include <KAuthExecuteJob>
-+#include <KLocalizedString>
-+
-+#include <QtApk.h>
-+
-+
-+AlpineApkUpdater::AlpineApkUpdater(AbstractResourcesBackend *parent)
-+ : AbstractBackendUpdater(parent)
-+ , m_backend(static_cast<AlpineApkBackend *>(parent))
-+{
-+ //
-+}
-+
-+void AlpineApkUpdater::prepare()
-+{
-+ qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+
-+ QtApk::Database *db = m_backend->apkdb();
-+
-+ if (db->isOpen()) {
-+ return;
-+ }
-+
-+ if (!db->open(QtApk::Database::QTAPK_OPENF_READONLY)) {
-+ emit passiveMessage(i18n("Failed to open APK database!"));
-+ return;
-+ }
-+
-+ if (!db->upgrade(QtApk::Database::QTAPK_UPGRADE_SIMULATE, &m_upgradeable)) {
-+ emit passiveMessage(i18n("Failed to get a list of packages to upgrade!"));
-+ db->close();
-+ return;
-+ }
-+ // clsoe DB ASAP
-+ db->close();
-+
-+ m_updatesCount = m_upgradeable.changes().size();
-+ qCDebug(LOG_ALPINEAPK) << "updater: prepare: updates count" << m_updatesCount;
-+
-+ m_allUpdateable.clear();
-+ m_markedToUpdate.clear();
-+ QHash<QString, AlpineApkResource *> *resources = m_backend->resourcesPtr();
-+ for (const QtApk::ChangesetItem &it : qAsConst(m_upgradeable.changes())) {
-+ const QtApk::Package &oldPkg = it.oldPackage;
-+ const QString newVersion = it.newPackage.version;
-+ AlpineApkResource *res = resources->value(oldPkg.name);
-+ if (res) {
-+ res->setAvailableVersion(newVersion);
-+ m_allUpdateable.insert(res);
-+ m_markedToUpdate.insert(res);
-+ }
-+ }
-+
-+ // emitting this signal here leads to infinite recursion
-+ // emit updatesCountChanged(m_updatesCount);
-+}
-+
-+bool AlpineApkUpdater::hasUpdates() const
-+{
-+ // qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO << m_updatesCount;
-+ return (m_updatesCount > 0);
-+}
-+
-+qreal AlpineApkUpdater::progress() const
-+{
-+ qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+ return 0.0;
-+}
-+
-+void AlpineApkUpdater::removeResources(const QList<AbstractResource *> &apps)
-+{
-+ // qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+ const QSet<AbstractResource *> checkSet = kToSet(apps);
-+ m_markedToUpdate -= checkSet;
-+}
-+
-+void AlpineApkUpdater::addResources(const QList<AbstractResource *> &apps)
-+{
-+ //Q_UNUSED(apps)
-+ //qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+ const QSet<AbstractResource *> checkSet = kToSet(apps);
-+ m_markedToUpdate += checkSet;
-+}
-+
-+QList<AbstractResource *> AlpineApkUpdater::toUpdate() const
-+{
-+ // qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+ return m_allUpdateable.values();
-+}
-+
-+QDateTime AlpineApkUpdater::lastUpdate() const
-+{
-+ qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+ return QDateTime();
-+}
-+
-+bool AlpineApkUpdater::isCancelable() const
-+{
-+ qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+ return true;
-+}
-+
-+bool AlpineApkUpdater::isProgressing() const
-+{
-+ qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+ return false;
-+}
-+
-+bool AlpineApkUpdater::isMarked(AbstractResource *res) const
-+{
-+ // qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+ return m_markedToUpdate.contains(res);
-+ // return true;
-+}
-+
-+void AlpineApkUpdater::fetchChangelog() const
-+{
-+ qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+}
-+
-+double AlpineApkUpdater::updateSize() const
-+{
-+ // qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+ double sum = 0.0;
-+ for (AbstractResource *res : m_markedToUpdate) {
-+ sum += res->size();
-+ }
-+ return sum;
-+}
-+
-+quint64 AlpineApkUpdater::downloadSpeed() const
-+{
-+ qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+ return 0;
-+}
-+
-+void AlpineApkUpdater::cancel()
-+{
-+ qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+}
-+
-+void AlpineApkUpdater::start()
-+{
-+ qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+ return;
-+#if 0
-+ KAuth::Action upgradeAction(QStringLiteral("org.kde.discover.alpineapkbackend.upgrade"));
-+ upgradeAction.setHelperId(QStringLiteral("org.kde.discover.alpineapkbackend"));
-+ if (!upgradeAction.isValid()) {
-+ qCWarning(LOG_ALPINEAPK) << "kauth upgradeAction is not valid!";
-+ return;
-+ }
-+ upgradeAction.setTimeout(60 * 1000); // 1 minute
-+ upgradeAction.setDetails(i18n("Get the list of packages to upgrade"));
-+ upgradeAction.addArgument(QLatin1String("onlySimulate"), true);
-+
-+ // run upgrade check with elevated privileges
-+ KAuth::ExecuteJob *reply = upgradeAction.execute();
-+ QObject::connect(reply, &KAuth::ExecuteJob::result,
-+ this, &AlpineApkUpdater::handleKAuthUpgradeHelperReply);
-+
-+ reply->start();
-+#endif
-+}
-+
-+void AlpineApkUpdater::proceed()
-+{
-+ qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-+}
-+
-+int AlpineApkUpdater::updatesCount()
-+{
-+ // qDebug(LOG_ALPINEAPK) << Q_FUNC_INFO << m_updatesCount;
-+ return m_updatesCount;
-+}
-+
-+void AlpineApkUpdater::startCheckForUpdates()
-+{
-+ KAuth::Action updateAction(QStringLiteral("org.kde.discover.alpineapkbackend.update"));
-+ updateAction.setHelperId(QStringLiteral("org.kde.discover.alpineapkbackend"));
-+ if (!updateAction.isValid()) {
-+ qCWarning(LOG_ALPINEAPK) << "kauth updateAction is not valid!";
-+ return;
-+ }
-+ updateAction.setTimeout(60 * 1000); // 1 minute
-+ updateAction.setDetails(i18n("Update repositories index"));
-+
-+ // run updates check with elevated privileges to access
-+ // system package manager files
-+ KAuth::ExecuteJob *reply = updateAction.execute();
-+ QObject::connect(reply, &KAuth::ExecuteJob::result,
-+ this, &AlpineApkUpdater::handleKAuthUpdateHelperReply);
-+ //QObject::connect(reply, &KAuth::ExecuteJob::newData,
-+ // this, &AlpineApkUpdater::handleKAuthUpdateHelperProgressStep);
-+ QObject::connect(reply, QOverload<KJob *, unsigned long>::of(&KAuth::ExecuteJob::percent),
-+ this, &AlpineApkUpdater::handleKAuthUpdateHelperProgress);
-+
-+ reply->start();
-+}
-+
-+void AlpineApkUpdater::handleKAuthUpdateHelperReply(KJob *job)
-+{
-+ KAuth::ExecuteJob *reply = static_cast<KAuth::ExecuteJob *>(job);
-+ const QVariantMap &replyData = reply->data();
-+ if (reply->error() == 0) {
-+ m_updatesCount = replyData.value(QLatin1String("updatesCount")).toInt();
-+ qCDebug(LOG_ALPINEAPK) << "KAuth helper update reply received, updatesCount:" << m_updatesCount;
-+ Q_EMIT updatesCountChanged(m_updatesCount);
-+ } else {
-+ const QString message = replyData.value(QLatin1String("errorString"),
-+ reply->errorString()).toString();
-+ qCDebug(LOG_ALPINEAPK) << "KAuth helper returned error:" << message << reply->error();
-+ if (reply->error() == KAuth::ActionReply::Error::AuthorizationDeniedError) {
-+ Q_EMIT passiveMessage(i18n("Authorization denied"));
-+ } else {
-+ Q_EMIT passiveMessage(i18n("Error") + QStringLiteral(":\n") + message);
-+ }
-+ }
-+
-+ // we are not in the state "Fetching updates" now, update UI
-+ Q_EMIT checkForUpdatesFinished();
-+}
-+
-+void AlpineApkUpdater::handleKAuthUpdateHelperProgress(KJob *job, unsigned long percent)
-+{
-+ Q_UNUSED(job)
-+ qCDebug(LOG_ALPINEAPK) << " fetch updates progress: " << percent;
-+ Q_EMIT fetchingUpdatesProgressChanged(percent);
-+}
-+
-+void AlpineApkUpdater::handleKAuthUpgradeHelperReply(KJob *job)
-+{
-+ KAuth::ExecuteJob *reply = static_cast<KAuth::ExecuteJob *>(job);
-+ const QVariantMap &replyData = reply->data();
-+ if (reply->error() == 0) {
-+ QVariant pkgsV = replyData.value(QLatin1String("changes"));
-+ bool onlySimulate = replyData.value(QLatin1String("onlySimulate"), false).toBool();
-+ qCDebug(LOG_ALPINEAPK) << "KAuth helper upgrade reply received:" << onlySimulate;
-+ if (onlySimulate) {
-+ QVector<QtApk::Package> pkgVector = pkgsV.value<QVector<QtApk::Package>>();
-+ qCDebug(LOG_ALPINEAPK) << " num changes:" << pkgVector.size();
-+ for (const QtApk::Package &pkg : pkgVector) {
-+ qCDebug(LOG_ALPINEAPK) << " " << pkg.name << pkg.version;
-+ }
-+ }
-+ } else {
-+ const QString message = replyData.value(QLatin1String("errorString"),
-+ reply->errorString()).toString();
-+ qCDebug(LOG_ALPINEAPK) << "KAuth helper returned error:" << message << reply->error();
-+ if (reply->error() == KAuth::ActionReply::Error::AuthorizationDeniedError) {
-+ Q_EMIT passiveMessage(i18n("Authorization denied"));
-+ } else {
-+ Q_EMIT passiveMessage(i18n("Error") + QStringLiteral(":\n") + message);
-+ }
-+ }
-+
-+ // we are not in the state "Fetching updates" now, update UI
-+ Q_EMIT checkForUpdatesFinished();
-+}
-+
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h
-new file mode 100644
-index 00000000..504e8c59
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h
-@@ -0,0 +1,190 @@
-+/***************************************************************************
-+ * Copyright © 2020 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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/>. *
-+ ***************************************************************************/
-+
-+#ifndef ALPINEAPKUPDATER_H
-+#define ALPINEAPKUPDATER_H
-+
-+#include "resources/AbstractBackendUpdater.h"
-+#include "resources/AbstractResourcesBackend.h"
-+
-+#include <QSet>
-+#include <QDateTime>
-+#include <QTimer>
-+#include <QVariant>
-+#include <QMap>
-+#include <QVector>
-+
-+#include <QtApkChangeset.h>
-+
-+class AbstractResourcesBackend;
-+class AlpineApkBackend;
-+class KJob;
-+
-+class AlpineApkUpdater : public AbstractBackendUpdater
-+{
-+ Q_OBJECT
-+ Q_PROPERTY(int updatesCount READ updatesCount NOTIFY updatesCountChanged)
-+
-+public:
-+ explicit AlpineApkUpdater(AbstractResourcesBackend *parent = nullptr);
-+
-+ /**
-+ * This method is called, when Muon switches to the updates view.
-+ * Here the backend should mark all upgradeable packages as to be upgraded.
-+ */
-+ void prepare() override;
-+
-+ /**
-+ * @returns true if the backend contains packages which can be updated
-+ */
-+ bool hasUpdates() const override;
-+ /**
-+ * @returns the progress of the update in percent
-+ */
-+ qreal progress() const override;
-+
-+ /**
-+ * This method is used to remove resources from the list of packages
-+ * marked to be upgraded. It will potentially be called before \start.
-+ */
-+ void removeResources(const QList<AbstractResource*> &apps) override;
-+
-+ /**
-+ * This method is used to add resource to the list of packages marked to be upgraded.
-+ * It will potentially be called before \start.
-+ */
-+ void addResources(const QList<AbstractResource*> &apps) override;
-+
-+ /**
-+ * @returns the list of updateable resources in the system
-+ */
-+ QList<AbstractResource *> toUpdate() const override;
-+
-+ /**
-+ * @returns the QDateTime when the last update happened
-+ */
-+ QDateTime lastUpdate() const override;
-+
-+ /**
-+ * @returns whether the updater can currently be canceled or not
-+ * @see cancelableChanged
-+ */
-+ bool isCancelable() const override;
-+
-+ /**
-+ * @returns whether the updater is currently running or not
-+ * this property decides, if there will be progress reporting in the GUI.
-+ * This has to stay true during the whole transaction!
-+ * @see progressingChanged
-+ */
-+ bool isProgressing() const override;
-+
-+ /**
-+ * @returns whether @p res is marked for update
-+ */
-+ bool isMarked(AbstractResource* res) const override;
-+
-+ void fetchChangelog() const override;
-+
-+ /**
-+ * @returns the size of all the packages set to update combined
-+ */
-+ double updateSize() const override;
-+
-+ /**
-+ * @returns the speed at which we are downloading
-+ */
-+ quint64 downloadSpeed() const override;
-+
-+public Q_SLOTS:
-+ /**
-+ * If \isCancelable is true during the transaction, this method has
-+ * to be implemented and will potentially be called when the user
-+ * wants to cancel the update.
-+ */
-+ void cancel() override;
-+
-+ /**
-+ * This method starts the update. All packages which are in \toUpdate
-+ * are going to be updated.
-+ *
-+ * From this moment on the AbstractBackendUpdater should continuously update
-+ * the other methods to show its progress.
-+ *
-+ * @see progress
-+ * @see progressChanged
-+ * @see isProgressing
-+ * @see progressingChanged
-+ */
-+ void start() override;
-+
-+ /**
-+ * Answers a proceed request
-+ */
-+ void proceed() override;
-+
-+Q_SIGNALS:
-+ void checkForUpdatesFinished();
-+ void updatesCountChanged(int updatesCount);
-+ void fetchingUpdatesProgressChanged(int progress);
-+ //void cancelTransaction();
-+
-+public Q_SLOTS:
-+ int updatesCount();
-+ void startCheckForUpdates();
-+
-+ // KAuth handler slots
-+ // update
-+ void handleKAuthUpdateHelperReply(KJob *job);
-+ void handleKAuthUpdateHelperProgress(KJob *job, unsigned long percent);
-+ // upgrade
-+ void handleKAuthUpgradeHelperReply(KJob *job);
-+
-+ //void transactionRemoved(Transaction* t);
-+ //void cleanup();
-+
-+public:
-+ QVector<QtApk::ChangesetItem> &changes() { return m_upgradeable.changes(); }
-+ const QVector<QtApk::ChangesetItem> &changes() const { return m_upgradeable.changes(); }
-+
-+private:
-+ AlpineApkBackend *const m_backend;
-+ int m_updatesCount = 0;
-+ QtApk::Changeset m_upgradeable;
-+ QSet<AbstractResource *> m_allUpdateable;
-+ QSet<AbstractResource *> m_markedToUpdate;
-+// void resourcesChanged(AbstractResource* res, const QVector<QByteArray>& props);
-+// void refreshUpdateable();
-+// void transactionAdded(Transaction* newTransaction);
-+// void transactionProgressChanged();
-+// void refreshProgress();
-+// QVector<Transaction*> transactions() const;
-+
-+// QSet<AbstractResource*> m_upgradeable;
-+// QSet<AbstractResource*> m_pendingResources;
-+// bool m_settingUp;
-+// qreal m_progress;
-+// QDateTime m_lastUpdate;
-+// QTimer m_timer;
-+// bool m_canCancel = false;
-+};
-+
-+
-+#endif // ALPINEAPKUPDATER_H
-diff --git a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-index ede3157f..38184945 100644
---- a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-+++ b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-@@ -9,6 +9,8 @@ set(alpineapkbackend_SRCS
- AlpineApkReviewsBackend.h
- AlpineApkSourcesBackend.cpp
- AlpineApkSourcesBackend.h
-+ AlpineApkUpdater.cpp
-+ AlpineApkUpdater.h
- AlpineApkTransaction.cpp
- AlpineApkTransaction.h
- )
---
-GitLab
-
-
-From c336f16343186998926232d82df580af688f5220 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Mon, 3 Feb 2020 03:52:41 +0300
-Subject: [PATCH 22/62] AlpineApkBackend: use our new updater
-
----
- .../AlpineApkBackend/AlpineApkBackend.cpp | 158 ++++++++----------
- .../AlpineApkBackend/AlpineApkBackend.h | 21 ++-
- 2 files changed, 85 insertions(+), 94 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index ed016aef..75738018 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -23,19 +23,14 @@
- #include "AlpineApkReviewsBackend.h"
- #include "AlpineApkTransaction.h"
- #include "AlpineApkSourcesBackend.h"
-+#include "AlpineApkUpdater.h"
- #include "alpineapk_backend_logging.h" // generated by ECM
-
--#include "resources/StandardBackendUpdater.h"
- #include "resources/SourcesModel.h"
- #include "Transaction/Transaction.h"
- #include "Category/Category.h"
-
--#include <KAboutData>
- #include <KLocalizedString>
--#include <KPluginFactory>
--#include <KConfigGroup>
--#include <KSharedConfig>
--#include <KAuthExecuteJob>
-
- #include <QDebug>
- #include <QLoggingCategory>
-@@ -47,45 +42,33 @@ DISCOVER_BACKEND_PLUGIN(AlpineApkBackend)
-
- AlpineApkBackend::AlpineApkBackend(QObject *parent)
- : AbstractResourcesBackend(parent)
-- , m_updater(new StandardBackendUpdater(this))
-+ , m_updater(new AlpineApkUpdater(this))
- , m_reviews(new AlpineApkReviewsBackend(this))
-- , m_startElements(120)
-+ , m_updatesTimeoutTimer(new QTimer(this))
- {
- #ifndef QT_DEBUG
- const_cast<QLoggingCategory &>(LOG_ALPINEAPK()).setEnabled(QtDebugMsg, false);
- #endif
-
-- qCDebug(LOG_ALPINEAPK) << "constructing backend!";
-+ // schedule checking for updates
-+ QTimer::singleShot(1000, this, &AlpineApkBackend::checkForUpdates);
-
-- QTimer::singleShot(1000, this, &AlpineApkBackend::startCheckForUpdates);
--
-- QObject::connect(m_updater, &StandardBackendUpdater::updatesCountChanged,
-+ // connections with our updater
-+ QObject::connect(m_updater, &AlpineApkUpdater::updatesCountChanged,
- this, &AlpineApkBackend::updatesCountChanged);
-+ QObject::connect(m_updater, &AlpineApkUpdater::checkForUpdatesFinished,
-+ this, &AlpineApkBackend::finishCheckForUpdates);
-+ QObject::connect(m_updater, &AlpineApkUpdater::fetchingUpdatesProgressChanged,
-+ this, &AlpineApkBackend::setFetchingUpdatesProgress);
-
-- populate();
--
-- SourcesModel::global()->addSourcesBackend(new AlpineApkSourcesBackend(this));
--}
--
--QVector<Category *> AlpineApkBackend::category() const
--{
-- // single root category
-- // we could add more, but Alpine apk does not have this concept
-- static Category *cat = new Category(
-- QStringLiteral("All packages"), // displayName
-- QStringLiteral("package-x-generic"), // icon
-- {}, // orFilters
-- { displayName() }, // pluginName
-- {}, // subCategories
-- QUrl(), // decoration (what is it?)
-- false // isAddons
-- );
-- return { cat };
--}
-+ // safety measure: make sure update check process can finish in some finite time
-+ QObject::connect(m_updatesTimeoutTimer, &QTimer::timeout,
-+ this, &AlpineApkBackend::finishCheckForUpdates);
-+ m_updatesTimeoutTimer->setTimerType(Qt::CoarseTimer);
-+ m_updatesTimeoutTimer->setSingleShot(true);
-+ m_updatesTimeoutTimer->setInterval(2 * 60 * 1000); // 2minutes
-
--void AlpineApkBackend::populate()
--{
-- qCDebug(LOG_ALPINEAPK) << "populating resources...";
-+ qCDebug(LOG_ALPINEAPK) << "backend: populating resources...";
-
- if (m_apkdb.open(QtApk::Database::QTAPK_OPENF_READONLY)) {
- m_availablePackages = m_apkdb.getAvailablePackages();
-@@ -103,7 +86,7 @@ void AlpineApkBackend::populate()
- m_resources.insert(key, res);
- connect(res, &AlpineApkResource::stateChanged, this, &AlpineApkBackend::updatesCountChanged);
- }
-- qCDebug(LOG_ALPINEAPK) << " available" << m_availablePackages.size()
-+ qCDebug(LOG_ALPINEAPK) << " available" << m_availablePackages.size()
- << "packages";
- }
- if (m_installedPackages.size() > 0) {
-@@ -113,62 +96,31 @@ void AlpineApkBackend::populate()
- m_resources.value(key)->setState(AbstractResource::Installed);
- }
- }
-- qCDebug(LOG_ALPINEAPK) << " installed" << m_installedPackages.size()
-+ qCDebug(LOG_ALPINEAPK) << " installed" << m_installedPackages.size()
- << "packages";
- }
--}
--
--void AlpineApkBackend::handleKauthHelperReply(KJob *job)
--{
-- qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-- KAuth::ExecuteJob* reply = static_cast<KAuth::ExecuteJob *>(job);
-- const QVariantMap replyData = reply->data();
-- if (reply->error() == 0) {
-- qCDebug(LOG_ALPINEAPK) << replyData[QLatin1String("reply")].toString();
-- } else {
-- const QString message = replyData.value(QLatin1String("errorString"), reply->errorString()).toString();
-- qCDebug(LOG_ALPINEAPK) << message;
-- }
--}
--
--void AlpineApkBackend::startCheckForUpdates()
--{
-- if (m_fetching) {
-- return;
-- }
-- qCDebug(LOG_ALPINEAPK) << "startCheckForUpdates()";
--
-- // temporary hack - finish updates check in 5 seconds
-- QTimer::singleShot(5000, this, &AlpineApkBackend::finishCheckForUpdates);
--
-- m_fetching = true;
-- emit fetchingChanged();
--
-- KAuth::Action testAction(QStringLiteral("org.kde.discover.alpineapkbackend.test"));
-- testAction.setHelperId(QStringLiteral("org.kde.discover.alpineapkbackend"));
-- testAction.setArguments({
-- { QStringLiteral("txt"), QLatin1String("Wooo!") },
-- });
-- if (!testAction.isValid()) {
-- qCWarning(LOG_ALPINEAPK) << "kauth action is not valid!";
-- return;
-- }
-
-- KAuth::ExecuteJob *reply = testAction.execute();
-- QObject::connect(reply, &KAuth::ExecuteJob::result,
-- this, &AlpineApkBackend::handleKauthHelperReply);
-- reply->start();
-+ SourcesModel::global()->addSourcesBackend(new AlpineApkSourcesBackend(this));
- }
-
--void AlpineApkBackend::finishCheckForUpdates()
-+QVector<Category *> AlpineApkBackend::category() const
- {
-- m_fetching = false;
-- emit fetchingChanged();
-+ // single root category
-+ // we could add more, but Alpine apk does not have this concept
-+ static Category *cat = new Category(
-+ i18nc("Root category name", "Alpine packages"),
-+ QStringLiteral("package-x-generic"), // icon
-+ {}, // orFilters
-+ { displayName() }, // pluginName
-+ {}, // subCategories
-+ QUrl(), // decoration (what is it?)
-+ false // isAddons
-+ );
-+ return { cat };
- }
-
- int AlpineApkBackend::updatesCount() const
- {
-- qCDebug(LOG_ALPINEAPK) << "updatesCount(): " << m_updater->updatesCount();
- return m_updater->updatesCount();
- }
-
-@@ -210,7 +162,7 @@ ResultsStream *AlpineApkBackend::findResourceByPackageName(const QUrl &searchUrl
- AlpineApkResource *result = nullptr;
-
- // QUrl("appstream://org.kde.krita.desktop")
-- // smart workaround for appstream
-+ // smart workaround for appstream URLs
- if (searchUrl.scheme() == QLatin1String("appstream")) {
- // remove leading "org.kde."
- QString pkgName = searchUrl.host();
-@@ -256,18 +208,46 @@ Transaction* AlpineApkBackend::removeApplication(AbstractResource *app)
- return new AlpineApkTransaction(qobject_cast<AlpineApkResource *>(app), Transaction::RemoveRole);
- }
-
-+int AlpineApkBackend::fetchingUpdatesProgress() const
-+{
-+ if (!m_fetching) return 100;
-+ return m_fetchProgress;
-+}
-+
- void AlpineApkBackend::checkForUpdates()
- {
- if (m_fetching) {
-- qCDebug(LOG_ALPINEAPK) << "checkForUpdates(): already fetching";
-+ qCDebug(LOG_ALPINEAPK) << "backend: checkForUpdates(): already fetching";
- return;
- }
-- startCheckForUpdates();
-+
-+ qCDebug(LOG_ALPINEAPK) << "backend: start checkForUpdates()";
-+
-+ // safety measure - finish updates check in some time
-+ m_updatesTimeoutTimer->start();
-+
-+ // let our updater do the job
-+ m_updater->startCheckForUpdates();
-+
-+ // update UI
-+ m_fetching = true;
-+ m_fetchProgress = 0;
-+ emit fetchingChanged();
-+ emit fetchingUpdatesProgressChanged();
-+}
-+
-+void AlpineApkBackend::finishCheckForUpdates()
-+{
-+ m_updatesTimeoutTimer->stop(); // stop safety timer
-+ // update UI
-+ m_fetching = false;
-+ emit fetchingChanged();
-+ emit fetchingUpdatesProgressChanged();
- }
-
- QString AlpineApkBackend::displayName() const
- {
-- return QStringLiteral("Alpine APK backend");
-+ return i18nc("Backend plugin display name", "Alpine APK backend");
- }
-
- bool AlpineApkBackend::hasApplications() const
-@@ -275,4 +255,10 @@ bool AlpineApkBackend::hasApplications() const
- return true;
- }
-
-+void AlpineApkBackend::setFetchingUpdatesProgress(int percent)
-+{
-+ m_fetchProgress = percent;
-+ emit fetchingUpdatesProgressChanged();
-+}
-+
- #include "AlpineApkBackend.moc"
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-index a533cee3..d6935257 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-@@ -27,14 +27,14 @@
- #include <QtApk.h>
-
- class AlpineApkReviewsBackend;
--class StandardBackendUpdater;
-+class AlpineApkUpdater;
- class AlpineApkResource;
- class KJob;
-+class QTimer;
-
- class AlpineApkBackend : public AbstractResourcesBackend
- {
- Q_OBJECT
-- Q_PROPERTY(int startElements MEMBER m_startElements)
-
- public:
- explicit AlpineApkBackend(QObject *parent = nullptr);
-@@ -46,32 +46,37 @@ public:
- ResultsStream *search(const AbstractResourcesBackend::Filters &filter) override;
- ResultsStream *findResourceByPackageName(const QUrl &search);
- QHash<QString, AlpineApkResource *> resources() const { return m_resources; }
-+ QHash<QString, AlpineApkResource *> *resourcesPtr() { return &m_resources; }
- bool isValid() const override { return true; } // No external file dependencies that could cause runtime errors
-
- Transaction *installApplication(AbstractResource *app) override;
- Transaction *installApplication(AbstractResource *app, const AddonList &addons) override;
- Transaction *removeApplication(AbstractResource *app) override;
- bool isFetching() const override { return m_fetching; }
-+ int fetchingUpdatesProgress() const override;
- void checkForUpdates() override;
- QString displayName() const override;
- bool hasApplications() const override;
-
- public Q_SLOTS:
-- void handleKauthHelperReply(KJob *job);
-- void startCheckForUpdates();
-+ void setFetchingUpdatesProgress(int percent);
-+
-+private Q_SLOTS:
- void finishCheckForUpdates();
-
--private:
-- void populate();
-+public:
-+ QtApk::Database *apkdb() { return &m_apkdb; }
-
-+private:
- QHash<QString, AlpineApkResource *> m_resources;
-- StandardBackendUpdater *m_updater;
-+ AlpineApkUpdater *m_updater;
- AlpineApkReviewsBackend *m_reviews;
- QtApk::Database m_apkdb;
- QVector<QtApk::Package> m_availablePackages;
- QVector<QtApk::Package> m_installedPackages;
- bool m_fetching = false;
-- int m_startElements = 0;
-+ int m_fetchProgress = 0;
-+ QTimer *m_updatesTimeoutTimer;
- };
-
- #endif // AlpineApkBackend_H
---
-GitLab
-
-
-From f5038a2fba366be10ffb562a5ba2b7ea4024c289 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Mon, 3 Feb 2020 18:21:04 +0300
-Subject: [PATCH 23/62] AlpineApk{Updater,AuthHelper}: pass fakeRoot to helper
-
-Env vars are not inherited by elevated helper
----
- .../backends/AlpineApkBackend/AlpineApkAuthHelper.cpp | 11 ++++++++++-
- .../backends/AlpineApkBackend/AlpineApkUpdater.cpp | 5 ++++-
- 2 files changed, 14 insertions(+), 2 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-index 4ff5c880..aa3dbdae 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-@@ -64,9 +64,13 @@ ActionReply AlpineApkAuthHelper::test(const QVariantMap &args)
-
- ActionReply AlpineApkAuthHelper::update(const QVariantMap &args)
- {
-- Q_UNUSED(args)
- ActionReply reply = ActionReply::HelperErrorReply();
-
-+ const QString fakeRoot = args.value(QLatin1String("fakeRoot"), QString()).toString();
-+ if (!fakeRoot.isEmpty()) {
-+ m_apkdb.setFakeRoot(fakeRoot);
-+ }
-+
- HelperSupport::progressStep(10);
-
- if (!m_apkdb.open(QtApk::Database::QTAPK_OPENF_READWRITE)) {
-@@ -125,6 +129,11 @@ ActionReply AlpineApkAuthHelper::upgrade(const QVariantMap &args)
- qCDebug(LOG_AUTHHELPER) << "Simulating upgrade run.";
- }
-
-+ const QString fakeRoot = args.value(QLatin1String("fakeRoot"), QString()).toString();
-+ if (!fakeRoot.isEmpty()) {
-+ m_apkdb.setFakeRoot(fakeRoot);
-+ }
-+
- QtApk::Changeset changes;
- bool upgrade_ok = m_apkdb.upgrade(flags, &changes);
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-index 1dd6cdac..d0c0482e 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-@@ -47,6 +47,7 @@ void AlpineApkUpdater::prepare()
- return;
- }
-
-+ // readonly is fine for a simulation of upgrade
- if (!db->open(QtApk::Database::QTAPK_OPENF_READONLY)) {
- emit passiveMessage(i18n("Failed to open APK database!"));
- return;
-@@ -57,7 +58,7 @@ void AlpineApkUpdater::prepare()
- db->close();
- return;
- }
-- // clsoe DB ASAP
-+ // close DB ASAP
- db->close();
-
- m_updatesCount = m_upgradeable.changes().size();
-@@ -202,6 +203,7 @@ int AlpineApkUpdater::updatesCount()
-
- void AlpineApkUpdater::startCheckForUpdates()
- {
-+ QtApk::Database *db = m_backend->apkdb();
- KAuth::Action updateAction(QStringLiteral("org.kde.discover.alpineapkbackend.update"));
- updateAction.setHelperId(QStringLiteral("org.kde.discover.alpineapkbackend"));
- if (!updateAction.isValid()) {
-@@ -210,6 +212,7 @@ void AlpineApkUpdater::startCheckForUpdates()
- }
- updateAction.setTimeout(60 * 1000); // 1 minute
- updateAction.setDetails(i18n("Update repositories index"));
-+ updateAction.addArgument(QLatin1String("fakeRoot"), db->fakeRoot());
-
- // run updates check with elevated privileges to access
- // system package manager files
---
-GitLab
-
-
-From 42d0a0e0b609e5ed4944f5221111eaf1d413c67c Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Mon, 3 Feb 2020 20:14:13 +0300
-Subject: [PATCH 24/62] Auth helper: WIP on using progress_fd
-
----
- .../AlpineApkBackend/AlpineApkAuthHelper.cpp | 13 ++++++++++---
- 1 file changed, 10 insertions(+), 3 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-index aa3dbdae..4c3bf545 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-@@ -21,9 +21,8 @@
- #include <QProcess>
- #include <QDebug>
- #include <QLoggingCategory>
--#include <QJsonDocument>
--#include <QJsonObject>
--#include <QJsonArray>
-+#include <QSocketNotifier>
-+#include <QScopedPointer>
- #include <QFile>
-
- #include <KAuthHelperSupport>
-@@ -134,6 +133,14 @@ ActionReply AlpineApkAuthHelper::upgrade(const QVariantMap &args)
- m_apkdb.setFakeRoot(fakeRoot);
- }
-
-+ int progress_fd = m_apkdb.progressFd();
-+ qCDebug(LOG_AUTHHELPER) << " progress_fd: " << progress_fd;
-+
-+ QScopedPointer<QSocketNotifier> notifier(new QSocketNotifier(progress_fd, QSocketNotifier::Read));
-+ QObject::connect(notifier.data(), &QSocketNotifier::activated, notifier.data(), [](int sock) {
-+ qCDebug(LOG_AUTHHELPER) << " read trigger from progress_fd!";
-+ });
-+
- QtApk::Changeset changes;
- bool upgrade_ok = m_apkdb.upgrade(flags, &changes);
-
---
-GitLab
-
-
-From f6e5d590bc8570db785a4a5a2cfded6abf6012d8 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Fri, 20 Mar 2020 17:53:01 +0300
-Subject: [PATCH 25/62] auth helper: fix usused vars
-
----
- libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-index 4c3bf545..bc9c1ec6 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-@@ -100,12 +100,14 @@ ActionReply AlpineApkAuthHelper::update(const QVariantMap &args)
-
- ActionReply AlpineApkAuthHelper::add(const QVariantMap &args)
- {
-+ Q_UNUSED(args)
- ActionReply reply = ActionReply::HelperErrorReply();
- return reply;
- }
-
- ActionReply AlpineApkAuthHelper::del(const QVariantMap &args)
- {
-+ Q_UNUSED(args)
- ActionReply reply = ActionReply::HelperErrorReply();
- return reply;
- }
-@@ -138,6 +140,7 @@ ActionReply AlpineApkAuthHelper::upgrade(const QVariantMap &args)
-
- QScopedPointer<QSocketNotifier> notifier(new QSocketNotifier(progress_fd, QSocketNotifier::Read));
- QObject::connect(notifier.data(), &QSocketNotifier::activated, notifier.data(), [](int sock) {
-+ Q_UNUSED(sock)
- qCDebug(LOG_AUTHHELPER) << " read trigger from progress_fd!";
- });
-
---
-GitLab
-
-
-From 762b7be428274d6a020a4f7b800eaaecab23fca1 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Wed, 8 Apr 2020 05:55:33 +0300
-Subject: [PATCH 26/62] AlpineApkBackend: cmake: use namespaced ApkQt
-
----
- libdiscover/backends/AlpineApkBackend/CMakeLists.txt | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-index 38184945..42e09c5b 100644
---- a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-+++ b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-@@ -38,7 +38,7 @@ target_link_libraries(
- KF5::ConfigCore
- KF5::AuthCore
- Discover::Common
-- apk-qt
-+ ApkQt::apk-qt
- )
-
- # KAuth helper exe
-@@ -54,7 +54,7 @@ set_source_files_properties(
- target_link_libraries(alpineapk_kauth_helper
- Qt5::Core
- KF5::AuthCore
-- apk-qt
-+ ApkQt::apk-qt
- )
-
- kauth_install_actions(org.kde.discover.alpineapkbackend org.kde.discover.alpineapkbackend.actions)
---
-GitLab
-
-
-From 9a963dff6d51cd5764c419d62732f706893b082c Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Thu, 9 Apr 2020 21:18:33 +0300
-Subject: [PATCH 27/62] AlpineApkBackend: mark pkgs as Technical type and fix
- searhes
-
-This makes updates appear as "System updates" in updates view
-and also makes them correctly categorized in top level
-categories when other backend is installed (Flatpak, KNewStuff)
----
- .../AlpineApkBackend/AlpineApkBackend.cpp | 62 ++++++++++++-------
- .../AlpineApkBackend/AlpineApkResource.cpp | 2 +-
- 2 files changed, 42 insertions(+), 22 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index 75738018..750d2820 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -79,9 +79,12 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
- if (m_availablePackages.size() > 0) {
- for (const QtApk::Package &pkg: m_availablePackages) {
- AlpineApkResource *res = new AlpineApkResource(pkg, this);
-- res->setCategoryName(QStringLiteral("all"));
-+ res->setCategoryName(QStringLiteral("alpine_packages"));
- res->setOriginSource(QStringLiteral("apk"));
- res->setSection(QStringLiteral("dummy"));
-+ // here is the place to set a proper type of package
-+ // AlpineApkResource defaults to AbstractResource::Technical,
-+ // which places it into "System updates" section
- const QString key = pkg.name.toLower();
- m_resources.insert(key, res);
- connect(res, &AlpineApkResource::stateChanged, this, &AlpineApkBackend::updatesCountChanged);
-@@ -105,18 +108,22 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
-
- QVector<Category *> AlpineApkBackend::category() const
- {
-- // single root category
-+ static QPair<FilterType, QString> s_apkFlt(
-+ FilterType::CategoryFilter, QLatin1String("alpine_packages"));
-+
-+ // Display a single root category
- // we could add more, but Alpine apk does not have this concept
-- static Category *cat = new Category(
-- i18nc("Root category name", "Alpine packages"),
-- QStringLiteral("package-x-generic"), // icon
-- {}, // orFilters
-- { displayName() }, // pluginName
-- {}, // subCategories
-- QUrl(), // decoration (what is it?)
-- false // isAddons
-+ static Category *s_rootCat = new Category(
-+ i18nc("Root category name", "Alpine packages"),
-+ QStringLiteral("package-x-generic"), // icon
-+ { s_apkFlt }, // orFilters - include packages that match filter
-+ { displayName() }, // pluginName
-+ {}, // subCategories - none
-+ QUrl(), // decoration (what is it?)
-+ false // isAddons
- );
-- return { cat };
-+
-+ return { s_rootCat };
- }
-
- int AlpineApkBackend::updatesCount() const
-@@ -130,17 +137,23 @@ ResultsStream *AlpineApkBackend::search(const AbstractResourcesBackend::Filters
- if (!filter.resourceUrl.isEmpty()) {
- return findResourceByPackageName(filter.resourceUrl);
- } else {
-- for (AbstractResource *r: qAsConst(m_resources)) {
-- if (r->type() == AbstractResource::Technical
-- && filter.state != AbstractResource::Upgradeable) {
-- continue;
-- }
-- if (r->state() < filter.state) {
-+ for (AbstractResource *resource: qAsConst(m_resources)) {
-+ // skip technical package types (not apps/addons)
-+ // that are not upgradeable
-+ // (does not work because for now all Alpine packages are "technical"
-+ // if (resource->type() == AbstractResource::Technical
-+ // && filter.state != AbstractResource::Upgradeable) {
-+ // continue;
-+ // }
-+
-+ // skip not-requested states
-+ if (resource->state() < filter.state) {
- continue;
- }
-- if(r->name().contains(filter.search, Qt::CaseInsensitive)
-- || r->comment().contains(filter.search, Qt::CaseInsensitive)) {
-- ret += r;
-+
-+ if(resource->name().contains(filter.search, Qt::CaseInsensitive)
-+ || resource->comment().contains(filter.search, Qt::CaseInsensitive)) {
-+ ret += resource;
- }
- }
- }
-@@ -162,7 +175,7 @@ ResultsStream *AlpineApkBackend::findResourceByPackageName(const QUrl &searchUrl
- AlpineApkResource *result = nullptr;
-
- // QUrl("appstream://org.kde.krita.desktop")
-- // smart workaround for appstream URLs
-+ // smart workaround for appstream URLs - handle "featured" apps
- if (searchUrl.scheme() == QLatin1String("appstream")) {
- // remove leading "org.kde."
- QString pkgName = searchUrl.host();
-@@ -177,6 +190,13 @@ ResultsStream *AlpineApkBackend::findResourceByPackageName(const QUrl &searchUrl
- result = m_resources.value(pkgName);
- }
-
-+ // QUrl("apk://krita")
-+ // handle packages from Alpine repos
-+ if (searchUrl.scheme() == QLatin1String("apk")) {
-+ const QString pkgName = searchUrl.host();
-+ result = m_resources.value(pkgName);
-+ }
-+
- if (!result) {
- return new ResultsStream(QStringLiteral("AlpineApkStream"), {});
- }
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-index af480b6c..346a28b2 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-@@ -26,7 +26,7 @@ AlpineApkResource::AlpineApkResource(const QtApk::Package &apkPkg,
- AbstractResourcesBackend *parent)
- : AbstractResource(parent)
- , m_state(AbstractResource::State::None)
-- , m_type(Application)
-+ , m_type(AbstractResource::Type::Technical)
- , m_pkg(apkPkg)
- {
- }
---
-GitLab
-
-
-From be1cba7cf2204dfe632a8b976c01eb809dfc2ce0 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Fri, 10 Apr 2020 09:00:29 +0300
-Subject: [PATCH 28/62] KAuth helper: disable progress_fd for now
-
----
- .../AlpineApkBackend/AlpineApkAuthHelper.cpp | 16 +++++++++-------
- 1 file changed, 9 insertions(+), 7 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-index bc9c1ec6..11e26786 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-@@ -26,6 +26,7 @@
- #include <QFile>
-
- #include <KAuthHelperSupport>
-+#include <kauth_version.h>
-
- #include "AlpineApkAuthHelper.h"
-
-@@ -135,14 +136,15 @@ ActionReply AlpineApkAuthHelper::upgrade(const QVariantMap &args)
- m_apkdb.setFakeRoot(fakeRoot);
- }
-
-- int progress_fd = m_apkdb.progressFd();
-- qCDebug(LOG_AUTHHELPER) << " progress_fd: " << progress_fd;
-+ // no progress notifications for now
-+ //int progress_fd = m_apkdb.progressFd();
-+ //qCDebug(LOG_AUTHHELPER) << " progress_fd: " << progress_fd;
-
-- QScopedPointer<QSocketNotifier> notifier(new QSocketNotifier(progress_fd, QSocketNotifier::Read));
-- QObject::connect(notifier.data(), &QSocketNotifier::activated, notifier.data(), [](int sock) {
-- Q_UNUSED(sock)
-- qCDebug(LOG_AUTHHELPER) << " read trigger from progress_fd!";
-- });
-+ //QScopedPointer<QSocketNotifier> notifier(new QSocketNotifier(progress_fd, QSocketNotifier::Read));
-+ //QObject::connect(notifier.data(), &QSocketNotifier::activated, notifier.data(), [](int sock) {
-+ // Q_UNUSED(sock)
-+ // qCDebug(LOG_AUTHHELPER) << " read trigger from progress_fd!";
-+ //});
-
- QtApk::Changeset changes;
- bool upgrade_ok = m_apkdb.upgrade(flags, &changes);
---
-GitLab
-
-
-From 10914a3a74fb4854170d9ad47f552541762fb722 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Fri, 10 Apr 2020 09:06:17 +0300
-Subject: [PATCH 29/62] AlpineApkUpdater: refactor out helper error handler
- func
-
----
- .../AlpineApkBackend/AlpineApkUpdater.cpp | 37 +++++++++----------
- .../AlpineApkBackend/AlpineApkUpdater.h | 6 +++
- 2 files changed, 24 insertions(+), 19 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-index d0c0482e..173b7e48 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-@@ -215,12 +215,11 @@ void AlpineApkUpdater::startCheckForUpdates()
- updateAction.addArgument(QLatin1String("fakeRoot"), db->fakeRoot());
-
- // run updates check with elevated privileges to access
-- // system package manager files
-+ // system package manager files
- KAuth::ExecuteJob *reply = updateAction.execute();
- QObject::connect(reply, &KAuth::ExecuteJob::result,
- this, &AlpineApkUpdater::handleKAuthUpdateHelperReply);
-- //QObject::connect(reply, &KAuth::ExecuteJob::newData,
-- // this, &AlpineApkUpdater::handleKAuthUpdateHelperProgressStep);
-+ // qOverload is needed because of conflict with getter named percent()
- QObject::connect(reply, QOverload<KJob *, unsigned long>::of(&KAuth::ExecuteJob::percent),
- this, &AlpineApkUpdater::handleKAuthUpdateHelperProgress);
-
-@@ -236,14 +235,7 @@ void AlpineApkUpdater::handleKAuthUpdateHelperReply(KJob *job)
- qCDebug(LOG_ALPINEAPK) << "KAuth helper update reply received, updatesCount:" << m_updatesCount;
- Q_EMIT updatesCountChanged(m_updatesCount);
- } else {
-- const QString message = replyData.value(QLatin1String("errorString"),
-- reply->errorString()).toString();
-- qCDebug(LOG_ALPINEAPK) << "KAuth helper returned error:" << message << reply->error();
-- if (reply->error() == KAuth::ActionReply::Error::AuthorizationDeniedError) {
-- Q_EMIT passiveMessage(i18n("Authorization denied"));
-- } else {
-- Q_EMIT passiveMessage(i18n("Error") + QStringLiteral(":\n") + message);
-- }
-+ handleKAuthHelperError(reply, replyData);
- }
-
- // we are not in the state "Fetching updates" now, update UI
-@@ -273,17 +265,24 @@ void AlpineApkUpdater::handleKAuthUpgradeHelperReply(KJob *job)
- }
- }
- } else {
-- const QString message = replyData.value(QLatin1String("errorString"),
-- reply->errorString()).toString();
-- qCDebug(LOG_ALPINEAPK) << "KAuth helper returned error:" << message << reply->error();
-- if (reply->error() == KAuth::ActionReply::Error::AuthorizationDeniedError) {
-- Q_EMIT passiveMessage(i18n("Authorization denied"));
-- } else {
-- Q_EMIT passiveMessage(i18n("Error") + QStringLiteral(":\n") + message);
-- }
-+ handleKAuthHelperError(reply, replyData);
- }
-
- // we are not in the state "Fetching updates" now, update UI
- Q_EMIT checkForUpdatesFinished();
- }
-
-+void AlpineApkUpdater::handleKAuthHelperError(
-+ KAuth::ExecuteJob *reply,
-+ const QVariantMap &replyData)
-+{
-+ const QString message = replyData.value(QLatin1String("errorString"),
-+ reply->errorString()).toString();
-+ qCDebug(LOG_ALPINEAPK) << "KAuth helper returned error:" << message << reply->error();
-+ if (reply->error() == KAuth::ActionReply::Error::AuthorizationDeniedError) {
-+ Q_EMIT passiveMessage(i18n("Authorization denied"));
-+ } else {
-+ Q_EMIT passiveMessage(i18n("Error") + QStringLiteral(":\n") + message);
-+ }
-+}
-+
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h
-index 504e8c59..77140ca2 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h
-@@ -36,6 +36,9 @@
- class AbstractResourcesBackend;
- class AlpineApkBackend;
- class KJob;
-+namespace KAuth {
-+ class ExecuteJob;
-+}
-
- class AlpineApkUpdater : public AbstractBackendUpdater
- {
-@@ -164,6 +167,9 @@ public:
- QVector<QtApk::ChangesetItem> &changes() { return m_upgradeable.changes(); }
- const QVector<QtApk::ChangesetItem> &changes() const { return m_upgradeable.changes(); }
-
-+protected:
-+ void handleKAuthHelperError(KAuth::ExecuteJob *reply, const QVariantMap &replyData);
-+
- private:
- AlpineApkBackend *const m_backend;
- int m_updatesCount = 0;
---
-GitLab
-
-
-From ea002ca88aeb3488c7f0b2f3f88b9d785bd8a771 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Fri, 10 Apr 2020 09:07:38 +0300
-Subject: [PATCH 30/62] AlpineApkUpdater: use non-deprecated version of
- setDetails(V2)
-
-since KF 5.68
----
- .../AlpineApkBackend/AlpineApkUpdater.cpp | 20 +++++++++++++++++--
- 1 file changed, 18 insertions(+), 2 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-index 173b7e48..dae6c2a3 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-@@ -25,6 +25,7 @@
- #include "utils.h"
-
- #include <KAuthExecuteJob>
-+#include <kauth_version.h>
- #include <KLocalizedString>
-
- #include <QtApk.h>
-@@ -178,8 +179,15 @@ void AlpineApkUpdater::start()
- return;
- }
- upgradeAction.setTimeout(60 * 1000); // 1 minute
-- upgradeAction.setDetails(i18n("Get the list of packages to upgrade"));
-- upgradeAction.addArgument(QLatin1String("onlySimulate"), true);
-+#if KAUTH_VERSION < QT_VERSION_CHECK(5, 68, 0)
-+ upgradeAction.setDetails(i18n("Upgrade currently installed packages"));
-+#else
-+ static const KAuth::Action::DetailsMap details{
-+ { KAuth::Action::AuthDetail::DetailMessage, i18n("Upgrade currently installed packages") }
-+ };
-+ upgradeAction.setDetailsV2(details);
-+#endif
-+ // upgradeAction.addArgument(QLatin1String("onlySimulate"), true);
-
- // run upgrade check with elevated privileges
- KAuth::ExecuteJob *reply = upgradeAction.execute();
-@@ -211,7 +219,15 @@ void AlpineApkUpdater::startCheckForUpdates()
- return;
- }
- updateAction.setTimeout(60 * 1000); // 1 minute
-+ // setDetails deprecated since KF 5.68, use setDetailsV2() with DetailsMap.
-+#if KAUTH_VERSION < QT_VERSION_CHECK(5, 68, 0)
- updateAction.setDetails(i18n("Update repositories index"));
-+#else
-+ static const KAuth::Action::DetailsMap details{
-+ { KAuth::Action::AuthDetail::DetailMessage, i18n("Update repositories index") }
-+ };
-+ updateAction.setDetailsV2(details);
-+#endif
- updateAction.addArgument(QLatin1String("fakeRoot"), db->fakeRoot());
-
- // run updates check with elevated privileges to access
---
-GitLab
-
-
-From fdf2085939477dbe1f5a45461529c78b92b953a2 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Fri, 10 Apr 2020 09:09:13 +0300
-Subject: [PATCH 31/62] WIP: AlpineApkUpdater: enable upgrade action again
-
----
- .../backends/AlpineApkBackend/AlpineApkUpdater.cpp | 14 ++++++++------
- 1 file changed, 8 insertions(+), 6 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-index dae6c2a3..89a816c4 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-@@ -170,15 +170,17 @@ void AlpineApkUpdater::cancel()
- void AlpineApkUpdater::start()
- {
- qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-- return;
--#if 0
-+ //return;
-+//#if 0
- KAuth::Action upgradeAction(QStringLiteral("org.kde.discover.alpineapkbackend.upgrade"));
- upgradeAction.setHelperId(QStringLiteral("org.kde.discover.alpineapkbackend"));
-+
- if (!upgradeAction.isValid()) {
- qCWarning(LOG_ALPINEAPK) << "kauth upgradeAction is not valid!";
- return;
- }
-- upgradeAction.setTimeout(60 * 1000); // 1 minute
-+
-+ upgradeAction.setTimeout(30 * 60 * 1000); // 30 min
- #if KAUTH_VERSION < QT_VERSION_CHECK(5, 68, 0)
- upgradeAction.setDetails(i18n("Upgrade currently installed packages"));
- #else
-@@ -189,13 +191,13 @@ void AlpineApkUpdater::start()
- #endif
- // upgradeAction.addArgument(QLatin1String("onlySimulate"), true);
-
-- // run upgrade check with elevated privileges
-+ // run upgrade with elevated privileges
- KAuth::ExecuteJob *reply = upgradeAction.execute();
- QObject::connect(reply, &KAuth::ExecuteJob::result,
- this, &AlpineApkUpdater::handleKAuthUpgradeHelperReply);
-
- reply->start();
--#endif
-+//#endif
- }
-
- void AlpineApkUpdater::proceed()
-@@ -272,7 +274,7 @@ void AlpineApkUpdater::handleKAuthUpgradeHelperReply(KJob *job)
- if (reply->error() == 0) {
- QVariant pkgsV = replyData.value(QLatin1String("changes"));
- bool onlySimulate = replyData.value(QLatin1String("onlySimulate"), false).toBool();
-- qCDebug(LOG_ALPINEAPK) << "KAuth helper upgrade reply received:" << onlySimulate;
-+ qCDebug(LOG_ALPINEAPK) << "KAuth helper upgrade reply received, onlySimulate:" << onlySimulate;
- if (onlySimulate) {
- QVector<QtApk::Package> pkgVector = pkgsV.value<QVector<QtApk::Package>>();
- qCDebug(LOG_ALPINEAPK) << " num changes:" << pkgVector.size();
---
-GitLab
-
-
-From 1061a9bf94a60c28c0f7902392fb6a49f848f8d8 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Thu, 11 Jun 2020 22:39:09 +0300
-Subject: [PATCH 32/62] Adapt to changes in libapk-qt 0.3
-
-* Rename link target to ApkQt::ApkQt
-* rename header include <QtApk.h> => <QtApk>
----
- .../backends/AlpineApkBackend/AlpineApkAuthHelper.cpp | 8 ++++----
- .../backends/AlpineApkBackend/AlpineApkAuthHelper.h | 2 +-
- .../backends/AlpineApkBackend/AlpineApkBackend.cpp | 2 +-
- libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h | 2 +-
- .../backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp | 2 +-
- .../backends/AlpineApkBackend/AlpineApkUpdater.cpp | 6 +++---
- libdiscover/backends/AlpineApkBackend/CMakeLists.txt | 4 ++--
- 7 files changed, 13 insertions(+), 13 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-index 11e26786..0496c8f2 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-@@ -73,7 +73,7 @@ ActionReply AlpineApkAuthHelper::update(const QVariantMap &args)
-
- HelperSupport::progressStep(10);
-
-- if (!m_apkdb.open(QtApk::Database::QTAPK_OPENF_READWRITE)) {
-+ if (!m_apkdb.open(QtApk::QTAPK_OPENF_READWRITE)) {
- reply.setErrorDescription(QStringLiteral("Failed to open database!"));
- return reply;
- }
-@@ -119,15 +119,15 @@ ActionReply AlpineApkAuthHelper::upgrade(const QVariantMap &args)
-
- HelperSupport::progressStep(10);
-
-- if (!m_apkdb.open(QtApk::Database::QTAPK_OPENF_READWRITE)) {
-+ if (!m_apkdb.open(QtApk::QTAPK_OPENF_READWRITE)) {
- reply.setErrorDescription(QStringLiteral("Failed to open database!"));
- return reply;
- }
-
- bool onlySimulate = args.value(QLatin1String("onlySimulate"), false).toBool();
-- QtApk::Database::DbUpgradeFlags flags = QtApk::Database::QTAPK_UPGRADE_DEFAULT;
-+ QtApk::DbUpgradeFlags flags = QtApk::QTAPK_UPGRADE_DEFAULT;
- if (onlySimulate) {
-- flags = QtApk::Database::QTAPK_UPGRADE_SIMULATE;
-+ flags = QtApk::QTAPK_UPGRADE_SIMULATE;
- qCDebug(LOG_AUTHHELPER) << "Simulating upgrade run.";
- }
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-index 5c06e557..a634ce23 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-@@ -22,7 +22,7 @@
- #include <QVariant>
- #include <KAuthActionReply>
-
--#include <QtApk.h>
-+#include <QtApk>
-
- using namespace KAuth;
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index 750d2820..a089afea 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -70,7 +70,7 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
-
- qCDebug(LOG_ALPINEAPK) << "backend: populating resources...";
-
-- if (m_apkdb.open(QtApk::Database::QTAPK_OPENF_READONLY)) {
-+ if (m_apkdb.open(QtApk::QTAPK_OPENF_READONLY)) {
- m_availablePackages = m_apkdb.getAvailablePackages();
- m_installedPackages = m_apkdb.getInstalledPackages();
- m_apkdb.close();
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-index d6935257..755cf6a5 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-@@ -24,7 +24,7 @@
- #include <resources/AbstractResourcesBackend.h>
- #include <QVariantList>
-
--#include <QtApk.h>
-+#include <QtApk>
-
- class AlpineApkReviewsBackend;
- class AlpineApkUpdater;
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-index b964b40d..225fb443 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-@@ -29,7 +29,7 @@
- #include <KLocalizedString>
-
- // libapk-qt
--#include <QtApk.h>
-+#include <QtApk>
-
- AlpineApkSourcesBackend::AlpineApkSourcesBackend(AbstractResourcesBackend *parent)
- : AbstractSourcesBackend(parent)
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-index 89a816c4..0083f340 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-@@ -28,7 +28,7 @@
- #include <kauth_version.h>
- #include <KLocalizedString>
-
--#include <QtApk.h>
-+#include <QtApk>
-
-
- AlpineApkUpdater::AlpineApkUpdater(AbstractResourcesBackend *parent)
-@@ -49,12 +49,12 @@ void AlpineApkUpdater::prepare()
- }
-
- // readonly is fine for a simulation of upgrade
-- if (!db->open(QtApk::Database::QTAPK_OPENF_READONLY)) {
-+ if (!db->open(QtApk::QTAPK_OPENF_READONLY)) {
- emit passiveMessage(i18n("Failed to open APK database!"));
- return;
- }
-
-- if (!db->upgrade(QtApk::Database::QTAPK_UPGRADE_SIMULATE, &m_upgradeable)) {
-+ if (!db->upgrade(QtApk::QTAPK_UPGRADE_SIMULATE, &m_upgradeable)) {
- emit passiveMessage(i18n("Failed to get a list of packages to upgrade!"));
- db->close();
- return;
-diff --git a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-index 42e09c5b..319c7ad2 100644
---- a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-+++ b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-@@ -38,7 +38,7 @@ target_link_libraries(
- KF5::ConfigCore
- KF5::AuthCore
- Discover::Common
-- ApkQt::apk-qt
-+ ApkQt::ApkQt
- )
-
- # KAuth helper exe
-@@ -54,7 +54,7 @@ set_source_files_properties(
- target_link_libraries(alpineapk_kauth_helper
- Qt5::Core
- KF5::AuthCore
-- ApkQt::apk-qt
-+ ApkQt::ApkQt
- )
-
- kauth_install_actions(org.kde.discover.alpineapkbackend org.kde.discover.alpineapkbackend.actions)
---
-GitLab
-
-
-From 46c472be152ee67f48e03c8b0bf87bd2a537040e Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Sun, 28 Jun 2020 03:38:15 +0300
-Subject: [PATCH 33/62] AlpineApkAuthHelper: implement all operations in async
- mode
-
-also delete useless test() action
----
- .../AlpineApkBackend/AlpineApkAuthHelper.cpp | 234 ++++++++++++------
- .../AlpineApkBackend/AlpineApkAuthHelper.h | 19 +-
- .../org.kde.discover.alpineapkbackend.actions | 6 -
- 3 files changed, 181 insertions(+), 78 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-index 0496c8f2..a3236011 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-@@ -40,88 +40,194 @@ using namespace KAuth;
-
- AlpineApkAuthHelper::AlpineApkAuthHelper() {}
-
--ActionReply AlpineApkAuthHelper::test(const QVariantMap &args)
-+bool AlpineApkAuthHelper::openDatabase(const QVariantMap &args, bool readwrite)
- {
-- const QString txt = args[QStringLiteral("txt")].toString();
--
-- ActionReply reply = ActionReply::HelperErrorReply();
-- QByteArray replyData(QByteArrayLiteral("ok"));
-+ // maybe set fakeRoot (needs to be done before Database::open()
-+ const QString fakeRoot = args.value(QLatin1String("fakeRoot"), QString()).toString();
-+ if (!fakeRoot.isEmpty()) {
-+ m_apkdb.setFakeRoot(fakeRoot);
-+ }
-
-- // write some text file at the root directory as root, why not
-- QFile f(QStringLiteral("/lol.txt"));
-- if (f.open(QIODevice::ReadWrite | QIODevice::Text)) {
-- f.write(txt.toUtf8());
-- f.close();
-+ // calculate flags to use during open
-+ QtApk::DbOpenFlags fl = QtApk::QTAPK_OPENF_ENABLE_PROGRESSFD;
-+ if (readwrite) {
-+ fl |= QtApk::QTAPK_OPENF_READWRITE;
-+ }
-
-- reply = ActionReply::SuccessReply();
-- reply.setData({
-- { QStringLiteral("reply"), replyData },
-- });
-+ if (!m_apkdb.open(fl)) {
-+ return false;
- }
-+ return true;
-+}
-
-- return reply;
-+void AlpineApkAuthHelper::closeDatabase()
-+{
-+ m_apkdb.close();
- }
-
--ActionReply AlpineApkAuthHelper::update(const QVariantMap &args)
-+void AlpineApkAuthHelper::setupTransactionPostCreate(QtApk::Transaction *trans)
- {
-- ActionReply reply = ActionReply::HelperErrorReply();
-+ // receive progress notifications
-+ QObject::connect(trans, &QtApk::Transaction::progressChanged,
-+ this, &AlpineApkAuthHelper::reportProgress);
-
-- const QString fakeRoot = args.value(QLatin1String("fakeRoot"), QString()).toString();
-- if (!fakeRoot.isEmpty()) {
-- m_apkdb.setFakeRoot(fakeRoot);
-- }
-+ // receive error messages
-+ QObject::connect(trans, &QtApk::Transaction::errorOccured,
-+ this, &AlpineApkAuthHelper::onTransactionError);
-
-- HelperSupport::progressStep(10);
-+ // what to do when transaction is complete
-+ QObject::connect(trans, &QtApk::Transaction::finished,
-+ this, &AlpineApkAuthHelper::onTransactionFinished);
-+}
-
-- if (!m_apkdb.open(QtApk::QTAPK_OPENF_READWRITE)) {
-- reply.setErrorDescription(QStringLiteral("Failed to open database!"));
-- return reply;
-+void AlpineApkAuthHelper::reportProgress(float percent)
-+{
-+ int p = static_cast<int>(percent);
-+ if (p < 0) p = 0;
-+ if (p > 100) p = 100;
-+ HelperSupport::progressStep(p);
-+}
-+
-+void AlpineApkAuthHelper::onTransactionError(const QString &msg)
-+{
-+ qCWarning(LOG_AUTHHELPER).nospace() << "ERROR occured in transaction \""
-+ << m_currentTransaction->desc()
-+ << "\": " << msg;
-+ const QString errMsg = m_currentTransaction->desc() + QLatin1String(" failed: ") + msg;
-+ m_actionReply.setErrorDescription(errMsg);
-+ m_actionReply.setData({
-+ { QLatin1String("errorString"), errMsg }
-+ });
-+ m_trans_ok = false;
-+}
-+
-+void AlpineApkAuthHelper::onTransactionFinished()
-+{
-+ m_lastChangeset = m_currentTransaction->changeset();
-+ m_currentTransaction->deleteLater();
-+ m_currentTransaction = nullptr;
-+ m_loop.quit();
-+}
-+
-+ActionReply AlpineApkAuthHelper::update(const QVariantMap &args)
-+{
-+ // return error by default
-+ m_actionReply = ActionReply::HelperErrorReply();
-+
-+ HelperSupport::progressStep(0);
-+
-+ if (!openDatabase(args)) {
-+ m_actionReply.setErrorDescription(QStringLiteral("Failed to open database!"));
-+ return m_actionReply;
- }
-
-- bool update_ok = m_apkdb.updatePackageIndex();
-+ m_trans_ok = true;
-+ QtApk::Transaction *trans = m_apkdb.updatePackageIndex();
-+ setupTransactionPostCreate(trans);
-
-- if (update_ok) {
-+ trans->start();
-+ m_loop.exec();
-+
-+ if (m_trans_ok) {
- int updatesCount = m_apkdb.upgradeablePackagesCount();
-- reply = ActionReply::SuccessReply();
-- reply.setData({
-+ m_actionReply = ActionReply::SuccessReply();
-+ m_actionReply.setData({
- { QLatin1String("updatesCount"), updatesCount }
- });
-- } else {
-- reply.setErrorDescription(QStringLiteral("Repo update failed!"));
-- reply.setData({
-- { QLatin1String("errorString"), QStringLiteral("Repo update failed!") }
-- });
- }
-
-- m_apkdb.close();
-+ closeDatabase();
- HelperSupport::progressStep(100);
-
-- return reply;
-+ return m_actionReply;
- }
-
- ActionReply AlpineApkAuthHelper::add(const QVariantMap &args)
- {
-- Q_UNUSED(args)
-- ActionReply reply = ActionReply::HelperErrorReply();
-- return reply;
-+ // return error by default
-+ m_actionReply = ActionReply::HelperErrorReply();
-+
-+ HelperSupport::progressStep(0);
-+
-+ if (!openDatabase(args)) {
-+ m_actionReply.setErrorDescription(QStringLiteral("Failed to open database!"));
-+ return m_actionReply;
-+ }
-+
-+ const QString pkgName = args.value(QLatin1String("pkgName"), QString()).toString();
-+ if (pkgName.isEmpty()) {
-+ m_actionReply.setErrorDescription(QStringLiteral("Specify pkgName for adding!"));
-+ return m_actionReply;
-+ }
-+
-+ m_trans_ok = true;
-+ QtApk::Transaction *trans = m_apkdb.add(pkgName);
-+ setupTransactionPostCreate(trans);
-+
-+ trans->start();
-+ m_loop.exec();
-+
-+ if (m_trans_ok) {
-+ m_actionReply = ActionReply::SuccessReply();
-+ }
-+
-+ closeDatabase();
-+ HelperSupport::progressStep(100);
-+
-+ return m_actionReply;
- }
-
- ActionReply AlpineApkAuthHelper::del(const QVariantMap &args)
- {
-- Q_UNUSED(args)
-- ActionReply reply = ActionReply::HelperErrorReply();
-- return reply;
-+ // return error by default
-+ m_actionReply = ActionReply::HelperErrorReply();
-+
-+ HelperSupport::progressStep(0);
-+
-+ if (!openDatabase(args)) {
-+ m_actionReply.setErrorDescription(QStringLiteral("Failed to open database!"));
-+ return m_actionReply;
-+ }
-+
-+ const QString pkgName = args.value(QLatin1String("pkgName"), QString()).toString();
-+ if (pkgName.isEmpty()) {
-+ m_actionReply.setErrorDescription(QStringLiteral("Specify pkgName for removing!"));
-+ return m_actionReply;
-+ }
-+
-+ const bool delRdepends = args.value(QLatin1String("delRdepends"), false).toBool();
-+
-+ QtApk::DbDelFlags delFlags = QtApk::QTAPK_DEL_DEFAULT;
-+ if (delRdepends) {
-+ delFlags = QtApk::QTAPK_DEL_RDEPENDS;
-+ }
-+
-+ m_trans_ok = true;
-+ QtApk::Transaction *trans = m_apkdb.del(pkgName, delFlags);
-+ setupTransactionPostCreate(trans);
-+
-+ trans->start();
-+ m_loop.exec();
-+
-+ if (m_trans_ok) {
-+ m_actionReply = ActionReply::SuccessReply();
-+ }
-+
-+ closeDatabase();
-+ HelperSupport::progressStep(100);
-+
-+ return m_actionReply;
- }
-
- ActionReply AlpineApkAuthHelper::upgrade(const QVariantMap &args)
- {
-- ActionReply reply = ActionReply::HelperErrorReply();
-+ m_actionReply = ActionReply::HelperErrorReply();
-
-- HelperSupport::progressStep(10);
-+ HelperSupport::progressStep(0);
-
-- if (!m_apkdb.open(QtApk::QTAPK_OPENF_READWRITE)) {
-- reply.setErrorDescription(QStringLiteral("Failed to open database!"));
-- return reply;
-+ if (!openDatabase(args)) {
-+ m_actionReply.setErrorDescription(QStringLiteral("Failed to open database!"));
-+ return m_actionReply;
- }
-
- bool onlySimulate = args.value(QLatin1String("onlySimulate"), false).toBool();
-@@ -131,28 +237,18 @@ ActionReply AlpineApkAuthHelper::upgrade(const QVariantMap &args)
- qCDebug(LOG_AUTHHELPER) << "Simulating upgrade run.";
- }
-
-- const QString fakeRoot = args.value(QLatin1String("fakeRoot"), QString()).toString();
-- if (!fakeRoot.isEmpty()) {
-- m_apkdb.setFakeRoot(fakeRoot);
-- }
--
-- // no progress notifications for now
-- //int progress_fd = m_apkdb.progressFd();
-- //qCDebug(LOG_AUTHHELPER) << " progress_fd: " << progress_fd;
-+ m_trans_ok = true;
-
-- //QScopedPointer<QSocketNotifier> notifier(new QSocketNotifier(progress_fd, QSocketNotifier::Read));
-- //QObject::connect(notifier.data(), &QSocketNotifier::activated, notifier.data(), [](int sock) {
-- // Q_UNUSED(sock)
-- // qCDebug(LOG_AUTHHELPER) << " read trigger from progress_fd!";
-- //});
-+ QtApk::Transaction *trans = m_apkdb.upgrade(flags);
-+ setupTransactionPostCreate(trans);
-
-- QtApk::Changeset changes;
-- bool upgrade_ok = m_apkdb.upgrade(flags, &changes);
-+ trans->start();
-+ m_loop.exec();
-
-- if (upgrade_ok) {
-- reply = ActionReply::SuccessReply();
-+ if (m_trans_ok) {
-+ m_actionReply = ActionReply::SuccessReply();
- QVariantMap replyData;
-- const QVector<QtApk::ChangesetItem> ch = changes.changes();
-+ const QVector<QtApk::ChangesetItem> ch = m_lastChangeset.changes();
- QVector<QVariant> chVector;
- QVector<QtApk::Package> pkgVector;
- for (const QtApk::ChangesetItem &it: ch) {
-@@ -160,15 +256,13 @@ ActionReply AlpineApkAuthHelper::upgrade(const QVariantMap &args)
- }
- replyData.insert(QLatin1String("changes"), QVariant::fromValue(pkgVector));
- replyData.insert(QLatin1String("onlySimulate"), onlySimulate);
-- reply.setData(replyData);
-- } else {
-- reply.setErrorDescription(QStringLiteral("Repo upgrade failed!"));
-+ m_actionReply.setData(replyData);
- }
-
-- m_apkdb.close();
-+ closeDatabase();
- HelperSupport::progressStep(100);
-
-- return reply;
-+ return m_actionReply;
- }
-
- KAUTH_HELPER_MAIN("org.kde.discover.alpineapkbackend", AlpineApkAuthHelper)
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-index a634ce23..a670a2aa 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-@@ -18,6 +18,7 @@
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-+#include <QEventLoop>
- #include <QObject>
- #include <QVariant>
- #include <KAuthActionReply>
-@@ -33,12 +34,26 @@ public:
- AlpineApkAuthHelper();
-
- public Q_SLOTS:
-- ActionReply test(const QVariantMap &args);
- ActionReply update(const QVariantMap &args);
- ActionReply add(const QVariantMap &args);
- ActionReply del(const QVariantMap &args);
- ActionReply upgrade(const QVariantMap &args);
-
-+protected:
-+ bool openDatabase(const QVariantMap &args, bool readwrite = true);
-+ void closeDatabase();
-+ void setupTransactionPostCreate(QtApk::Transaction *trans);
-+
-+protected Q_SLOTS:
-+ void reportProgress(float percent);
-+ void onTransactionError(const QString &msg);
-+ void onTransactionFinished();
-+
- private:
-- QtApk::Database m_apkdb;
-+ QtApk::DatabaseAsync m_apkdb; // runs transactions in bg thread
-+ QtApk::Transaction *m_currentTransaction = nullptr;
-+ QEventLoop m_loop; // event loop that will run and wait while bg transaction is in progress
-+ ActionReply m_actionReply; // return value for main action slots
-+ bool m_trans_ok = true; // flag to indicate if bg transaction was successful
-+ QtApk::Changeset m_lastChangeset; // changeset from last completed transaction
- };
-diff --git a/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-index 10305a1a..0755c415 100644
---- a/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-+++ b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-@@ -1,9 +1,3 @@
--[org.kde.discover.alpineapkbackend.test]
--Name=Test Action
--Description=Just test
--Policy=auth_admin
--Persistence=session
--
- [org.kde.discover.alpineapkbackend.update]
- Name=Update repository index
- Description=Updates available packages list from repositories
---
-GitLab
-
-
-From 0e6cedcab270b845a8391491f2eb21bfb63b9137 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Mon, 29 Jun 2020 03:22:42 +0300
-Subject: [PATCH 34/62] AlpineApkAuthHelper: add method to write repositories
- config
-
----
- .../AlpineApkBackend/AlpineApkAuthHelper.cpp | 21 +++++++++++++++++++
- .../AlpineApkBackend/AlpineApkAuthHelper.h | 1 +
- .../org.kde.discover.alpineapkbackend.actions | 6 ++++++
- 3 files changed, 28 insertions(+)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-index a3236011..81c18255 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-@@ -265,4 +265,25 @@ ActionReply AlpineApkAuthHelper::upgrade(const QVariantMap &args)
- return m_actionReply;
- }
-
-+ActionReply AlpineApkAuthHelper::repoconfig(const QVariantMap &args)
-+{
-+ m_actionReply = ActionReply::HelperErrorReply();
-+ HelperSupport::progressStep(10);
-+
-+ if (args.contains(QLatin1String("repoList"))) {
-+ const QVariant v = args.value(QLatin1String("repoList"));
-+ const QVector<QtApk::Repository> repoVec = v.value<QVector<QtApk::Repository>>();
-+ if (QtApk::Database::saveRepositories(repoVec)) {
-+ m_actionReply = ActionReply::SuccessReply(); // OK
-+ } else {
-+ m_actionReply.setErrorDescription(QStringLiteral("Failed to write repositories config!"));
-+ }
-+ } else {
-+ m_actionReply.setErrorDescription(QStringLiteral("repoList parameter is missing in request!"));
-+ }
-+
-+ HelperSupport::progressStep(100);
-+ return m_actionReply;
-+}
-+
- KAUTH_HELPER_MAIN("org.kde.discover.alpineapkbackend", AlpineApkAuthHelper)
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-index a670a2aa..acce5648 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-@@ -38,6 +38,7 @@ public Q_SLOTS:
- ActionReply add(const QVariantMap &args);
- ActionReply del(const QVariantMap &args);
- ActionReply upgrade(const QVariantMap &args);
-+ ActionReply repoconfig(const QVariantMap &args);
-
- protected:
- bool openDatabase(const QVariantMap &args, bool readwrite = true);
-diff --git a/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-index 0755c415..f1bffe65 100644
---- a/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-+++ b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-@@ -21,3 +21,9 @@ Name=Remove package
- Description=Uninstall one package
- Policy=auth_admin
- Persistence=session
-+
-+[org.kde.discover.alpineapkbackend.repoconfig]
-+Name=Remove package
-+Description=Configure repositories URLs
-+Policy=auth_admin
-+Persistence=session
---
-GitLab
-
-
-From a29f4083d97a854b988d14b34400f6812b5000c7 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Mon, 29 Jun 2020 06:52:42 +0300
-Subject: [PATCH 35/62] AlpineApkAuthHelper: create event loop only when needed
-
-It fixes error "QEventLoop: requires QApplication",
-this makes it creation delayed to moment *after*
-QCoreApplication object is created by KAuthCore
-internals.
----
- .../AlpineApkBackend/AlpineApkAuthHelper.cpp | 14 +++++++++-----
- .../AlpineApkBackend/AlpineApkAuthHelper.h | 2 +-
- 2 files changed, 10 insertions(+), 6 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-index 81c18255..b436aa73 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-@@ -78,6 +78,10 @@ void AlpineApkAuthHelper::setupTransactionPostCreate(QtApk::Transaction *trans)
- // what to do when transaction is complete
- QObject::connect(trans, &QtApk::Transaction::finished,
- this, &AlpineApkAuthHelper::onTransactionFinished);
-+
-+ if (!m_loop) {
-+ m_loop = new QEventLoop(this);
-+ }
- }
-
- void AlpineApkAuthHelper::reportProgress(float percent)
-@@ -106,7 +110,7 @@ void AlpineApkAuthHelper::onTransactionFinished()
- m_lastChangeset = m_currentTransaction->changeset();
- m_currentTransaction->deleteLater();
- m_currentTransaction = nullptr;
-- m_loop.quit();
-+ m_loop->quit();
- }
-
- ActionReply AlpineApkAuthHelper::update(const QVariantMap &args)
-@@ -126,7 +130,7 @@ ActionReply AlpineApkAuthHelper::update(const QVariantMap &args)
- setupTransactionPostCreate(trans);
-
- trans->start();
-- m_loop.exec();
-+ m_loop->exec();
-
- if (m_trans_ok) {
- int updatesCount = m_apkdb.upgradeablePackagesCount();
-@@ -165,7 +169,7 @@ ActionReply AlpineApkAuthHelper::add(const QVariantMap &args)
- setupTransactionPostCreate(trans);
-
- trans->start();
-- m_loop.exec();
-+ m_loop->exec();
-
- if (m_trans_ok) {
- m_actionReply = ActionReply::SuccessReply();
-@@ -207,7 +211,7 @@ ActionReply AlpineApkAuthHelper::del(const QVariantMap &args)
- setupTransactionPostCreate(trans);
-
- trans->start();
-- m_loop.exec();
-+ m_loop->exec();
-
- if (m_trans_ok) {
- m_actionReply = ActionReply::SuccessReply();
-@@ -243,7 +247,7 @@ ActionReply AlpineApkAuthHelper::upgrade(const QVariantMap &args)
- setupTransactionPostCreate(trans);
-
- trans->start();
-- m_loop.exec();
-+ m_loop->exec();
-
- if (m_trans_ok) {
- m_actionReply = ActionReply::SuccessReply();
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-index acce5648..eed39f28 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-@@ -53,7 +53,7 @@ protected Q_SLOTS:
- private:
- QtApk::DatabaseAsync m_apkdb; // runs transactions in bg thread
- QtApk::Transaction *m_currentTransaction = nullptr;
-- QEventLoop m_loop; // event loop that will run and wait while bg transaction is in progress
-+ QEventLoop *m_loop = nullptr; // event loop that will run and wait while bg transaction is in progress
- ActionReply m_actionReply; // return value for main action slots
- bool m_trans_ok = true; // flag to indicate if bg transaction was successful
- QtApk::Changeset m_lastChangeset; // changeset from last completed transaction
---
-GitLab
-
-
-From 731de8079606f91c9631ed1f26c92a4c11a4195a Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Mon, 29 Jun 2020 06:55:59 +0300
-Subject: [PATCH 36/62] AlpineApkAuthHelper: fix nullptr deref in
- onTransactionFinished
-
-m_currentTransaction was never assigned
----
- libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp | 2 ++
- 1 file changed, 2 insertions(+)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-index b436aa73..f5d8e17e 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-@@ -67,6 +67,8 @@ void AlpineApkAuthHelper::closeDatabase()
-
- void AlpineApkAuthHelper::setupTransactionPostCreate(QtApk::Transaction *trans)
- {
-+ m_currentTransaction = trans; // remember current transaction here
-+
- // receive progress notifications
- QObject::connect(trans, &QtApk::Transaction::progressChanged,
- this, &AlpineApkAuthHelper::reportProgress);
---
-GitLab
-
-
-From 675e5a1dc6d0415be6b63a1d5296ad7092724b3d Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Tue, 30 Jun 2020 05:39:42 +0300
-Subject: [PATCH 37/62] AlpineApkSourcesBackend: fully functional sources
- editor
-
-* allows enable/disable repo
-* allows to add/remove repo
-* allows to change sources order
-* allows to reload/save changes
----
- .../AlpineApkSourcesBackend.cpp | 130 +++++++++++++-----
- .../AlpineApkSourcesBackend.h | 7 +
- 2 files changed, 102 insertions(+), 35 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-index 225fb443..28f08ef8 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-@@ -26,6 +26,8 @@
- #include <QVector>
-
- // KF5
-+#include <KAuthExecuteJob>
-+#include <kauth_version.h>
- #include <KLocalizedString>
-
- // libapk-qt
-@@ -35,16 +37,19 @@ AlpineApkSourcesBackend::AlpineApkSourcesBackend(AbstractResourcesBackend *paren
- : AbstractSourcesBackend(parent)
- , m_sourcesModel(new QStandardItemModel(this))
- , m_refreshAction(new QAction(QIcon::fromTheme(QStringLiteral("view-refresh")),
-- QStringLiteral("Refresh"), this))
-+ QStringLiteral("Reload"), this))
-+ , m_saveAction(new QAction(QIcon::fromTheme(QStringLiteral("document-save")),
-+ QStringLiteral("Save"), this))
-+ // ^^ unfortunately QML side ignores icons for custom actions
- {
- loadSources();
- QObject::connect(m_refreshAction, &QAction::triggered,
- this, &AlpineApkSourcesBackend::loadSources);
--
-- // can be used to track enabling/disabling repo source
-- // QObject::connect(m_sourcesModel, &QStandardItemModel::itemChanged, this, [](QStandardItem* item) {
-- // qCDebug(LOG_ALPINEAPK) << "source backend: DummySource changed" << item << item->checkState();
-- // });
-+ QObject::connect(m_saveAction, &QAction::triggered,
-+ this, &AlpineApkSourcesBackend::saveSources);
-+ // track enabling/disabling repo source
-+ QObject::connect(m_sourcesModel, &QStandardItemModel::itemChanged,
-+ this, &AlpineApkSourcesBackend::onItemChanged);
- }
-
- QAbstractItemModel *AlpineApkSourcesBackend::sources()
-@@ -52,48 +57,97 @@ QAbstractItemModel *AlpineApkSourcesBackend::sources()
- return m_sourcesModel;
- }
-
-+QStandardItem *AlpineApkSourcesBackend::sourceForId(const QString& id) const
-+{
-+ for (int i = 0; i < m_sourcesModel->rowCount(); ++i) {
-+ QStandardItem *item = m_sourcesModel->item(i, 0);
-+ if (item->data(AbstractSourcesBackend::IdRole) == id) {
-+ return item;
-+ }
-+ }
-+ return nullptr;
-+}
-+
- bool AlpineApkSourcesBackend::addSource(const QString &id)
- {
-- return addSourceFull(id, QString(), true);
-+ m_repos.append(QtApk::Repository(id, QString(), true));
-+ fillModelFromRepos();
-+ return true;
- }
-
--QStandardItem *AlpineApkSourcesBackend::sourceForId(const QString& id) const
-+void AlpineApkSourcesBackend::loadSources()
-+{
-+ m_repos = QtApk::Database::getRepositories();
-+ fillModelFromRepos();
-+}
-+
-+void AlpineApkSourcesBackend::fillModelFromRepos()
- {
-- for (int i = 0, c = m_sourcesModel->rowCount(); i < c; ++i) {
-- QStandardItem *it = m_sourcesModel->item(i, 0);
-- if (it->text() == id) {
-- return it;
-+ m_sourcesModel->clear();
-+ for (const QtApk::Repository &repo: m_repos) {
-+ if (repo.url.isEmpty()) {
-+ continue;
- }
-+ qCDebug(LOG_ALPINEAPK) << "source backend: Adding source:" << repo.url << repo.enabled;
-+ QStandardItem *it = new QStandardItem(repo.url);
-+ it->setData(repo.url, AbstractSourcesBackend::IdRole);
-+ it->setData(repo.comment, Qt::ToolTipRole);
-+ it->setCheckable(true);
-+ it->setCheckState(repo.enabled ? Qt::Checked : Qt::Unchecked);
-+ m_sourcesModel->appendRow(it);
- }
-- return nullptr;
- }
-
--bool AlpineApkSourcesBackend::addSourceFull(const QString &id, const QString &comment, bool enabled)
-+void AlpineApkSourcesBackend::saveSources()
- {
-- if (id.isEmpty()) {
-- return false;
-+ KAuth::Action repoConfigAction(QStringLiteral("org.kde.discover.alpineapkbackend.repoconfig"));
-+ repoConfigAction.setHelperId(QStringLiteral("org.kde.discover.alpineapkbackend"));
-+ if (!repoConfigAction.isValid()) {
-+ qCWarning(LOG_ALPINEAPK) << "repoConfigAction is not valid!";
-+ return;
- }
-
-- qCDebug(LOG_ALPINEAPK) << "source backend: Adding source:" << id;
-+ repoConfigAction.setTimeout(1 * 60 * 1000); // 1 min
-+#if KAUTH_VERSION < QT_VERSION_CHECK(5, 68, 0)
-+ upgradeAction.setDetails(i18n("Configure repositories URLs"));
-+#else
-+ static const KAuth::Action::DetailsMap details{
-+ { KAuth::Action::AuthDetail::DetailMessage, i18n("Configure repositories URLs") }
-+ };
-+ repoConfigAction.setDetailsV2(details);
-+#endif
-+ // pass in new repositories list
-+ repoConfigAction.addArgument(QLatin1String("repoList"),
-+ QVariant::fromValue<QVector<QtApk::Repository>>(m_repos));
-+
-+ // run with elevated privileges
-+ KAuth::ExecuteJob *reply = repoConfigAction.execute();
-+ QObject::connect(reply, &KAuth::ExecuteJob::result, this, [this] (KJob *job) {
-+ KAuth::ExecuteJob *reply = static_cast<KAuth::ExecuteJob *>(job);
-+ if (reply->error() != 0) {
-+ const QString errMessage = reply->errorString();
-+ qCWarning(LOG_ALPINEAPK) << "KAuth helper returned error:"
-+ << reply->error() << errMessage;
-+ if (reply->error() == KAuth::ActionReply::Error::AuthorizationDeniedError) {
-+ Q_EMIT passiveMessage(i18n("Authorization denied"));
-+ } else {
-+ Q_EMIT passiveMessage(i18n("Error: ") + errMessage);
-+ }
-+ }
-+ this->loadSources();
-+ });
-
-- QStandardItem *it = new QStandardItem(id);
-- it->setData(id, AbstractSourcesBackend::IdRole);
-- it->setData(comment, Qt::ToolTipRole);
-- it->setCheckable(true);
-- it->setCheckState(enabled ? Qt::Checked : Qt::Unchecked);
-- // for now, disable editing sources
-- it->setFlags(it->flags() & ~Qt::ItemIsEnabled);
-- m_sourcesModel->appendRow(it);
-- return true;
-+ reply->start();
- }
-
--void AlpineApkSourcesBackend::loadSources()
-+void AlpineApkSourcesBackend::onItemChanged(QStandardItem *item)
- {
-- QVector<QtApk::Repository> repos = QtApk::Database::getRepositories();
-- m_sourcesModel->clear();
-- for (const QtApk::Repository &repo: repos) {
-- addSourceFull(repo.url, repo.comment, repo.enabled);
-- }
-+ // update internal storage vector and relaod model from it
-+ // otherwise checks state are not updated in UI
-+ const Qt::CheckState cs = item->checkState();
-+ const QModelIndex idx = m_sourcesModel->indexFromItem(item);
-+ m_repos[idx.row()].enabled = (cs == Qt::Checked);
-+ fillModelFromRepos();
- }
-
- bool AlpineApkSourcesBackend::removeSource(const QString &id)
-@@ -103,18 +157,20 @@ bool AlpineApkSourcesBackend::removeSource(const QString &id)
- qCWarning(LOG_ALPINEAPK) << "source backend: couldn't find " << id;
- return false;
- }
-+ m_repos.remove(it->row());
- return m_sourcesModel->removeRow(it->row());
- }
-
- QString AlpineApkSourcesBackend::idDescription()
- {
-- return i18nc("Adding repo", "Enter apk repository URL, for example: "
-+ return i18nc("Adding repo", "Enter Alpine repository URL, for example: "
- "http://dl-cdn.alpinelinux.org/alpine/edge/testing/");
- }
-
- QVariantList AlpineApkSourcesBackend::actions() const
- {
- static const QVariantList s_actions {
-+ QVariant::fromValue<QObject *>(m_saveAction),
- QVariant::fromValue<QObject *>(m_refreshAction),
- };
- return s_actions;
-@@ -122,12 +178,12 @@ QVariantList AlpineApkSourcesBackend::actions() const
-
- bool AlpineApkSourcesBackend::supportsAdding() const
- {
-- return false; // for now, disable editing sources
-+ return true;
- }
-
- bool AlpineApkSourcesBackend::canMoveSources() const
- {
-- return false; // for now, disable editing sources
-+ return true;
- }
-
- bool AlpineApkSourcesBackend::moveSource(const QString& sourceId, int delta)
-@@ -147,5 +203,9 @@ bool AlpineApkSourcesBackend::moveSource(const QString& sourceId, int delta)
- || row == (m_sourcesModel->rowCount() - 1)) {
- Q_EMIT lastSourceIdChanged();
- }
-+
-+ // swap also items in internal storage vector
-+ m_repos.swapItemsAt(row, destRow);
-+
- return true;
- }
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h
-index 57894591..eacda22d 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h
-@@ -24,6 +24,8 @@
- #include <resources/AbstractSourcesBackend.h>
- #include <QStandardItemModel>
-
-+#include <QtApkRepository.h>
-+
- class AlpineApkSourcesBackend : public AbstractSourcesBackend
- {
- public:
-@@ -42,9 +44,14 @@ private:
- QStandardItem *sourceForId(const QString &id) const;
- bool addSourceFull(const QString &id, const QString &comment, bool enabled);
- void loadSources();
-+ void saveSources();
-+ void fillModelFromRepos();
-+ void onItemChanged(QStandardItem* item);
-
- QStandardItemModel *m_sourcesModel = nullptr;
- QAction *m_refreshAction = nullptr;
-+ QAction *m_saveAction = nullptr;
-+ QVector<QtApk::Repository> m_repos;
- };
-
- #endif // ALPINEAPKSOURCESBACKEND_H
---
-GitLab
-
-
-From 355f05379ed44cbd04208cba261995cb0adcb727 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Wed, 1 Jul 2020 08:34:10 +0300
-Subject: [PATCH 38/62] AlpineApkUpdater: update progressing status
-
----
- .../AlpineApkBackend/AlpineApkUpdater.cpp | 25 +++++++++++--------
- .../AlpineApkBackend/AlpineApkUpdater.h | 2 +-
- 2 files changed, 16 insertions(+), 11 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-index 0083f340..2f3d184f 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-@@ -125,20 +125,18 @@ QDateTime AlpineApkUpdater::lastUpdate() const
- bool AlpineApkUpdater::isCancelable() const
- {
- qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-- return true;
-+ return false;
- }
-
- bool AlpineApkUpdater::isProgressing() const
- {
-- qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-- return false;
-+ qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO << m_progressing;
-+ return m_progressing;
- }
-
- bool AlpineApkUpdater::isMarked(AbstractResource *res) const
- {
-- // qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
- return m_markedToUpdate.contains(res);
-- // return true;
- }
-
- void AlpineApkUpdater::fetchChangelog() const
-@@ -148,7 +146,6 @@ void AlpineApkUpdater::fetchChangelog() const
-
- double AlpineApkUpdater::updateSize() const
- {
-- // qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
- double sum = 0.0;
- for (AbstractResource *res : m_markedToUpdate) {
- sum += res->size();
-@@ -170,8 +167,6 @@ void AlpineApkUpdater::cancel()
- void AlpineApkUpdater::start()
- {
- qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-- //return;
--//#if 0
- KAuth::Action upgradeAction(QStringLiteral("org.kde.discover.alpineapkbackend.upgrade"));
- upgradeAction.setHelperId(QStringLiteral("org.kde.discover.alpineapkbackend"));
-
-@@ -196,8 +191,10 @@ void AlpineApkUpdater::start()
- QObject::connect(reply, &KAuth::ExecuteJob::result,
- this, &AlpineApkUpdater::handleKAuthUpgradeHelperReply);
-
-+ m_progressing = true;
-+ Q_EMIT progressingChanged(m_progressing);
-+
- reply->start();
--//#endif
- }
-
- void AlpineApkUpdater::proceed()
-@@ -207,7 +204,7 @@ void AlpineApkUpdater::proceed()
-
- int AlpineApkUpdater::updatesCount()
- {
-- // qDebug(LOG_ALPINEAPK) << Q_FUNC_INFO << m_updatesCount;
-+ qDebug(LOG_ALPINEAPK) << Q_FUNC_INFO << m_updatesCount;
- return m_updatesCount;
- }
-
-@@ -241,6 +238,10 @@ void AlpineApkUpdater::startCheckForUpdates()
- QObject::connect(reply, QOverload<KJob *, unsigned long>::of(&KAuth::ExecuteJob::percent),
- this, &AlpineApkUpdater::handleKAuthUpdateHelperProgress);
-
-+ m_progressing = true;
-+ Q_EMIT progressingChanged(m_progressing);
-+ Q_EMIT progressChanged(0);
-+
- reply->start();
- }
-
-@@ -256,6 +257,9 @@ void AlpineApkUpdater::handleKAuthUpdateHelperReply(KJob *job)
- handleKAuthHelperError(reply, replyData);
- }
-
-+ m_progressing = false;
-+ Q_EMIT progressingChanged(m_progressing);
-+
- // we are not in the state "Fetching updates" now, update UI
- Q_EMIT checkForUpdatesFinished();
- }
-@@ -265,6 +269,7 @@ void AlpineApkUpdater::handleKAuthUpdateHelperProgress(KJob *job, unsigned long
- Q_UNUSED(job)
- qCDebug(LOG_ALPINEAPK) << " fetch updates progress: " << percent;
- Q_EMIT fetchingUpdatesProgressChanged(percent);
-+ Q_EMIT progressChanged(static_cast<qreal>(percent));
- }
-
- void AlpineApkUpdater::handleKAuthUpgradeHelperReply(KJob *job)
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h
-index 77140ca2..0ee2fcb4 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h
-@@ -185,7 +185,7 @@ private:
-
- // QSet<AbstractResource*> m_upgradeable;
- // QSet<AbstractResource*> m_pendingResources;
--// bool m_settingUp;
-+ bool m_progressing = false;
- // qreal m_progress;
- // QDateTime m_lastUpdate;
- // QTimer m_timer;
---
-GitLab
-
-
-From 53c7dcf6655a2a7c4d979c59780ed2e4b86da6d0 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Wed, 1 Jul 2020 10:06:03 +0300
-Subject: [PATCH 39/62] AlpineApkTransaction: transaction should know its
- backend
-
----
- .../AlpineApkBackend/AlpineApkTransaction.cpp | 28 +++++++++----------
- .../AlpineApkBackend/AlpineApkTransaction.h | 27 ++++++++++--------
- 2 files changed, 29 insertions(+), 26 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-index b4f90df5..fdc1d053 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-@@ -26,7 +26,6 @@
- #include <QDebug>
- #include <KRandom>
-
--// #define TEST_PROCEED
-
- AlpineApkTransaction::AlpineApkTransaction(AlpineApkResource *app, Role role)
- : AlpineApkTransaction(app, {}, role)
-@@ -36,12 +35,25 @@ AlpineApkTransaction::AlpineApkTransaction(AlpineApkResource *app, Role role)
- AlpineApkTransaction::AlpineApkTransaction(AlpineApkResource *app, const AddonList &addons, Transaction::Role role)
- : Transaction(app->backend(), app, role, addons)
- , m_app(app)
-+ , m_backend(static_cast<AlpineApkBackend *>(app->backend()))
- {
-- setCancellable(true);
-+ setCancellable(false);
- setStatus(DownloadingStatus);
- iterateTransaction();
- }
-
-+void AlpineApkTransaction::proceed()
-+{
-+ finishTransaction();
-+}
-+
-+void AlpineApkTransaction::cancel()
-+{
-+ m_iterate = false;
-+
-+ setStatus(CancelledStatus);
-+}
-+
- void AlpineApkTransaction::iterateTransaction()
- {
- if (!m_iterate) {
-@@ -59,18 +71,6 @@ void AlpineApkTransaction::iterateTransaction()
- }
- }
-
--void AlpineApkTransaction::proceed()
--{
-- finishTransaction();
--}
--
--void AlpineApkTransaction::cancel()
--{
-- m_iterate = false;
--
-- setStatus(CancelledStatus);
--}
--
- void AlpineApkTransaction::finishTransaction()
- {
- AbstractResource::State newState;
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h
-index 63aeef8d..ba0a7750 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h
-@@ -23,24 +23,27 @@
-
- #include <Transaction/Transaction.h>
-
-+class AlpineApkBackend;
- class AlpineApkResource;
-+
- class AlpineApkTransaction : public Transaction
- {
-- Q_OBJECT
-- public:
-- AlpineApkTransaction(AlpineApkResource *app, Role role);
-- AlpineApkTransaction(AlpineApkResource *app, const AddonList &list, Role role);
-+Q_OBJECT
-+public:
-+ AlpineApkTransaction(AlpineApkResource *app, Role role);
-+ AlpineApkTransaction(AlpineApkResource *app, const AddonList &list, Role role);
-
-- void cancel() override;
-- void proceed() override;
-+ void cancel() override;
-+ void proceed() override;
-
-- private Q_SLOTS:
-- void iterateTransaction();
-- void finishTransaction();
-+private Q_SLOTS:
-+ void iterateTransaction();
-+ void finishTransaction();
-
-- private:
-- bool m_iterate = true;
-- AlpineApkResource *m_app;
-+private:
-+ bool m_iterate = true;
-+ AlpineApkResource *m_app;
-+ AlpineApkBackend *m_backend;
- };
-
- #endif // ALPINEAPKTRANSACTION_H
---
-GitLab
-
-
-From bc80a45c1214dbaf4d26698b59ec2a7687568578 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Tue, 28 Jul 2020 21:05:11 +0300
-Subject: [PATCH 40/62] AlpineApkBackend: style fixes
-
----
- .../AlpineApkBackend/AlpineApkBackend.cpp | 15 ++++++++++-----
- 1 file changed, 10 insertions(+), 5 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index a089afea..b695e5e6 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -66,7 +66,7 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
- this, &AlpineApkBackend::finishCheckForUpdates);
- m_updatesTimeoutTimer->setTimerType(Qt::CoarseTimer);
- m_updatesTimeoutTimer->setSingleShot(true);
-- m_updatesTimeoutTimer->setInterval(2 * 60 * 1000); // 2minutes
-+ m_updatesTimeoutTimer->setInterval(5 * 60 * 1000); // 5 minutes
-
- qCDebug(LOG_ALPINEAPK) << "backend: populating resources...";
-
-@@ -87,7 +87,8 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
- // which places it into "System updates" section
- const QString key = pkg.name.toLower();
- m_resources.insert(key, res);
-- connect(res, &AlpineApkResource::stateChanged, this, &AlpineApkBackend::updatesCountChanged);
-+ connect(res, &AlpineApkResource::stateChanged,
-+ this, &AlpineApkBackend::updatesCountChanged);
- }
- qCDebug(LOG_ALPINEAPK) << " available" << m_availablePackages.size()
- << "packages";
-@@ -215,17 +216,20 @@ AbstractReviewsBackend *AlpineApkBackend::reviewsBackend() const
-
- Transaction* AlpineApkBackend::installApplication(AbstractResource *app, const AddonList &addons)
- {
-- return new AlpineApkTransaction(qobject_cast<AlpineApkResource *>(app), addons, Transaction::InstallRole);
-+ return new AlpineApkTransaction(qobject_cast<AlpineApkResource *>(app),
-+ addons, Transaction::InstallRole);
- }
-
- Transaction* AlpineApkBackend::installApplication(AbstractResource *app)
- {
-- return new AlpineApkTransaction(qobject_cast<AlpineApkResource *>(app), Transaction::InstallRole);
-+ return new AlpineApkTransaction(qobject_cast<AlpineApkResource *>(app),
-+ Transaction::InstallRole);
- }
-
- Transaction* AlpineApkBackend::removeApplication(AbstractResource *app)
- {
-- return new AlpineApkTransaction(qobject_cast<AlpineApkResource *>(app), Transaction::RemoveRole);
-+ return new AlpineApkTransaction(qobject_cast<AlpineApkResource *>(app),
-+ Transaction::RemoveRole);
- }
-
- int AlpineApkBackend::fetchingUpdatesProgress() const
-@@ -281,4 +285,5 @@ void AlpineApkBackend::setFetchingUpdatesProgress(int percent)
- emit fetchingUpdatesProgressChanged();
- }
-
-+// needed because DISCOVER_BACKEND_PLUGIN(AlpineApkBackend) contains Q_OBJECT
- #include "AlpineApkBackend.moc"
---
-GitLab
-
-
-From 030de6832ec272e596db97577994a103ddc53e57 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Wed, 29 Jul 2020 03:48:50 +0300
-Subject: [PATCH 41/62] AlpineApk KAuth backend: fix repoconfig action name
-
----
- .../AlpineApkBackend/org.kde.discover.alpineapkbackend.actions | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-index f1bffe65..5f7f7677 100644
---- a/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-+++ b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-@@ -23,7 +23,7 @@ Policy=auth_admin
- Persistence=session
-
- [org.kde.discover.alpineapkbackend.repoconfig]
--Name=Remove package
-+Name=Configure repositories
- Description=Configure repositories URLs
- Policy=auth_admin
- Persistence=session
---
-GitLab
-
-
-From 3c121cf5f78c515869228428e949d09f207e2c0c Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Wed, 29 Jul 2020 03:50:27 +0300
-Subject: [PATCH 42/62] AlpineApkAuthHelper: clsoe database only on helper exit
-
-Don't be so quick to close database after each operation, close it in
-Helper class destructor, on helper exit.
----
- .../AlpineApkBackend/AlpineApkAuthHelper.cpp | 24 ++++++++++++-------
- .../AlpineApkBackend/AlpineApkAuthHelper.h | 1 +
- 2 files changed, 16 insertions(+), 9 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-index f5d8e17e..e6e6cb7a 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-@@ -40,8 +40,18 @@ using namespace KAuth;
-
- AlpineApkAuthHelper::AlpineApkAuthHelper() {}
-
-+AlpineApkAuthHelper::~AlpineApkAuthHelper()
-+{
-+ closeDatabase();
-+}
-+
- bool AlpineApkAuthHelper::openDatabase(const QVariantMap &args, bool readwrite)
- {
-+ // is already opened?
-+ if (m_apkdb.isOpen()) {
-+ return true;
-+ }
-+
- // maybe set fakeRoot (needs to be done before Database::open()
- const QString fakeRoot = args.value(QLatin1String("fakeRoot"), QString()).toString();
- if (!fakeRoot.isEmpty()) {
-@@ -62,7 +72,11 @@ bool AlpineApkAuthHelper::openDatabase(const QVariantMap &args, bool readwrite)
-
- void AlpineApkAuthHelper::closeDatabase()
- {
-- m_apkdb.close();
-+ // close database only if opened
-+ if (m_apkdb.isOpen()) {
-+ // this also stops bg thread
-+ m_apkdb.close();
-+ }
- }
-
- void AlpineApkAuthHelper::setupTransactionPostCreate(QtApk::Transaction *trans)
-@@ -142,9 +156,7 @@ ActionReply AlpineApkAuthHelper::update(const QVariantMap &args)
- });
- }
-
-- closeDatabase();
- HelperSupport::progressStep(100);
--
- return m_actionReply;
- }
-
-@@ -177,9 +189,7 @@ ActionReply AlpineApkAuthHelper::add(const QVariantMap &args)
- m_actionReply = ActionReply::SuccessReply();
- }
-
-- closeDatabase();
- HelperSupport::progressStep(100);
--
- return m_actionReply;
- }
-
-@@ -219,9 +229,7 @@ ActionReply AlpineApkAuthHelper::del(const QVariantMap &args)
- m_actionReply = ActionReply::SuccessReply();
- }
-
-- closeDatabase();
- HelperSupport::progressStep(100);
--
- return m_actionReply;
- }
-
-@@ -265,9 +273,7 @@ ActionReply AlpineApkAuthHelper::upgrade(const QVariantMap &args)
- m_actionReply.setData(replyData);
- }
-
-- closeDatabase();
- HelperSupport::progressStep(100);
--
- return m_actionReply;
- }
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-index eed39f28..7fd69a8f 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-@@ -32,6 +32,7 @@ class AlpineApkAuthHelper : public QObject
- Q_OBJECT
- public:
- AlpineApkAuthHelper();
-+ ~AlpineApkAuthHelper() override;
-
- public Q_SLOTS:
- ActionReply update(const QVariantMap &args);
---
-GitLab
-
-
-From 6489f33f67a1b68e440b0eea3192e0edcb6721a3 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Wed, 29 Jul 2020 03:59:10 +0300
-Subject: [PATCH 43/62] AlpineApkTransaction: implement add/del packages.
-
----
- .../AlpineApkBackend/AlpineApkTransaction.cpp | 120 ++++++++++++++----
- .../AlpineApkBackend/AlpineApkTransaction.h | 12 +-
- 2 files changed, 101 insertions(+), 31 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-index fdc1d053..b5d659da 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-@@ -22,56 +22,118 @@
- #include "AlpineApkBackend.h"
- #include "AlpineApkResource.h"
- #include "alpineapk_backend_logging.h" // generated by ECM
--#include <QTimer>
-+
-+// Qt
- #include <QDebug>
--#include <KRandom>
-+#include <QTimer>
-
-+// KF5
-+#include <KAuthExecuteJob>
-+#include <kauth_version.h>
-+#include <KLocalizedString>
-
--AlpineApkTransaction::AlpineApkTransaction(AlpineApkResource *app, Role role)
-- : AlpineApkTransaction(app, {}, role)
-+AlpineApkTransaction::AlpineApkTransaction(AlpineApkResource *res, Role role)
-+ : AlpineApkTransaction(res, {}, role)
- {
- }
-
--AlpineApkTransaction::AlpineApkTransaction(AlpineApkResource *app, const AddonList &addons, Transaction::Role role)
-- : Transaction(app->backend(), app, role, addons)
-- , m_app(app)
-- , m_backend(static_cast<AlpineApkBackend *>(app->backend()))
-+AlpineApkTransaction::AlpineApkTransaction(AlpineApkResource *res, const AddonList &addons, Transaction::Role role)
-+ : Transaction(res->backend(), res, role, addons)
-+ , m_resource(res)
-+ , m_backend(static_cast<AlpineApkBackend *>(res->backend()))
- {
- setCancellable(false);
-- setStatus(DownloadingStatus);
-- iterateTransaction();
-+ setStatus(QueuedStatus);
-+ // seems like Discover's transactions are supposed to start
-+ // automatically; no dedicated method to start transaction?
-+ startTransaction();
- }
-
- void AlpineApkTransaction::proceed()
- {
-- finishTransaction();
-+ startTransaction();
- }
-
- void AlpineApkTransaction::cancel()
- {
-- m_iterate = false;
--
- setStatus(CancelledStatus);
- }
-
--void AlpineApkTransaction::iterateTransaction()
-+void AlpineApkTransaction::startTransaction()
- {
-- if (!m_iterate) {
-+ KAuth::Action authAction;
-+ QString actionDescription(i18n("Install package"));
-+ switch(role()) {
-+ case InstallRole:
-+ authAction.setName(QStringLiteral("org.kde.discover.alpineapkbackend.add"));
-+ break;
-+ case RemoveRole:
-+ authAction.setName(QStringLiteral("org.kde.discover.alpineapkbackend.del"));
-+ actionDescription = i18n("Remove package");
-+ break;
-+ case ChangeAddonsRole:
-+ qCWarning(LOG_ALPINEAPK) << "Addons are not supported by Alpine APK Backend!";
- return;
-+ break;
- }
-+ authAction.setHelperId(QStringLiteral("org.kde.discover.alpineapkbackend"));
-
-- if(progress() < 100) {
-- setProgress(qBound(0, progress() + (KRandom::random() % 30), 100));
-- QTimer::singleShot(/*KRandom::random()%*/100, this, &AlpineApkTransaction::iterateTransaction);
-- } else if (status() == DownloadingStatus) {
-- setStatus(CommittingStatus);
-- QTimer::singleShot(/*KRandom::random()%*/100, this, &AlpineApkTransaction::iterateTransaction);
-+ if (!authAction.isValid()) {
-+ qCWarning(LOG_ALPINEAPK) << "kauth addAction is not valid!";
-+ return;
-+ }
-+
-+ authAction.setTimeout(60 * 60 * 1000); // 60 min
-+#if KAUTH_VERSION < QT_VERSION_CHECK(5, 68, 0)
-+ addAction.setDetails(actionDescription);
-+#else
-+ const KAuth::Action::DetailsMap details{
-+ { KAuth::Action::AuthDetail::DetailMessage, actionDescription }
-+ };
-+ authAction.setDetailsV2(details);
-+#endif
-+ authAction.addArgument(QLatin1String("pkgName"), m_resource->m_pkg.name);
-+
-+ // run upgrade with elevated privileges
-+ KAuth::ExecuteJob *reply = authAction.execute();
-+
-+ // get result of this job
-+ QObject::connect(reply, &KAuth::ExecuteJob::result, this, [this](KJob *job) {
-+ KAuth::ExecuteJob *reply = static_cast<KAuth::ExecuteJob *>(job);
-+ const QVariantMap &replyData = reply->data();
-+ if (reply->error() == 0) {
-+ finishTransactionOK();
-+ } else {
-+ QString message = replyData.value(QLatin1String("errorString"),
-+ reply->errorString()).toString();
-+ if (reply->error() == KAuth::ActionReply::Error::AuthorizationDeniedError) {
-+ message = i18n("Error: Authorization denied");
-+ }
-+ finishTransactionWithError(message);
-+ }
-+ });
-+
-+ // get progress reports for this job
-+ QObject::connect(reply, QOverload<KJob*, unsigned long>::of(&KAuth::ExecuteJob::percent), this,
-+ [this](KJob *job, unsigned long percent) {
-+ Q_UNUSED(job)
-+ if (percent >= 40 && role() == InstallRole) {
-+ setStatus(CommittingStatus);
-+ }
-+ setProgress(static_cast<int>(percent));
-+ });
-+
-+ setProgress(0);
-+ if (role() == InstallRole) {
-+ setStatus(DownloadingStatus);
- } else {
-- finishTransaction();
-+ setStatus(CommittingStatus);
- }
-+
-+ reply->start();
- }
-
--void AlpineApkTransaction::finishTransaction()
-+void AlpineApkTransaction::finishTransactionOK()
- {
- AbstractResource::State newState;
- switch(role()) {
-@@ -83,8 +145,16 @@ void AlpineApkTransaction::finishTransaction()
- newState = AbstractResource::None;
- break;
- }
-- m_app->setAddons(addons());
-- m_app->setState(newState);
-+ m_resource->setAddons(addons());
-+ m_resource->setState(newState);
- setStatus(DoneStatus);
- deleteLater();
- }
-+
-+void AlpineApkTransaction::finishTransactionWithError(const QString &errMsg)
-+{
-+ qCWarning(LOG_ALPINEAPK) << "Transaction finished with error:" << errMsg;
-+ Q_EMIT passiveMessage(i18n("Error") + QStringLiteral(":\n") + errMsg);
-+ setStatus(DoneWithErrorStatus);
-+ deleteLater();
-+}
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h
-index ba0a7750..cab1f6b9 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.h
-@@ -30,19 +30,19 @@ class AlpineApkTransaction : public Transaction
- {
- Q_OBJECT
- public:
-- AlpineApkTransaction(AlpineApkResource *app, Role role);
-- AlpineApkTransaction(AlpineApkResource *app, const AddonList &list, Role role);
-+ AlpineApkTransaction(AlpineApkResource *res, Role role);
-+ AlpineApkTransaction(AlpineApkResource *res, const AddonList &list, Role role);
-
- void cancel() override;
- void proceed() override;
-
- private Q_SLOTS:
-- void iterateTransaction();
-- void finishTransaction();
-+ void startTransaction();
-+ void finishTransactionOK();
-+ void finishTransactionWithError(const QString &errMsg);
-
- private:
-- bool m_iterate = true;
-- AlpineApkResource *m_app;
-+ AlpineApkResource *m_resource;
- AlpineApkBackend *m_backend;
- };
-
---
-GitLab
-
-
-From b21745b7881dedb89219f7c77153d258c774d40d Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Thu, 30 Jul 2020 03:41:57 +0300
-Subject: [PATCH 44/62] AlpineApkBackend: build with AppStreamQt support
-
-provide list of AppStreamQt components, load them once at startup
----
- .../AlpineApkBackend/AlpineApkBackend.cpp | 88 +++++++++++++++++--
- .../AlpineApkBackend/AlpineApkBackend.h | 4 +
- .../backends/AlpineApkBackend/CMakeLists.txt | 1 +
- 3 files changed, 88 insertions(+), 5 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index b695e5e6..ac91a6ef 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -32,11 +32,14 @@
-
- #include <KLocalizedString>
-
-+#include <AppStreamQt/pool.h>
-+
-+#include <QAction>
- #include <QDebug>
- #include <QLoggingCategory>
-+#include <QSet>
- #include <QThread>
- #include <QTimer>
--#include <QAction>
-
- DISCOVER_BACKEND_PLUGIN(AlpineApkBackend)
-
-@@ -68,6 +71,36 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
- m_updatesTimeoutTimer->setSingleShot(true);
- m_updatesTimeoutTimer->setInterval(5 * 60 * 1000); // 5 minutes
-
-+ qCDebug(LOG_ALPINEAPK) << "backend: loading AppStream metadata...";
-+ AppStream::Pool *appStreamPool = new AppStream::Pool(this);
-+ appStreamPool->setFlags(AppStream::Pool::FlagReadCollection |
-+ AppStream::Pool::FlagReadMetainfo |
-+ AppStream::Pool::FlagReadDesktopFiles);
-+ appStreamPool->setCacheFlags(AppStream::Pool::CacheFlagUseUser |
-+ AppStream::Pool::CacheFlagUseSystem);
-+ if (!appStreamPool->load()) {
-+ qCWarning(LOG_ALPINEAPK) << "backend: Failed to load appstream data:"
-+ << appStreamPool->lastError();
-+ } else {
-+ m_appStreamComponents = appStreamPool->components();
-+ qCDebug(LOG_ALPINEAPK) << "backend: loaded AppStream metadata OK:"
-+ << m_appStreamComponents.size() << "components.";
-+ // collect all categories present in appstream metadata
-+// QSet<QString> collectedCategories;
-+// for (const AppStream::Component &component : m_appStreamComponents) {
-+// const QStringList cats = component.categories();
-+// for (const QString &cat : cats) {
-+// collectedCategories.insert(cat);
-+// }
-+// }
-+// for (const QString &cat : collectedCategories) {
-+// qCDebug(LOG_ALPINEAPK) << " collected category: " << cat;
-+// m_collectedCategories << cat;
-+// }
-+ }
-+ delete appStreamPool;
-+ appStreamPool = nullptr;
-+
- qCDebug(LOG_ALPINEAPK) << "backend: populating resources...";
-
- if (m_apkdb.open(QtApk::QTAPK_OPENF_READONLY)) {
-@@ -78,13 +111,38 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
-
- if (m_availablePackages.size() > 0) {
- for (const QtApk::Package &pkg: m_availablePackages) {
-- AlpineApkResource *res = new AlpineApkResource(pkg, this);
-+
-+ // try to find appstream data for this package
-+ AppStream::Component appstreamComponent;
-+ AbstractResource::Type resType = AbstractResource::Type::Technical; // default
-+ for (const auto& appsC : m_appStreamComponents) {
-+ // find result which package name is exactly the one we want
-+ if (appsC.packageNames().contains(pkg.name)) {
-+ // found!
-+ appstreamComponent = appsC;
-+ // determine resource type here
-+ switch (appsC.kind()) {
-+ case AppStream::Component::KindDesktopApp:
-+ case AppStream::Component::KindConsoleApp:
-+ case AppStream::Component::KindWebApp:
-+ resType = AbstractResource::Type::Application;
-+ break;
-+ case AppStream::Component::KindAddon:
-+ resType = AbstractResource::Type::Addon;
-+ break;
-+ default:
-+ resType = AbstractResource::Type::Technical;
-+ break;
-+ }
-+ break; // exit for() loop
-+ }
-+ }
-+
-+ AlpineApkResource *res = new AlpineApkResource(pkg, appstreamComponent, resType, this);
- res->setCategoryName(QStringLiteral("alpine_packages"));
- res->setOriginSource(QStringLiteral("apk"));
- res->setSection(QStringLiteral("dummy"));
-- // here is the place to set a proper type of package
-- // AlpineApkResource defaults to AbstractResource::Technical,
-- // which places it into "System updates" section
-+
- const QString key = pkg.name.toLower();
- m_resources.insert(key, res);
- connect(res, &AlpineApkResource::stateChanged,
-@@ -125,6 +183,26 @@ QVector<Category *> AlpineApkBackend::category() const
- );
-
- return { s_rootCat };
-+
-+// static QVector<Category *> s_cats;
-+// if (s_cats.isEmpty()) {
-+// // fill only once
-+// s_cats << s_rootCat;
-+// for (const QString &scat : m_collectedCategories) {
-+// Category *cat = new Category(
-+// scat, // name
-+// QStringLiteral("package-x-generic"), // icon
-+// {}, // orFilters
-+// { displayName() }, // pluginName
-+// {}, // subcategories
-+// QUrl(), // decoration
-+// false // isAddons
-+// );
-+// s_cats << cat;
-+// }
-+// }
-+// return s_cats;
-+ // ^^ causes deep hang in discover in recalculating QML bindings
- }
-
- int AlpineApkBackend::updatesCount() const
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-index 755cf6a5..efcaf2ea 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-@@ -26,6 +26,8 @@
-
- #include <QtApk>
-
-+#include <AppStreamQt/component.h>
-+
- class AlpineApkReviewsBackend;
- class AlpineApkUpdater;
- class AlpineApkResource;
-@@ -77,6 +79,8 @@ private:
- bool m_fetching = false;
- int m_fetchProgress = 0;
- QTimer *m_updatesTimeoutTimer;
-+ QList<AppStream::Component> m_appStreamComponents;
-+ // QVector<QString> m_collectedCategories;
- };
-
- #endif // AlpineApkBackend_H
-diff --git a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-index 319c7ad2..53652538 100644
---- a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-+++ b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-@@ -39,6 +39,7 @@ target_link_libraries(
- KF5::AuthCore
- Discover::Common
- ApkQt::ApkQt
-+ AppStreamQt
- )
-
- # KAuth helper exe
---
-GitLab
-
-
-From e30e7319103e7aabaea9bcc424b33cc1a0226111 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Thu, 30 Jul 2020 03:44:55 +0300
-Subject: [PATCH 45/62] AlpineApkResource: AppStream integration
-
-return some data from appstream metadata, if available
----
- .../AlpineApkBackend/AlpineApkResource.cpp | 136 +++++++++++++++++-
- .../AlpineApkBackend/AlpineApkResource.h | 13 +-
- 2 files changed, 141 insertions(+), 8 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-index 346a28b2..a6f4bc0f 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-@@ -20,14 +20,29 @@
-
- #include "AlpineApkResource.h"
- #include "alpineapk_backend_logging.h" // generated by ECM
-+
-+#include <AppStreamQt/icon.h>
-+#include <AppStreamQt/pool.h>
-+#include <AppStreamQt/release.h>
-+
-+#include <QFileInfo>
-+#include <QIcon>
-+#include <QProcess>
-+
-+// libdiscover
-+#include "appstream/AppStreamUtils.h"
-+#include "config-paths.h"
- #include "Transaction/AddonList.h"
-
- AlpineApkResource::AlpineApkResource(const QtApk::Package &apkPkg,
-+ AppStream::Component &component,
-+ AbstractResource::Type typ,
- AbstractResourcesBackend *parent)
- : AbstractResource(parent)
- , m_state(AbstractResource::State::None)
-- , m_type(AbstractResource::Type::Technical)
-+ , m_type(typ)
- , m_pkg(apkPkg)
-+ , m_appsC(component)
- {
- }
-
-@@ -43,11 +58,17 @@ QString AlpineApkResource::availableVersion() const
-
- QStringList AlpineApkResource::categories()
- {
-+ if (hasAppStreamData()) {
-+ return m_appsC.categories();
-+ }
- return { m_category };
- }
-
- QString AlpineApkResource::comment()
- {
-+ if (hasAppStreamData()) {
-+ return m_appsC.summary();
-+ }
- return m_pkg.description;
- }
-
-@@ -58,26 +79,83 @@ int AlpineApkResource::size()
-
- QUrl AlpineApkResource::homepage()
- {
-+ if (hasAppStreamData()) {
-+ return m_appsC.url(AppStream::Component::UrlKindHomepage);
-+ }
- return QUrl::fromUserInput(m_pkg.url);
- }
-
- QUrl AlpineApkResource::helpURL()
- {
-+ if (hasAppStreamData()) {
-+ return m_appsC.url(AppStream::Component::UrlKindHelp);
-+ }
- return QUrl();
- }
-
- QUrl AlpineApkResource::bugURL()
- {
-+ if (hasAppStreamData()) {
-+ return m_appsC.url(AppStream::Component::UrlKindBugtracker);
-+ }
- return QUrl();
- }
-
- QUrl AlpineApkResource::donationURL()
- {
-+ if (hasAppStreamData()) {
-+ return m_appsC.url(AppStream::Component::UrlKindDonation);
-+ }
- return QUrl();
- }
-
-+///xdg-compatible icon name to represent the resource, url or QIcon
- QVariant AlpineApkResource::icon() const
- {
-+ if (hasAppStreamData()) {
-+ const QList<AppStream::Icon> icns = m_appsC.icons();
-+ if (icns.size() == 0) {
-+ return QStringLiteral("package-x-generic");
-+ }
-+ QIcon ico;
-+ const AppStream::Icon &appIco = icns.first();
-+
-+ switch (appIco.kind()) {
-+ case AppStream::Icon::KindStock:
-+ // we can create icons of this type directly from theme
-+ ico = QIcon::fromTheme(appIco.name());
-+ break;
-+ case AppStream::Icon::KindLocal:
-+ case AppStream::Icon::KindCached: {
-+ // try from predefined standard Alpine path
-+ const QString appstreamIconsPath = QLatin1String("/usr/share/app-info/icons/");
-+ const QString path = appstreamIconsPath + appIco.url().path();
-+ if (QFileInfo::exists(path)) {
-+ ico.addFile(path, appIco.size());
-+ } else {
-+ const QString altPath = appstreamIconsPath +
-+ QStringLiteral("%1x%2/").arg(appIco.size().width()).arg(appIco.size().height()) +
-+ appIco.url().path();
-+ if (QFileInfo::exists(altPath)) {
-+ ico.addFile(altPath, appIco.size());
-+ }
-+ }
-+ } break;
-+ default: break;
-+ }
-+
-+ // return icon only if we successfully loaded it
-+ if (!ico.isNull()) {
-+ return QVariant::fromValue<QIcon>(ico);
-+ }
-+
-+ // try to load from icon theme by package name, this is better
-+ // than nothing and works surprisingly well for many packages
-+ ico = QIcon::fromTheme(m_pkg.name);
-+ if (!ico.isNull()) {
-+ return QVariant::fromValue<QIcon>(ico);
-+ }
-+ }
- return QStringLiteral("package-x-generic");
- }
-
-@@ -98,11 +176,17 @@ QJsonArray AlpineApkResource::licenses()
-
- QString AlpineApkResource::longDescription()
- {
-+ if (hasAppStreamData()) {
-+ return m_appsC.description();
-+ }
- return m_pkg.description;
- }
-
- QString AlpineApkResource::name() const
- {
-+ if (hasAppStreamData()) {
-+ return m_appsC.name();
-+ }
- return m_pkg.name;
- }
-
-@@ -128,13 +212,25 @@ AbstractResource::State AlpineApkResource::state()
-
- void AlpineApkResource::fetchChangelog()
- {
-- // QString log = longDescription();
-- // Q_EMIT changelogFetched(log);
-+ if (hasAppStreamData()) {
-+ emit changelogFetched(AppStreamUtils::changelogToHtml(m_appsC));
-+ }
- }
-
- void AlpineApkResource::fetchScreenshots()
- {
-- // Q_EMIT screenshotsFetched(m_screenshotThumbnails, m_screenshots);
-+ if (hasAppStreamData()) {
-+ const QPair<QList<QUrl>, QList<QUrl> > sc = AppStreamUtils::fetchScreenshots(m_appsC);
-+ Q_EMIT screenshotsFetched(sc.first, sc.second);
-+ }
-+}
-+
-+QString AlpineApkResource::appstreamId() const
-+{
-+ if (hasAppStreamData()) {
-+ return m_appsC.id();
-+ }
-+ return QString();
- }
-
- void AlpineApkResource::setState(AbstractResource::State state)
-@@ -184,20 +280,41 @@ void AlpineApkResource::setAvailableVersion(const QString &av)
- m_availableVersion = av;
- }
-
-+bool AlpineApkResource::hasAppStreamData() const
-+{
-+ return !m_appsC.id().isEmpty();
-+}
-+
-+bool AlpineApkResource::canExecute() const
-+{
-+ if (hasAppStreamData()) {
-+ return (m_appsC.kind() == AppStream::Component::KindDesktopApp &&
-+ (m_state == AbstractResource::Installed || m_state == AbstractResource::Upgradeable));
-+ }
-+ return false;
-+}
-
- void AlpineApkResource::invokeApplication() const
- {
-- // QDesktopServices d;
-- // d.openUrl(QUrl(QStringLiteral("https://projects.kde.org/projects/extragear/sysadmin/muon")));
-+ const QString desktopFile = QLatin1String("/usr/share/applications/") + appstreamId();
-+ if (QFile::exists(desktopFile)) {
-+ QProcess::startDetached(QStringLiteral("kstart5"), {QStringLiteral("--service"), desktopFile});
-+ }
- }
-
- QUrl AlpineApkResource::url() const
- {
-+ if (hasAppStreamData()) {
-+ return QUrl(QStringLiteral("appstream://") + appstreamId());
-+ }
- return QUrl(QLatin1String("apk://") + packageName());
- }
-
- QString AlpineApkResource::author() const
- {
-+ if (hasAppStreamData()) {
-+ return m_appsC.developerName();
-+ }
- return m_pkg.maintainer;
- }
-
-@@ -208,5 +325,12 @@ QString AlpineApkResource::sourceIcon() const
-
- QDate AlpineApkResource::releaseDate() const
- {
-+ if (hasAppStreamData()) {
-+ if (!m_appsC.releases().isEmpty()) {
-+ auto release = m_appsC.releases().constFirst();
-+ return release.timestamp().date();
-+ }
-+ }
-+ // just build date is fine, too
- return m_pkg.buildTime.date();
- }
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-index 7140786c..e8948c46 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-@@ -23,6 +23,7 @@
-
- #include <resources/AbstractResource.h>
- #include <QtApkPackage.h>
-+#include <AppStreamQt/component.h>
-
- class AddonList;
-
-@@ -31,7 +32,10 @@ class AlpineApkResource : public AbstractResource
- Q_OBJECT
-
- public:
-- explicit AlpineApkResource(const QtApk::Package &apkPkg, AbstractResourcesBackend *parent);
-+ explicit AlpineApkResource(const QtApk::Package &apkPkg,
-+ AppStream::Component &component,
-+ AbstractResource::Type typ,
-+ AbstractResourcesBackend *parent);
-
- QList<PackageState> addonsInformation() override;
- QString section() override;
-@@ -52,10 +56,11 @@ public:
- QString name() const override;
- QString packageName() const override;
- AbstractResource::Type type() const override { return m_type; }
-- bool canExecute() const override { return true; }
-+ bool canExecute() const override;
- void invokeApplication() const override;
- void fetchChangelog() override;
- void fetchScreenshots() override;
-+ QString appstreamId() const override;
- QUrl url() const override;
- QString author() const override;
- QString sourceIcon() const override;
-@@ -69,6 +74,9 @@ public:
- void setAddonInstalled(const QString &addon, bool installed);
- void setAvailableVersion(const QString &av);
-
-+private:
-+ bool hasAppStreamData() const;
-+
- public:
- AbstractResource::State m_state;
- const AbstractResource::Type m_type;
-@@ -78,6 +86,7 @@ public:
- QString m_originSoruce;
- QString m_sectionName;
- QList<PackageState> m_addons;
-+ AppStream::Component m_appsC;
- };
-
- #endif // ALPINEAPKRESOURCE_H
---
-GitLab
-
-
-From 656f93bd845834c2115880a74b8420d7b5dfaac5 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Mon, 28 Sep 2020 08:38:25 +0300
-Subject: [PATCH 46/62] AlpineApkBackend: cmake: depend on Qt5::Concurrent
-
----
- libdiscover/backends/AlpineApkBackend/CMakeLists.txt | 1 +
- 1 file changed, 1 insertion(+)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-index 53652538..9e3bd82c 100644
---- a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-+++ b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-@@ -34,6 +34,7 @@ target_link_libraries(
- PRIVATE
- Qt5::Core
- Qt5::Widgets
-+ Qt5::Concurrent
- KF5::CoreAddons
- KF5::ConfigCore
- KF5::AuthCore
---
-GitLab
-
-
-From 722746208bd713f5fd5d9ea7f3bb0cd2546b712d Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Mon, 28 Sep 2020 09:51:12 +0300
-Subject: [PATCH 47/62] AlpineApkBackend: load packages data in backgroud
-
-Load packages data and appstream metadata in background thread to
-unblock UI and increase discover startup time.
----
- .../AlpineApkBackend/AlpineApkBackend.cpp | 114 +++++++++++++-----
- .../AlpineApkBackend/AlpineApkBackend.h | 5 +
- 2 files changed, 91 insertions(+), 28 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index ac91a6ef..e441c4b3 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -35,10 +35,14 @@
- #include <AppStreamQt/pool.h>
-
- #include <QAction>
-+#include <QtConcurrentRun>
- #include <QDebug>
-+#include <QFuture>
-+#include <QFutureWatcher>
- #include <QLoggingCategory>
- #include <QSet>
- #include <QThread>
-+#include <QThreadPool>
- #include <QTimer>
-
- DISCOVER_BACKEND_PLUGIN(AlpineApkBackend)
-@@ -53,9 +57,6 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
- const_cast<QLoggingCategory &>(LOG_ALPINEAPK()).setEnabled(QtDebugMsg, false);
- #endif
-
-- // schedule checking for updates
-- QTimer::singleShot(1000, this, &AlpineApkBackend::checkForUpdates);
--
- // connections with our updater
- QObject::connect(m_updater, &AlpineApkUpdater::updatesCountChanged,
- this, &AlpineApkBackend::updatesCountChanged);
-@@ -71,8 +72,24 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
- m_updatesTimeoutTimer->setSingleShot(true);
- m_updatesTimeoutTimer->setInterval(5 * 60 * 1000); // 5 minutes
-
-+ // load packages data in a separate thread; it takes a noticeable amount of time
-+ // and this way UI is not blocked here
-+ m_fetching = true; // we are busy!
-+ QFuture<void> loadResFuture = QtConcurrent::run(QThreadPool::globalInstance(), this,
-+ &AlpineApkBackend::loadResources);
-+
-+ QObject::connect(&m_voidFutureWatcher, &QFutureWatcher<void>::finished,
-+ this, &AlpineApkBackend::onLoadResourcesFinished);
-+ m_voidFutureWatcher.setFuture(loadResFuture);
-+
-+ SourcesModel::global()->addSourcesBackend(new AlpineApkSourcesBackend(this));
-+}
-+
-+void AlpineApkBackend::loadResources()
-+{
- qCDebug(LOG_ALPINEAPK) << "backend: loading AppStream metadata...";
-- AppStream::Pool *appStreamPool = new AppStream::Pool(this);
-+
-+ AppStream::Pool *appStreamPool = new AppStream::Pool();
- appStreamPool->setFlags(AppStream::Pool::FlagReadCollection |
- AppStream::Pool::FlagReadMetainfo |
- AppStream::Pool::FlagReadDesktopFiles);
-@@ -102,6 +119,7 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
- appStreamPool = nullptr;
-
- qCDebug(LOG_ALPINEAPK) << "backend: populating resources...";
-+ emit this->passiveMessage(i18n("Loading, please wait..."));
-
- if (m_apkdb.open(QtApk::QTAPK_OPENF_READONLY)) {
- m_availablePackages = m_apkdb.getAvailablePackages();
-@@ -114,43 +132,77 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
-
- // try to find appstream data for this package
- AppStream::Component appstreamComponent;
-- AbstractResource::Type resType = AbstractResource::Type::Technical; // default
- for (const auto& appsC : m_appStreamComponents) {
- // find result which package name is exactly the one we want
- if (appsC.packageNames().contains(pkg.name)) {
-- // found!
-- appstreamComponent = appsC;
-- // determine resource type here
-- switch (appsC.kind()) {
-- case AppStream::Component::KindDesktopApp:
-- case AppStream::Component::KindConsoleApp:
-- case AppStream::Component::KindWebApp:
-- resType = AbstractResource::Type::Application;
-- break;
-- case AppStream::Component::KindAddon:
-- resType = AbstractResource::Type::Addon;
-- break;
-- default:
-- resType = AbstractResource::Type::Technical;
-- break;
-+ // workaround for kate (Kate Sessions is found first, but
-+ // package name = "kate" too, bugged metadata?)
-+ if (pkg.name == QStringLiteral("kate")) {
-+ // qCDebug(LOG_ALPINEAPK) << appsC.packageNames() << appsC.id();
-+ // ^^ ("kate") "org.kde.plasma.katesessions"
-+ if (appsC.id() != QStringLiteral("org.kde.kate")) {
-+ continue;
-+ }
- }
-+ appstreamComponent = appsC;
- break; // exit for() loop
- }
- }
-
-+ const QString key = pkg.name.toLower();
-+ m_resourcesAppstreamData.insert(key, appstreamComponent);
-+ }
-+ }
-+
-+ qCDebug(LOG_ALPINEAPK) << " available" << m_availablePackages.size()
-+ << "packages";
-+ qCDebug(LOG_ALPINEAPK) << " installed" << m_installedPackages.size()
-+ << "packages";
-+}
-+
-+static AbstractResource::Type toDiscoverResourceType(const AppStream::Component &component)
-+{
-+ AbstractResource::Type resType = AbstractResource::Type::Technical; // default
-+ // determine resource type here
-+ switch (component.kind()) {
-+ case AppStream::Component::KindDesktopApp:
-+ case AppStream::Component::KindConsoleApp:
-+ case AppStream::Component::KindWebApp:
-+ resType = AbstractResource::Type::Application;
-+ break;
-+ case AppStream::Component::KindAddon:
-+ resType = AbstractResource::Type::Addon;
-+ break;
-+ default:
-+ resType = AbstractResource::Type::Technical;
-+ break;
-+ }
-+ return resType;
-+}
-+
-+void AlpineApkBackend::onLoadResourcesFinished()
-+{
-+ qCDebug(LOG_ALPINEAPK) << "backend: appstream data loaded and sorted; fill in resources";
-+
-+ if (m_availablePackages.size() > 0) {
-+ for (const QtApk::Package &pkg: m_availablePackages) {
-+ const QString key = pkg.name.toLower();
-+
-+ AppStream::Component &appstreamComponent = m_resourcesAppstreamData[key];
-+ const AbstractResource::Type resType = toDiscoverResourceType(appstreamComponent);
-+
- AlpineApkResource *res = new AlpineApkResource(pkg, appstreamComponent, resType, this);
- res->setCategoryName(QStringLiteral("alpine_packages"));
- res->setOriginSource(QStringLiteral("apk"));
- res->setSection(QStringLiteral("dummy"));
-
-- const QString key = pkg.name.toLower();
- m_resources.insert(key, res);
-- connect(res, &AlpineApkResource::stateChanged,
-- this, &AlpineApkBackend::updatesCountChanged);
-+ QObject::connect(res, &AlpineApkResource::stateChanged,
-+ this, &AlpineApkBackend::updatesCountChanged);
- }
-- qCDebug(LOG_ALPINEAPK) << " available" << m_availablePackages.size()
-- << "packages";
- }
-+
-+ // update "installed/not installed" state
- if (m_installedPackages.size() > 0) {
- for (const QtApk::Package &pkg: m_installedPackages) {
- const QString key = pkg.name.toLower();
-@@ -158,11 +210,17 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
- m_resources.value(key)->setState(AbstractResource::Installed);
- }
- }
-- qCDebug(LOG_ALPINEAPK) << " installed" << m_installedPackages.size()
-- << "packages";
- }
-
-- SourcesModel::global()->addSourcesBackend(new AlpineApkSourcesBackend(this));
-+ qCDebug(LOG_ALPINEAPK) << "backend: resources loaded.";
-+
-+ m_fetching = false;
-+ emit fetchingChanged();
-+ // ^^ this causes the UI to update "Featured" page and show
-+ // to user that we actually have loaded packages data
-+
-+ // schedule check for updates 1 sec after we've loaded all resources
-+ QTimer::singleShot(1000, this, &AlpineApkBackend::checkForUpdates);
- }
-
- QVector<Category *> AlpineApkBackend::category() const
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-index efcaf2ea..2ec8b00b 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-@@ -23,6 +23,7 @@
-
- #include <resources/AbstractResourcesBackend.h>
- #include <QVariantList>
-+#include <QFutureWatcher>
-
- #include <QtApk>
-
-@@ -65,12 +66,15 @@ public Q_SLOTS:
-
- private Q_SLOTS:
- void finishCheckForUpdates();
-+ void loadResources();
-+ void onLoadResourcesFinished();
-
- public:
- QtApk::Database *apkdb() { return &m_apkdb; }
-
- private:
- QHash<QString, AlpineApkResource *> m_resources;
-+ QHash<QString, AppStream::Component> m_resourcesAppstreamData;
- AlpineApkUpdater *m_updater;
- AlpineApkReviewsBackend *m_reviews;
- QtApk::Database m_apkdb;
-@@ -81,6 +85,7 @@ private:
- QTimer *m_updatesTimeoutTimer;
- QList<AppStream::Component> m_appStreamComponents;
- // QVector<QString> m_collectedCategories;
-+ QFutureWatcher<void> m_voidFutureWatcher;
- };
-
- #endif // AlpineApkBackend_H
---
-GitLab
-
-
-From 9110e3e0a945f0a383d50cac77f720706ecf725a Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Mon, 28 Sep 2020 09:51:35 +0300
-Subject: [PATCH 48/62] AlpineApkUpdater: disable too spammy logging
-
----
- libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-index 2f3d184f..c03fd5c5 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-@@ -204,7 +204,7 @@ void AlpineApkUpdater::proceed()
-
- int AlpineApkUpdater::updatesCount()
- {
-- qDebug(LOG_ALPINEAPK) << Q_FUNC_INFO << m_updatesCount;
-+ // qDebug(LOG_ALPINEAPK) << Q_FUNC_INFO << m_updatesCount;
- return m_updatesCount;
- }
-
---
-GitLab
-
-
-From c8bedfdd53b6f8da72745efb9090f285a33ea8ca Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Wed, 13 Jan 2021 22:08:44 +0300
-Subject: [PATCH 49/62] AlpineApkUpdater: try harder to get error string from
- helper
-
----
- .../backends/AlpineApkBackend/AlpineApkUpdater.cpp | 14 ++++++++++++--
- 1 file changed, 12 insertions(+), 2 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-index c03fd5c5..677a784f 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-@@ -299,12 +299,22 @@ void AlpineApkUpdater::handleKAuthHelperError(
- KAuth::ExecuteJob *reply,
- const QVariantMap &replyData)
- {
-- const QString message = replyData.value(QLatin1String("errorString"),
-+ // error message should be received as part of JSON reply from helper
-+ QString message = replyData.value(QLatin1String("errorString"),
- reply->errorString()).toString();
-- qCDebug(LOG_ALPINEAPK) << "KAuth helper returned error:" << message << reply->error();
- if (reply->error() == KAuth::ActionReply::Error::AuthorizationDeniedError) {
-+ qCWarning(LOG_ALPINEAPK) << "updater: KAuth helper returned AuthorizationDeniedError";
- Q_EMIT passiveMessage(i18n("Authorization denied"));
- } else {
-+ // if received error message is empty, try other ways to get error text for user
-+ // there are multiple ways to get error messages in kauth/kjob
-+ if (message.isEmpty()) {
-+ message = reply->errorString();
-+ if (message.isEmpty()) {
-+ message = reply->errorText();
-+ }
-+ }
-+ qCDebug(LOG_ALPINEAPK) << "updater: KAuth helper returned error:" << message << reply->error();
- Q_EMIT passiveMessage(i18n("Error") + QStringLiteral(":\n") + message);
- }
- }
---
-GitLab
-
-
-From 563f349cf9cab5642e675d67d16ae990b0f5ae3b Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Sun, 24 Jan 2021 05:20:42 +0300
-Subject: [PATCH 50/62] fixup AlpineApkTransaction.cpp
-
----
- libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-index b5d659da..ffd44292 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-@@ -94,7 +94,7 @@ void AlpineApkTransaction::startTransaction()
- #endif
- authAction.addArgument(QLatin1String("pkgName"), m_resource->m_pkg.name);
-
-- // run upgrade with elevated privileges
-+ // run action with elevated privileges
- KAuth::ExecuteJob *reply = authAction.execute();
-
- // get result of this job
---
-GitLab
-
-
-From d3800d49e67a05ceb354c0193eaf797d9858bd39 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Sun, 24 Jan 2021 08:16:20 +0300
-Subject: [PATCH 51/62] AlpineApkBackend: rename root category name
-
----
- libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index e441c4b3..8ddcc8e9 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -231,7 +231,7 @@ QVector<Category *> AlpineApkBackend::category() const
- // Display a single root category
- // we could add more, but Alpine apk does not have this concept
- static Category *s_rootCat = new Category(
-- i18nc("Root category name", "Alpine packages"),
-+ i18nc("Root category name", "Alpine Linux packages"),
- QStringLiteral("package-x-generic"), // icon
- { s_apkFlt }, // orFilters - include packages that match filter
- { displayName() }, // pluginName
---
-GitLab
-
-
-From 9284ff898c9fcb32eef7dc8d406141e41d476cf1 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Sun, 24 Jan 2021 08:28:04 +0300
-Subject: [PATCH 52/62] KAuth helper: use single KAuth action for all
- operations
-
-Use single entry point for all package management operations.
-Using single KAuth action allows user to enter his password only once
-for all privileged operations during Discover session.
----
- .../AlpineApkBackend/AlpineApkAuthHelper.cpp | 91 ++++++++++---------
- .../AlpineApkBackend/AlpineApkAuthHelper.h | 15 ++-
- .../org.kde.discover.alpineapkbackend.actions | 30 +-----
- 3 files changed, 59 insertions(+), 77 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-index e6e6cb7a..97affc01 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.cpp
-@@ -113,6 +113,7 @@ void AlpineApkAuthHelper::onTransactionError(const QString &msg)
- qCWarning(LOG_AUTHHELPER).nospace() << "ERROR occured in transaction \""
- << m_currentTransaction->desc()
- << "\": " << msg;
-+ // construct error message to use in helper reply
- const QString errMsg = m_currentTransaction->desc() + QLatin1String(" failed: ") + msg;
- m_actionReply.setErrorDescription(errMsg);
- m_actionReply.setData({
-@@ -129,16 +130,48 @@ void AlpineApkAuthHelper::onTransactionFinished()
- m_loop->quit();
- }
-
--ActionReply AlpineApkAuthHelper::update(const QVariantMap &args)
-+// single entry point for all package management actions
-+ActionReply AlpineApkAuthHelper::pkgmgmt(const QVariantMap &args)
- {
-- // return error by default
- m_actionReply = ActionReply::HelperErrorReply();
--
- HelperSupport::progressStep(0);
-
-+ // actual package management action to perform is passed in "pkgAction" argument
-+ if (!args.contains(QLatin1String("pkgAction"))) {
-+ m_actionReply.setError(ActionReply::InvalidActionError);
-+ m_actionReply.setErrorDescription(QLatin1String("Please pass \'pkgAction\' argument."));
-+ HelperSupport::progressStep(100);
-+ return m_actionReply;
-+ }
-+
-+ const QString pkgAction = args.value(QLatin1String("pkgAction")).toString();
-+
-+ if (pkgAction == QStringLiteral("update")) {
-+ update(args);
-+ } else if (pkgAction == QStringLiteral("add")) {
-+ add(args);
-+ } else if (pkgAction == QStringLiteral("del")) {
-+ del(args);
-+ } else if (pkgAction == QStringLiteral("upgrade")) {
-+ upgrade(args);
-+ } else if (pkgAction == QStringLiteral("repoconfig")) {
-+ repoconfig(args);
-+ } else {
-+ // error: unknown pkgAction
-+ m_actionReply.setError(ActionReply::NoSuchActionError);
-+ m_actionReply.setErrorDescription(QLatin1String("Please pass a valid \'pkgAction\' argument. "
-+ "Action \"%1\" is not recognized.").arg(pkgAction));
-+ }
-+
-+ HelperSupport::progressStep(100);
-+ return m_actionReply;
-+}
-+
-+void AlpineApkAuthHelper::update(const QVariantMap &args)
-+{
- if (!openDatabase(args)) {
- m_actionReply.setErrorDescription(QStringLiteral("Failed to open database!"));
-- return m_actionReply;
-+ return;
- }
-
- m_trans_ok = true;
-@@ -155,27 +188,19 @@ ActionReply AlpineApkAuthHelper::update(const QVariantMap &args)
- { QLatin1String("updatesCount"), updatesCount }
- });
- }
--
-- HelperSupport::progressStep(100);
-- return m_actionReply;
- }
-
--ActionReply AlpineApkAuthHelper::add(const QVariantMap &args)
-+void AlpineApkAuthHelper::add(const QVariantMap &args)
- {
-- // return error by default
-- m_actionReply = ActionReply::HelperErrorReply();
--
-- HelperSupport::progressStep(0);
--
- if (!openDatabase(args)) {
- m_actionReply.setErrorDescription(QStringLiteral("Failed to open database!"));
-- return m_actionReply;
-+ return;
- }
-
- const QString pkgName = args.value(QLatin1String("pkgName"), QString()).toString();
- if (pkgName.isEmpty()) {
- m_actionReply.setErrorDescription(QStringLiteral("Specify pkgName for adding!"));
-- return m_actionReply;
-+ return;
- }
-
- m_trans_ok = true;
-@@ -188,27 +213,19 @@ ActionReply AlpineApkAuthHelper::add(const QVariantMap &args)
- if (m_trans_ok) {
- m_actionReply = ActionReply::SuccessReply();
- }
--
-- HelperSupport::progressStep(100);
-- return m_actionReply;
- }
-
--ActionReply AlpineApkAuthHelper::del(const QVariantMap &args)
-+void AlpineApkAuthHelper::del(const QVariantMap &args)
- {
-- // return error by default
-- m_actionReply = ActionReply::HelperErrorReply();
--
-- HelperSupport::progressStep(0);
--
- if (!openDatabase(args)) {
- m_actionReply.setErrorDescription(QStringLiteral("Failed to open database!"));
-- return m_actionReply;
-+ return;
- }
-
- const QString pkgName = args.value(QLatin1String("pkgName"), QString()).toString();
- if (pkgName.isEmpty()) {
- m_actionReply.setErrorDescription(QStringLiteral("Specify pkgName for removing!"));
-- return m_actionReply;
-+ return;
- }
-
- const bool delRdepends = args.value(QLatin1String("delRdepends"), false).toBool();
-@@ -228,20 +245,13 @@ ActionReply AlpineApkAuthHelper::del(const QVariantMap &args)
- if (m_trans_ok) {
- m_actionReply = ActionReply::SuccessReply();
- }
--
-- HelperSupport::progressStep(100);
-- return m_actionReply;
- }
-
--ActionReply AlpineApkAuthHelper::upgrade(const QVariantMap &args)
-+void AlpineApkAuthHelper::upgrade(const QVariantMap &args)
- {
-- m_actionReply = ActionReply::HelperErrorReply();
--
-- HelperSupport::progressStep(0);
--
- if (!openDatabase(args)) {
- m_actionReply.setErrorDescription(QStringLiteral("Failed to open database!"));
-- return m_actionReply;
-+ return;
- }
-
- bool onlySimulate = args.value(QLatin1String("onlySimulate"), false).toBool();
-@@ -272,16 +282,10 @@ ActionReply AlpineApkAuthHelper::upgrade(const QVariantMap &args)
- replyData.insert(QLatin1String("onlySimulate"), onlySimulate);
- m_actionReply.setData(replyData);
- }
--
-- HelperSupport::progressStep(100);
-- return m_actionReply;
- }
-
--ActionReply AlpineApkAuthHelper::repoconfig(const QVariantMap &args)
-+void AlpineApkAuthHelper::repoconfig(const QVariantMap &args)
- {
-- m_actionReply = ActionReply::HelperErrorReply();
-- HelperSupport::progressStep(10);
--
- if (args.contains(QLatin1String("repoList"))) {
- const QVariant v = args.value(QLatin1String("repoList"));
- const QVector<QtApk::Repository> repoVec = v.value<QVector<QtApk::Repository>>();
-@@ -293,9 +297,6 @@ ActionReply AlpineApkAuthHelper::repoconfig(const QVariantMap &args)
- } else {
- m_actionReply.setErrorDescription(QStringLiteral("repoList parameter is missing in request!"));
- }
--
-- HelperSupport::progressStep(100);
-- return m_actionReply;
- }
-
- KAUTH_HELPER_MAIN("org.kde.discover.alpineapkbackend", AlpineApkAuthHelper)
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-index 7fd69a8f..240e6ed3 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthHelper.h
-@@ -35,17 +35,22 @@ public:
- ~AlpineApkAuthHelper() override;
-
- public Q_SLOTS:
-- ActionReply update(const QVariantMap &args);
-- ActionReply add(const QVariantMap &args);
-- ActionReply del(const QVariantMap &args);
-- ActionReply upgrade(const QVariantMap &args);
-- ActionReply repoconfig(const QVariantMap &args);
-+ // single entry point for all package management operations
-+ ActionReply pkgmgmt(const QVariantMap &args);
-
- protected:
-+ // helpers
- bool openDatabase(const QVariantMap &args, bool readwrite = true);
- void closeDatabase();
- void setupTransactionPostCreate(QtApk::Transaction *trans);
-
-+ // individual pakckage management actions
-+ void update(const QVariantMap &args);
-+ void add(const QVariantMap &args);
-+ void del(const QVariantMap &args);
-+ void upgrade(const QVariantMap &args);
-+ void repoconfig(const QVariantMap &args);
-+
- protected Q_SLOTS:
- void reportProgress(float percent);
- void onTransactionError(const QString &msg);
-diff --git a/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-index 5f7f7677..c9bb5f9f 100644
---- a/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-+++ b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-@@ -1,29 +1,5 @@
--[org.kde.discover.alpineapkbackend.update]
--Name=Update repository index
--Description=Updates available packages list from repositories
--Policy=auth_admin
--Persistence=session
--
--[org.kde.discover.alpineapkbackend.upgrade]
--Name=Upgrade all upgradable packages
--Description=Upgrade installed packages to latest versions
--Policy=auth_admin
--Persistence=session
--
--[org.kde.discover.alpineapkbackend.add]
--Name=Install/upgrade package
--Description=Installs/upgrades one package
--Policy=auth_admin
--Persistence=session
--
--[org.kde.discover.alpineapkbackend.del]
--Name=Remove package
--Description=Uninstall one package
--Policy=auth_admin
--Persistence=session
--
--[org.kde.discover.alpineapkbackend.repoconfig]
--Name=Configure repositories
--Description=Configure repositories URLs
-+[org.kde.discover.alpineapkbackend.pkgmgmt]
-+Name=Package management
-+Description=Install or remove packages, upgrade system
- Policy=auth_admin
- Persistence=session
---
-GitLab
-
-
-From 5d3beff075531cce8263f386eb067ab9943c4017 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Sun, 24 Jan 2021 08:32:59 +0300
-Subject: [PATCH 53/62] AlpineApk: refactor code to use single entry for all
- KAuth stuff
-
- * Add AlpineApkAuthActionFactory to contain all KAuth
- action creation stuff in one place.
- * ActionFactory: Use new single entry point for all KAuth
- helper operations.
- * Switch all places in code that used KAuth actions to
- using ActionFactory:create*() methods.
----
- .../AlpineApkAuthActionFactory.cpp | 118 ++++++++++++++++++
- .../AlpineApkAuthActionFactory.h | 41 ++++++
- .../AlpineApkSourcesBackend.cpp | 28 +----
- .../AlpineApkBackend/AlpineApkTransaction.cpp | 29 +----
- .../AlpineApkBackend/AlpineApkUpdater.cpp | 45 +------
- .../backends/AlpineApkBackend/CMakeLists.txt | 2 +
- 6 files changed, 178 insertions(+), 85 deletions(-)
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkAuthActionFactory.cpp
- create mode 100644 libdiscover/backends/AlpineApkBackend/AlpineApkAuthActionFactory.h
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthActionFactory.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthActionFactory.cpp
-new file mode 100644
-index 00000000..972f8ec5
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthActionFactory.cpp
-@@ -0,0 +1,118 @@
-+/***************************************************************************
-+ * Copyright © 2020 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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 <KLocalizedString>
-+#include <kauth_version.h>
-+
-+#include "AlpineApkAuthActionFactory.h"
-+#include "alpineapk_backend_logging.h"
-+
-+namespace ActionFactory {
-+
-+static KAuth::Action createAlpineApkKAuthAction()
-+{
-+ KAuth::Action action(QStringLiteral("org.kde.discover.alpineapkbackend.pkgmgmt"));
-+ action.setHelperId(QStringLiteral("org.kde.discover.alpineapkbackend"));
-+ if (!action.isValid()) {
-+ qCWarning(LOG_ALPINEAPK) << "Created KAuth action is not valid!";
-+ return action;
-+ }
-+
-+ // set action description
-+ // setDetails deprecated since KF 5.68, use setDetailsV2() with DetailsMap.
-+#if KAUTH_VERSION < QT_VERSION_CHECK(5, 68, 0)
-+ action.setDetails(i18n("Package management"));
-+#else
-+ static const KAuth::Action::DetailsMap details{
-+ { KAuth::Action::AuthDetail::DetailMessage, i18n("Package management") }
-+ };
-+ action.setDetailsV2(details);
-+#endif
-+
-+ // change default timeout to 1 minute, bcause default DBus timeout
-+ // of 25 seconds is not enough
-+ action.setTimeout(1 * 60 * 1000);
-+
-+ return action;
-+}
-+
-+KAuth::ExecuteJob *createUpdateAction(const QString &fakeRoot)
-+{
-+ KAuth::Action action = createAlpineApkKAuthAction();
-+ if (!action.isValid()) {
-+ return nullptr;
-+ }
-+ // update-action specific details
-+ action.setTimeout(2 * 60 * 1000); // 2 minutes
-+ action.addArgument(QLatin1String("pkgAction"), QLatin1String("update"));
-+ action.addArgument(QLatin1String("fakeRoot"), fakeRoot);
-+ return action.execute();
-+}
-+
-+KAuth::ExecuteJob *createUpgradeAction(bool onlySimulate)
-+{
-+ KAuth::Action action = createAlpineApkKAuthAction();
-+ if (!action.isValid()) {
-+ return nullptr;
-+ }
-+ action.setTimeout(3 * 60 * 60 * 1000); // 3 hours, system upgrade can take really long
-+ action.addArgument(QLatin1String("pkgAction"), QLatin1String("upgrade"));
-+ action.addArgument(QLatin1String("onlySimulate"), onlySimulate);
-+ return action.execute();
-+}
-+
-+KAuth::ExecuteJob *createAddAction(const QString &pkgName)
-+{
-+ KAuth::Action action = createAlpineApkKAuthAction();
-+ if (!action.isValid()) {
-+ return nullptr;
-+ }
-+ action.setTimeout(1 * 60 * 60 * 1000); // 1 hour, in case package is really big?
-+ action.addArgument(QLatin1String("pkgAction"), QLatin1String("add"));
-+ action.addArgument(QLatin1String("pkgName"), pkgName);
-+ return action.execute();
-+}
-+
-+KAuth::ExecuteJob *createDelAction(const QString &pkgName)
-+{
-+ KAuth::Action action = createAlpineApkKAuthAction();
-+ if (!action.isValid()) {
-+ return nullptr;
-+ }
-+ action.setTimeout(1 * 60 * 60 * 1000); // although deletion is almost instant
-+ action.addArgument(QLatin1String("pkgAction"), QLatin1String("del"));
-+ action.addArgument(QLatin1String("pkgName"), pkgName);
-+ return action.execute();
-+}
-+
-+KAuth::ExecuteJob *createRepoconfigAction(const QVariant &repoUrls)
-+{
-+ KAuth::Action action = createAlpineApkKAuthAction();
-+ if (!action.isValid()) {
-+ return nullptr;
-+ }
-+ // should be instant, writes few lines to /etc/apk/repositories
-+ action.setTimeout(1 * 60 * 1000); // 1 minute
-+ action.addArgument(QLatin1String("pkgAction"), QLatin1String("repoconfig"));
-+ action.addArgument(QLatin1String("repoList"), repoUrls);
-+ return action.execute();
-+}
-+
-+} // namespace ActionFactory
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkAuthActionFactory.h b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthActionFactory.h
-new file mode 100644
-index 00000000..ff5667f8
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkAuthActionFactory.h
-@@ -0,0 +1,41 @@
-+/***************************************************************************
-+ * Copyright © 2020 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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/>. *
-+ ***************************************************************************/
-+
-+#ifndef AlpineApkAuthActionFactory_H
-+#define AlpineApkAuthActionFactory_H
-+
-+#include <QString>
-+#include <QVariant>
-+
-+#include <KAuthAction>
-+#include <KAuthActionReply>
-+#include <KAuthExecuteJob>
-+
-+namespace ActionFactory {
-+
-+KAuth::ExecuteJob *createUpdateAction(const QString &fakeRoot);
-+KAuth::ExecuteJob *createUpgradeAction(bool onlySimulate = false);
-+KAuth::ExecuteJob *createAddAction(const QString &pkgName);
-+KAuth::ExecuteJob *createDelAction(const QString &pkgName);
-+KAuth::ExecuteJob *createRepoconfigAction(const QVariant &repoUrls);
-+
-+} // namespace ActionFactory
-+
-+#endif
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-index 28f08ef8..a126483a 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-@@ -19,6 +19,7 @@
- ***************************************************************************/
-
- #include "AlpineApkSourcesBackend.h"
-+#include "AlpineApkAuthActionFactory.h"
- #include "alpineapk_backend_logging.h" // generated by ECM
-
- #include <QDebug>
-@@ -27,7 +28,6 @@
-
- // KF5
- #include <KAuthExecuteJob>
--#include <kauth_version.h>
- #include <KLocalizedString>
-
- // libapk-qt
-@@ -100,28 +100,12 @@ void AlpineApkSourcesBackend::fillModelFromRepos()
-
- void AlpineApkSourcesBackend::saveSources()
- {
-- KAuth::Action repoConfigAction(QStringLiteral("org.kde.discover.alpineapkbackend.repoconfig"));
-- repoConfigAction.setHelperId(QStringLiteral("org.kde.discover.alpineapkbackend"));
-- if (!repoConfigAction.isValid()) {
-- qCWarning(LOG_ALPINEAPK) << "repoConfigAction is not valid!";
-- return;
-- }
--
-- repoConfigAction.setTimeout(1 * 60 * 1000); // 1 min
--#if KAUTH_VERSION < QT_VERSION_CHECK(5, 68, 0)
-- upgradeAction.setDetails(i18n("Configure repositories URLs"));
--#else
-- static const KAuth::Action::DetailsMap details{
-- { KAuth::Action::AuthDetail::DetailMessage, i18n("Configure repositories URLs") }
-- };
-- repoConfigAction.setDetailsV2(details);
--#endif
-- // pass in new repositories list
-- repoConfigAction.addArgument(QLatin1String("repoList"),
-- QVariant::fromValue<QVector<QtApk::Repository>>(m_repos));
-+ const QVariant repoUrls = QVariant::fromValue<QVector<QtApk::Repository>>(m_repos);
-
- // run with elevated privileges
-- KAuth::ExecuteJob *reply = repoConfigAction.execute();
-+ KAuth::ExecuteJob *reply = ActionFactory::createRepoconfigAction(repoUrls);
-+ if (!reply) return;
-+
- QObject::connect(reply, &KAuth::ExecuteJob::result, this, [this] (KJob *job) {
- KAuth::ExecuteJob *reply = static_cast<KAuth::ExecuteJob *>(job);
- if (reply->error() != 0) {
-@@ -142,7 +126,7 @@ void AlpineApkSourcesBackend::saveSources()
-
- void AlpineApkSourcesBackend::onItemChanged(QStandardItem *item)
- {
-- // update internal storage vector and relaod model from it
-+ // update internal storage vector and reload model from it
- // otherwise checks state are not updated in UI
- const Qt::CheckState cs = item->checkState();
- const QModelIndex idx = m_sourcesModel->indexFromItem(item);
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-index ffd44292..26bf1bd0 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkTransaction.cpp
-@@ -21,6 +21,7 @@
- #include "AlpineApkTransaction.h"
- #include "AlpineApkBackend.h"
- #include "AlpineApkResource.h"
-+#include "AlpineApkAuthActionFactory.h"
- #include "alpineapk_backend_logging.h" // generated by ECM
-
- // Qt
-@@ -29,7 +30,6 @@
-
- // KF5
- #include <KAuthExecuteJob>
--#include <kauth_version.h>
- #include <KLocalizedString>
-
- AlpineApkTransaction::AlpineApkTransaction(AlpineApkResource *res, Role role)
-@@ -61,42 +61,23 @@ void AlpineApkTransaction::cancel()
-
- void AlpineApkTransaction::startTransaction()
- {
-- KAuth::Action authAction;
-- QString actionDescription(i18n("Install package"));
-+ KAuth::ExecuteJob *reply = nullptr;
- switch(role()) {
- case InstallRole:
-- authAction.setName(QStringLiteral("org.kde.discover.alpineapkbackend.add"));
-+ reply = ActionFactory::createAddAction(m_resource->m_pkg.name);
- break;
- case RemoveRole:
-- authAction.setName(QStringLiteral("org.kde.discover.alpineapkbackend.del"));
-- actionDescription = i18n("Remove package");
-+ reply = ActionFactory::createDelAction(m_resource->m_pkg.name);
- break;
- case ChangeAddonsRole:
- qCWarning(LOG_ALPINEAPK) << "Addons are not supported by Alpine APK Backend!";
-- return;
- break;
- }
-- authAction.setHelperId(QStringLiteral("org.kde.discover.alpineapkbackend"));
-
-- if (!authAction.isValid()) {
-- qCWarning(LOG_ALPINEAPK) << "kauth addAction is not valid!";
-+ if (!reply) {
- return;
- }
-
-- authAction.setTimeout(60 * 60 * 1000); // 60 min
--#if KAUTH_VERSION < QT_VERSION_CHECK(5, 68, 0)
-- addAction.setDetails(actionDescription);
--#else
-- const KAuth::Action::DetailsMap details{
-- { KAuth::Action::AuthDetail::DetailMessage, actionDescription }
-- };
-- authAction.setDetailsV2(details);
--#endif
-- authAction.addArgument(QLatin1String("pkgName"), m_resource->m_pkg.name);
--
-- // run action with elevated privileges
-- KAuth::ExecuteJob *reply = authAction.execute();
--
- // get result of this job
- QObject::connect(reply, &KAuth::ExecuteJob::result, this, [this](KJob *job) {
- KAuth::ExecuteJob *reply = static_cast<KAuth::ExecuteJob *>(job);
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-index 677a784f..0bbbce1c 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-@@ -21,11 +21,11 @@
- #include "AlpineApkUpdater.h"
- #include "AlpineApkResource.h"
- #include "AlpineApkBackend.h"
-+#include "AlpineApkAuthActionFactory.h"
- #include "alpineapk_backend_logging.h"
- #include "utils.h"
-
- #include <KAuthExecuteJob>
--#include <kauth_version.h>
- #include <KLocalizedString>
-
- #include <QtApk>
-@@ -167,27 +167,10 @@ void AlpineApkUpdater::cancel()
- void AlpineApkUpdater::start()
- {
- qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-- KAuth::Action upgradeAction(QStringLiteral("org.kde.discover.alpineapkbackend.upgrade"));
-- upgradeAction.setHelperId(QStringLiteral("org.kde.discover.alpineapkbackend"));
--
-- if (!upgradeAction.isValid()) {
-- qCWarning(LOG_ALPINEAPK) << "kauth upgradeAction is not valid!";
-- return;
-- }
--
-- upgradeAction.setTimeout(30 * 60 * 1000); // 30 min
--#if KAUTH_VERSION < QT_VERSION_CHECK(5, 68, 0)
-- upgradeAction.setDetails(i18n("Upgrade currently installed packages"));
--#else
-- static const KAuth::Action::DetailsMap details{
-- { KAuth::Action::AuthDetail::DetailMessage, i18n("Upgrade currently installed packages") }
-- };
-- upgradeAction.setDetailsV2(details);
--#endif
-- // upgradeAction.addArgument(QLatin1String("onlySimulate"), true);
-
- // run upgrade with elevated privileges
-- KAuth::ExecuteJob *reply = upgradeAction.execute();
-+ KAuth::ExecuteJob *reply = ActionFactory::createUpgradeAction();
-+ if (!reply) return;
- QObject::connect(reply, &KAuth::ExecuteJob::result,
- this, &AlpineApkUpdater::handleKAuthUpgradeHelperReply);
-
-@@ -211,27 +194,11 @@ int AlpineApkUpdater::updatesCount()
- void AlpineApkUpdater::startCheckForUpdates()
- {
- QtApk::Database *db = m_backend->apkdb();
-- KAuth::Action updateAction(QStringLiteral("org.kde.discover.alpineapkbackend.update"));
-- updateAction.setHelperId(QStringLiteral("org.kde.discover.alpineapkbackend"));
-- if (!updateAction.isValid()) {
-- qCWarning(LOG_ALPINEAPK) << "kauth updateAction is not valid!";
-- return;
-- }
-- updateAction.setTimeout(60 * 1000); // 1 minute
-- // setDetails deprecated since KF 5.68, use setDetailsV2() with DetailsMap.
--#if KAUTH_VERSION < QT_VERSION_CHECK(5, 68, 0)
-- updateAction.setDetails(i18n("Update repositories index"));
--#else
-- static const KAuth::Action::DetailsMap details{
-- { KAuth::Action::AuthDetail::DetailMessage, i18n("Update repositories index") }
-- };
-- updateAction.setDetailsV2(details);
--#endif
-- updateAction.addArgument(QLatin1String("fakeRoot"), db->fakeRoot());
-
- // run updates check with elevated privileges to access
- // system package manager files
-- KAuth::ExecuteJob *reply = updateAction.execute();
-+ KAuth::ExecuteJob *reply = ActionFactory::createUpdateAction(db->fakeRoot());
-+ if (!reply) return;
- QObject::connect(reply, &KAuth::ExecuteJob::result,
- this, &AlpineApkUpdater::handleKAuthUpdateHelperReply);
- // qOverload is needed because of conflict with getter named percent()
-@@ -279,8 +246,8 @@ void AlpineApkUpdater::handleKAuthUpgradeHelperReply(KJob *job)
- if (reply->error() == 0) {
- QVariant pkgsV = replyData.value(QLatin1String("changes"));
- bool onlySimulate = replyData.value(QLatin1String("onlySimulate"), false).toBool();
-- qCDebug(LOG_ALPINEAPK) << "KAuth helper upgrade reply received, onlySimulate:" << onlySimulate;
- if (onlySimulate) {
-+ qCDebug(LOG_ALPINEAPK) << "KAuth helper upgrade reply received, simulation mode";
- QVector<QtApk::Package> pkgVector = pkgsV.value<QVector<QtApk::Package>>();
- qCDebug(LOG_ALPINEAPK) << " num changes:" << pkgVector.size();
- for (const QtApk::Package &pkg : pkgVector) {
-diff --git a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-index 9e3bd82c..7e54cfd9 100644
---- a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-+++ b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-@@ -1,6 +1,8 @@
- find_package(KF5Auth CONFIG REQUIRED) # Probably should be moved to top CMakeLists
-
- set(alpineapkbackend_SRCS
-+ AlpineApkAuthActionFactory.h
-+ AlpineApkAuthActionFactory.cpp
- AlpineApkBackend.cpp
- AlpineApkBackend.h
- AlpineApkResource.cpp
---
-GitLab
-
-
-From c3416800dbfa16dd35c24b5a8c77ea6ebe6e4b89 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Fri, 29 Jan 2021 12:00:56 +0300
-Subject: [PATCH 54/62] AlpineApkResource: add AppStream data setter
-
----
- libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp | 5 +++++
- libdiscover/backends/AlpineApkBackend/AlpineApkResource.h | 1 +
- 2 files changed, 6 insertions(+)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-index a6f4bc0f..8f493a49 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-@@ -285,6 +285,11 @@ bool AlpineApkResource::hasAppStreamData() const
- return !m_appsC.id().isEmpty();
- }
-
-+void AlpineApkResource::setAppStreamData(const AppStream::Component &component)
-+{
-+ m_appsC = component;
-+}
-+
- bool AlpineApkResource::canExecute() const
- {
- if (hasAppStreamData()) {
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-index e8948c46..5304a877 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.h
-@@ -73,6 +73,7 @@ public:
- void setAddons(const AddonList &addons);
- void setAddonInstalled(const QString &addon, bool installed);
- void setAvailableVersion(const QString &av);
-+ void setAppStreamData(const AppStream::Component &component);
-
- private:
- bool hasAppStreamData() const;
---
-GitLab
-
-
-From 85869f1ec60905ce436bd975cbf36c40c6072717 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Fri, 29 Jan 2021 12:11:51 +0300
-Subject: [PATCH 55/62] Add AppstreamDataDownloader class
-
----
- .../AppstreamDataDownloader.cpp | 303 ++++++++++++++++++
- .../AppstreamDataDownloader.h | 139 ++++++++
- .../backends/AlpineApkBackend/CMakeLists.txt | 2 +
- 3 files changed, 444 insertions(+)
- create mode 100644 libdiscover/backends/AlpineApkBackend/AppstreamDataDownloader.cpp
- create mode 100644 libdiscover/backends/AlpineApkBackend/AppstreamDataDownloader.h
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AppstreamDataDownloader.cpp b/libdiscover/backends/AlpineApkBackend/AppstreamDataDownloader.cpp
-new file mode 100644
-index 00000000..16587994
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AppstreamDataDownloader.cpp
-@@ -0,0 +1,303 @@
-+/***************************************************************************
-+ * Copyright © 2020 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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 <QDateTime>
-+#include <QDir>
-+#include <QEventLoop>
-+#include <QFile>
-+#include <QFileInfo>
-+#include <QJsonArray>
-+#include <QJsonDocument>
-+#include <QJsonParseError>
-+#include <QJsonObject>
-+#include <QNetworkAccessManager>
-+#include <QNetworkReply>
-+#include <QNetworkRequest>
-+#include <QStandardPaths>
-+#include <QThreadPool>
-+#include <QUrl>
-+#include <QtConcurrentRun>
-+
-+#include "AppstreamDataDownloader.h"
-+#include "alpineapk_backend_logging.h"
-+
-+namespace DiscoverVersion {
-+// contains static QLatin1String version("5.20.5"); definition
-+// autogenerated from top CMakeLists.txt
-+#include "../../../DiscoverVersion.h"
-+}
-+
-+#ifdef ALPINE_LINUX_BUILD
-+/**
-+ * @brief ApkAppstreamDataDownloader::getApkArch
-+ * Reads current configured system apk architecture
-+ * from "/etc/apk/arch" file.
-+ * @return "x86_64" / "armhf" / "armv7" / "aarch64" and so on
-+ */
-+static QString getApkArch()
-+{
-+ static QString s_retArch;
-+ if (!s_retArch.isEmpty()) {
-+ return s_retArch;
-+ }
-+ QFile archFile(QStringLiteral("/etc/apk/arch"));
-+ if (!archFile.open(QIODevice::ReadOnly)) {
-+ // TODO: we could try to guess at compile time by checking presence of
-+ // defines like __x86_64__ (check with: "gcc -march=native -dM -E - </dev/null")
-+ // but that seems like outside of scope of this small function
-+ return s_retArch;
-+ }
-+ s_retArch = QString::fromUtf8(archFile.readAll()).trimmed();
-+ archFile.close();
-+ return s_retArch;
-+}
-+
-+static inline void replaceCARCH(QString &in, const QString &arch)
-+{
-+ // URLs in JSON look like this:
-+ // https://appstream.alpinelinux.org/data/edge/main/Components-main-@CARCH@.xml.gz
-+ // we need to replace @CARCH@ with a real arch value
-+ in.replace(QLatin1String("@CARCH@"), arch);
-+}
-+#endif
-+
-+QString AppstreamDataDownloader::getAppStreamCacheDir()
-+{
-+ QString cachePath = QStandardPaths::writableLocation(QStandardPaths::CacheLocation);
-+ // ^^ "~/.cache/discover"
-+ cachePath += QStringLiteral("/appstream_data");
-+ QDir cacheDir(cachePath);
-+ if (!cacheDir.exists()) {
-+ const bool ok = cacheDir.mkpath(QStringLiteral("."));
-+ if (ok) {
-+ qCDebug(LOG_ALPINEAPK) << "Created appstream data cache dir:" << cachePath;
-+ } else {
-+ qCWarning(LOG_ALPINEAPK) << "Failed to create appstream data cache dir:" << cachePath;
-+ }
-+ }
-+ return cachePath;
-+}
-+
-+AppstreamDataDownloader::AppstreamDataDownloader(QObject *parent)
-+ : QObject(parent)
-+{
-+}
-+
-+void AppstreamDataDownloader::setCacheExpirePeriodSecs(qint64 secs)
-+{
-+ m_cacheExpireSeconds = secs;
-+}
-+
-+void AppstreamDataDownloader::loadUrlsJson(const QString &jsonPath)
-+{
-+ const QString jsonBaseName = QFileInfo(jsonPath).baseName();
-+ QFile jsonFile(jsonPath);
-+ if (!jsonFile.open(QIODevice::ReadOnly)) {
-+ qCWarning(LOG_ALPINEAPK) << "Failed to open JSON:" << jsonPath << "for reading!";
-+ Q_EMIT downloadFinished();
-+ return;
-+ }
-+ const QByteArray jsonBa = jsonFile.readAll();
-+ jsonFile.close();
-+
-+ QJsonParseError jsonError;
-+ const QJsonDocument jDoc = QJsonDocument::fromJson(jsonBa, &jsonError);
-+ if (jDoc.isNull()) {
-+ qCWarning(LOG_ALPINEAPK) << "Failed to parse JSON:" << jsonPath << "!";
-+ qCWarning(LOG_ALPINEAPK) << jsonError.errorString();
-+ Q_EMIT downloadFinished();
-+ return;
-+ }
-+ // JSON structure:
-+ // {
-+ // "urls": [
-+ // "https://...", "https://...", "https://..."
-+ // ]
-+ // }
-+ const QJsonObject rootObj = jDoc.object();
-+ const QJsonArray urls = rootObj.value(QLatin1String("urls")).toArray();
-+ for (const QJsonValue &urlValue : urls) {
-+ QString url = urlValue.toString();
-+#ifdef ALPINE_LINUX_BUILD
-+ replaceCARCH(url, getApkArch());
-+#endif
-+ m_urls.append(url);
-+ // prefixes are used to avoid name clashes with similar URL paths
-+ // from other JSON files. json file basename is used as prefix
-+ m_urlPrefixes.insert(url, jsonBaseName);
-+ }
-+}
-+
-+QString AppstreamDataDownloader::getLocalFileSavePath(const QUrl &urlToDownload)
-+{
-+ // we are adding a prefix here to local file name to avoid possible
-+ // file name clashes with files from other JSONs
-+ const QString urlPrefix = m_urlPrefixes.value(urlToDownload.toString(), QString());
-+ const QFileInfo urlInfo(urlToDownload.path());
-+ const QString localCacheFile = AppstreamDataDownloader::getAppStreamCacheDir()
-+ + QDir::separator()
-+ + urlPrefix + QLatin1Char('_')
-+ + urlInfo.fileName();
-+ // aka "~/.cache/discover/appstream_data/urlPrefix_fileName.xml.gz"
-+ return localCacheFile;
-+}
-+
-+void AppstreamDataDownloader::start()
-+{
-+ m_urls.clear();
-+ // load json files with appdata URLs configuration
-+ const QString path = QStandardPaths::locate(
-+ QStandardPaths::GenericDataLocation,
-+ QLatin1String("libdiscover/external-appstream-urls"),
-+ QStandardPaths::LocateDirectory);
-+ if (path.isEmpty()) {
-+ qCWarning(LOG_ALPINEAPK) << "external-appstream-urls directory does not exist.";
-+ return;
-+ }
-+
-+ QDir jsonsDir(path);
-+ // search for all JSON files in that directory and load each one
-+ QFileInfoList fileList = jsonsDir.entryInfoList({QStringLiteral("*.json")}, QDir::Files);
-+ for (const QFileInfo &fi : fileList) {
-+ qCDebug(LOG_ALPINEAPK) << " reading URLs JSON: " << fi.absoluteFilePath();
-+ loadUrlsJson(fi.absoluteFilePath());
-+ }
-+
-+ qCDebug(LOG_ALPINEAPK) << "appstream_downloader: urls:" << m_urls;
-+
-+ // check if download is needed at all, maybe all files are already up to date?
-+
-+ getAppStreamCacheDir(); // can create a cache dir if not exists
-+
-+ const QDateTime dtNow = QDateTime::currentDateTime();
-+ m_urlsToDownload.clear();
-+ for (const QString &url : m_urls) {
-+ const QUrl urlToDownload(url, QUrl::TolerantMode);
-+ const QString localCacheFile = getLocalFileSavePath(urlToDownload);
-+ const QFileInfo localFi(localCacheFile);
-+ if (localFi.exists()) {
-+ int modifiedSecsAgo = localFi.lastModified().secsTo(dtNow);
-+ if (modifiedSecsAgo >= m_cacheExpireSeconds) {
-+ m_urlsToDownload.append(url);
-+ }
-+ qCDebug(LOG_ALPINEAPK) << " appstream metadata file: " << localFi.fileName()
-+ << " was last modified " << modifiedSecsAgo << " seconds ago";
-+ } else {
-+ // locally downloaded file does not even exist, we need to download it
-+ m_urlsToDownload.append(url);
-+ qCDebug(LOG_ALPINEAPK) << " appstream metadata file: " << localFi.fileName()
-+ << " does not exist, queued for downloading";
-+ }
-+ }
-+
-+ if (m_urlsToDownload.size() > 0) {
-+ // some files are outdated; download is needed
-+ qCDebug(LOG_ALPINEAPK) << "appstream_downloader: We will need to download "
-+ << m_urlsToDownload.size() << " file(s)";
-+
-+ // start downloader in a background thread
-+ QFuture<void> downloaderFuture = QtConcurrent::run(
-+ QThreadPool::globalInstance(), this, &AppstreamDataDownloader::download);
-+
-+ // directly connect signal to signal
-+ QObject::connect(&m_voidFutureWatcher, &QFutureWatcher<void>::finished,
-+ this, &AppstreamDataDownloader::downloadFinished);
-+ m_voidFutureWatcher.setFuture(downloaderFuture);
-+ } else {
-+ // no need to download anything
-+ qCDebug(LOG_ALPINEAPK) << "appstream_downloader: All appstream data files "
-+ "are up to date, not downloading anything";
-+ Q_EMIT downloadFinished();
-+ return;
-+ }
-+}
-+
-+// this function runs in background thread
-+void AppstreamDataDownloader::download()
-+{
-+ QNetworkAccessManager nam;
-+ QList<QNetworkReply *> replies;
-+ QEventLoop loop;
-+
-+ // start a HTTP GET request for each URL
-+ const QStringList urls = m_urlsToDownload;
-+ const QString discoverVersion(QStringLiteral("plasma-discover %1").arg(DiscoverVersion::version));
-+ for (const QString &url : urls) {
-+ const QUrl uurl(url, QUrl::TolerantMode);
-+ QNetworkRequest req(uurl);
-+ req.setHeader(QNetworkRequest::UserAgentHeader, discoverVersion);
-+ replies.push_back(nam.get(req));
-+ }
-+
-+ for (QNetworkReply *rep : replies) {
-+ // lambda that stops the loop when all requests have finished
-+ // intentionaly use contextless lambda, it is not called otherwise
-+ QObject::connect(rep, &QNetworkReply::finished, [&loop, &replies, rep] () {
-+ const int numReplies = replies.size();
-+ int numFinished = 0;
-+ for (QNetworkReply *arep : replies) {
-+ if (arep->isFinished()) {
-+ numFinished++;
-+ }
-+ }
-+ if (numFinished >= numReplies) {
-+ loop.quit();
-+ }
-+ qCDebug(LOG_ALPINEAPK).nospace()
-+ << "appstream_downloader: " << rep->url()
-+ << " request finished (" << numFinished << "/" << numReplies << ")";
-+ });
-+ }
-+
-+ // wait for all requests to finish
-+ loop.exec();
-+
-+ qCDebug(LOG_ALPINEAPK) << "appstream_downloader: all downloads have finished!";
-+
-+ int numErrors = 0;
-+ for (QNetworkReply *rep : replies) {
-+ const QString localCacheFile = getLocalFileSavePath(rep->url());
-+
-+ if (rep->error() == QNetworkReply::NoError) {
-+ // read received reply contents and save it to file
-+ const QByteArray data = rep->readAll();
-+ QFile fout(localCacheFile);
-+ if (fout.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
-+ fout.write(data);
-+ fout.close();
-+ m_cacheWasUpdated = true;
-+ qCDebug(LOG_ALPINEAPK) << "appstream_downloader: saved: " << localCacheFile;
-+ } else {
-+ qCWarning(LOG_ALPINEAPK) << "appstream_downloader: failed to save:" << localCacheFile;
-+ }
-+ } else {
-+ // download failed for some reason
-+ QFileInfo urlinfo(rep->url().path());
-+ qCWarning(LOG_ALPINEAPK) << "appstream_downloader: failed to download"
-+ << urlinfo.fileName() << rep->errorString();
-+ numErrors++;
-+ }
-+ }
-+
-+ // cleanup: delete all replies objects
-+ for (QNetworkReply *arep : replies) {
-+ arep->deleteLater();
-+ }
-+}
-diff --git a/libdiscover/backends/AlpineApkBackend/AppstreamDataDownloader.h b/libdiscover/backends/AlpineApkBackend/AppstreamDataDownloader.h
-new file mode 100644
-index 00000000..05771982
---- /dev/null
-+++ b/libdiscover/backends/AlpineApkBackend/AppstreamDataDownloader.h
-@@ -0,0 +1,139 @@
-+/***************************************************************************
-+ * Copyright © 2020 Alexey Min <alexey.min@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 2 of *
-+ * the License or (at your option) version 3 or any later version *
-+ * accepted by the membership of KDE e.V. (or its successor approved *
-+ * by the membership of KDE e.V.), which shall act as a proxy *
-+ * defined in Section 14 of version 3 of the license. *
-+ * *
-+ * 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/>. *
-+ ***************************************************************************/
-+
-+#ifndef AlpineAppstreamDataDownloader_H
-+#define AlpineAppstreamDataDownloader_H
-+
-+#include <QFutureWatcher>
-+#include <QHash>
-+#include <QList>
-+#include <QObject>
-+#include <QString>
-+#include <QUrl>
-+
-+/**
-+ * @brief The AppstreamDataDownloader class
-+ *
-+ * @details The job of this class is to download appstream data
-+ * gzipped XMLs from the Web server hosted somewhere (for
-+ * Alpine Linux - at https://appstream.alpinelinux.org).
-+ *
-+ * Some distros (for example, Alpine Linux) do not provide
-+ * appstream data as installable package, instead they host it
-+ * on the internet and you have to download and install them
-+ * manually.
-+ *
-+ * Logic behind this decision is beyond my understanding, but we
-+ * have what we have... Those files are not very large (from few
-+ * kilobytes to couple of megabytes) but we still need them.
-+ *
-+ * URLs to download archives from are stored in JSON files in
-+ * /usr/share/libdiscover/external-appstream-urls/ directory
-+ * (QStandardPaths::GenericDataLocation/libdiscover/external-appstream-urls
-+ * from C++/Qt code, ${DATA_INSTALL_DIR}/libdiscover/external-appstream-urls
-+ * from cmake).
-+ *
-+ * JSON file format:
-+ * ---------------------
-+ * {
-+ * "urls": [ "https://url1", "https://url2", ... ]
-+ * }
-+ * ---------------------
-+ *
-+ * This class can load any amount of those JSON files,
-+ * fetch URLs from them and download all files pointed by
-+ * those URLs to discover's cache directory:
-+ * "~/.cache/discover/appstream_data" (aka QStandardPaths::CacheLocation).
-+ * If files are already present in cache and not outdated,
-+ * they are not downloaded again. Default cache expiration
-+ * time is 2 days.
-+ */
-+class AppstreamDataDownloader: public QObject
-+{
-+ Q_OBJECT
-+public:
-+ explicit AppstreamDataDownloader(QObject *parent = nullptr);
-+
-+ /**
-+ * @brief getAppstreamCacheDir
-+ * @details Use return value of this function to add extra metadata
-+ * directories to AppStream loader, in case of AppStreamQt:
-+ * AppStream::Pool::addMetadataLocation().
-+ * This method creates a cache dir if it does not exist.
-+ * @return directory where downloaded files are stored.
-+ */
-+ static QString getAppStreamCacheDir();
-+
-+ /**
-+ * @brief cacheWasUpdated
-+ * @details Call this after receiving downloadFinished() signal to
-+ * test if there actually was something new downloaded.
-+ *
-+ * @return true, if new files were actually downloaded, or
-+ * false is files already present in cache are up to date.
-+ */
-+ bool cacheWasUpdated() const { return m_cacheWasUpdated; }
-+
-+ /**
-+ * @brief getCacheExpirePeriodSecs
-+ * @return cache expire timeout in seconds
-+ */
-+ qint64 getCacheExpirePeriodSecs() const { return m_cacheExpireSeconds; }
-+
-+ /**
-+ * @brief setCacheExpirePeriodSecs
-+ * @param secs - new cache expiration timeout, in seconds.
-+ */
-+ void setCacheExpirePeriodSecs(qint64 secs);
-+
-+public Q_SLOTS:
-+ /**
-+ * @brief start
-+ * Start the background thread that does all the job.
-+ * downloadFinished() signal will be emitted when everything is done.
-+ * start() may finish immediately if all cached files are
-+ * up to date and no downloads are needed.
-+ */
-+ void start();
-+
-+Q_SIGNALS:
-+ /**
-+ * @brief downloadFinished
-+ * This signal is emitted when download job is finished.
-+ * To check if there were actual downloads performed, call
-+ * cacheWasUpdated().
-+ */
-+ void downloadFinished();
-+
-+private:
-+ QString getLocalFileSavePath(const QUrl &urlTodownload);
-+ void loadUrlsJson(const QString &path);
-+ void download();
-+
-+protected:
-+ qint64 m_cacheExpireSeconds = 2 * 24 * 3600; // 2 days
-+ QStringList m_urls;
-+ QStringList m_urlsToDownload;
-+ QHash<QString, QString> m_urlPrefixes;
-+ QFutureWatcher<void> m_voidFutureWatcher;
-+ bool m_cacheWasUpdated = false;
-+};
-+
-+#endif
-diff --git a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-index 7e54cfd9..8602dce7 100644
---- a/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-+++ b/libdiscover/backends/AlpineApkBackend/CMakeLists.txt
-@@ -15,6 +15,8 @@ set(alpineapkbackend_SRCS
- AlpineApkUpdater.h
- AlpineApkTransaction.cpp
- AlpineApkTransaction.h
-+ AppstreamDataDownloader.h
-+ AppstreamDataDownloader.cpp
- )
-
- ecm_qt_declare_logging_category(
---
-GitLab
-
-
-From 18d3bc729adc212c18364c86c5849fed83c29c16 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Fri, 29 Jan 2021 12:17:48 +0300
-Subject: [PATCH 56/62] AlpineApkBackend: use AppstreamDataDownloader
-
-Download AppStream data from external URLs after
-loading resources initially. Reload AppStream
-metadata after download has finished.
-
-Refactor resource loading process into several
-subroutines for easier understanding and code sharing.
----
- .../AlpineApkBackend/AlpineApkBackend.cpp | 166 +++++++++++++-----
- .../AlpineApkBackend/AlpineApkBackend.h | 10 +-
- 2 files changed, 131 insertions(+), 45 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index 8ddcc8e9..4bfe165b 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -24,6 +24,7 @@
- #include "AlpineApkTransaction.h"
- #include "AlpineApkSourcesBackend.h"
- #include "AlpineApkUpdater.h"
-+#include "AppstreamDataDownloader.h"
- #include "alpineapk_backend_logging.h" // generated by ECM
-
- #include "resources/SourcesModel.h"
-@@ -85,16 +86,19 @@ AlpineApkBackend::AlpineApkBackend(QObject *parent)
- SourcesModel::global()->addSourcesBackend(new AlpineApkSourcesBackend(this));
- }
-
--void AlpineApkBackend::loadResources()
-+// this fills in m_appStreamComponents
-+void AlpineApkBackend::loadAppStreamComponents()
- {
-- qCDebug(LOG_ALPINEAPK) << "backend: loading AppStream metadata...";
--
- AppStream::Pool *appStreamPool = new AppStream::Pool();
- appStreamPool->setFlags(AppStream::Pool::FlagReadCollection |
- AppStream::Pool::FlagReadMetainfo |
- AppStream::Pool::FlagReadDesktopFiles);
- appStreamPool->setCacheFlags(AppStream::Pool::CacheFlagUseUser |
- AppStream::Pool::CacheFlagUseSystem);
-+
-+ // hey hey! cool stuff
-+ appStreamPool->addMetadataLocation(AppstreamDataDownloader::getAppStreamCacheDir());
-+
- if (!appStreamPool->load()) {
- qCWarning(LOG_ALPINEAPK) << "backend: Failed to load appstream data:"
- << appStreamPool->lastError();
-@@ -103,36 +107,32 @@ void AlpineApkBackend::loadResources()
- qCDebug(LOG_ALPINEAPK) << "backend: loaded AppStream metadata OK:"
- << m_appStreamComponents.size() << "components.";
- // collect all categories present in appstream metadata
--// QSet<QString> collectedCategories;
--// for (const AppStream::Component &component : m_appStreamComponents) {
--// const QStringList cats = component.categories();
--// for (const QString &cat : cats) {
--// collectedCategories.insert(cat);
--// }
--// }
--// for (const QString &cat : collectedCategories) {
--// qCDebug(LOG_ALPINEAPK) << " collected category: " << cat;
--// m_collectedCategories << cat;
--// }
-+ // QSet<QString> collectedCategories;
-+ // for (const AppStream::Component &component : m_appStreamComponents) {
-+ // const QStringList cats = component.categories();
-+ // for (const QString &cat : cats) {
-+ // collectedCategories.insert(cat);
-+ // }
-+ // }
-+ // for (const QString &cat : collectedCategories) {
-+ // qCDebug(LOG_ALPINEAPK) << " collected category: " << cat;
-+ // m_collectedCategories << cat;
-+ // }
- }
- delete appStreamPool;
-- appStreamPool = nullptr;
--
-- qCDebug(LOG_ALPINEAPK) << "backend: populating resources...";
-- emit this->passiveMessage(i18n("Loading, please wait..."));
--
-- if (m_apkdb.open(QtApk::QTAPK_OPENF_READONLY)) {
-- m_availablePackages = m_apkdb.getAvailablePackages();
-- m_installedPackages = m_apkdb.getInstalledPackages();
-- m_apkdb.close();
-- }
-+}
-
-+// this uses m_appStreamComponents and m_availablePackages
-+// to fill in m_resourcesAppstreamData
-+void AlpineApkBackend::parseAppStreamMetadata()
-+{
- if (m_availablePackages.size() > 0) {
-- for (const QtApk::Package &pkg: m_availablePackages) {
-+
-+ for (const QtApk::Package &pkg: qAsConst(m_availablePackages)) {
-
- // try to find appstream data for this package
- AppStream::Component appstreamComponent;
-- for (const auto& appsC : m_appStreamComponents) {
-+ for (const auto& appsC : qAsConst(m_appStreamComponents)) {
- // find result which package name is exactly the one we want
- if (appsC.packageNames().contains(pkg.name)) {
- // workaround for kate (Kate Sessions is found first, but
-@@ -153,11 +153,6 @@ void AlpineApkBackend::loadResources()
- m_resourcesAppstreamData.insert(key, appstreamComponent);
- }
- }
--
-- qCDebug(LOG_ALPINEAPK) << " available" << m_availablePackages.size()
-- << "packages";
-- qCDebug(LOG_ALPINEAPK) << " installed" << m_installedPackages.size()
-- << "packages";
- }
-
- static AbstractResource::Type toDiscoverResourceType(const AppStream::Component &component)
-@@ -180,28 +175,81 @@ static AbstractResource::Type toDiscoverResourceType(const AppStream::Component
- return resType;
- }
-
--void AlpineApkBackend::onLoadResourcesFinished()
-+void AlpineApkBackend::fillResourcesAndApplyAppStreamData()
- {
-- qCDebug(LOG_ALPINEAPK) << "backend: appstream data loaded and sorted; fill in resources";
--
-+ // now the tricky part - we need to reapply appstream component metadata to each resource
- if (m_availablePackages.size() > 0) {
- for (const QtApk::Package &pkg: m_availablePackages) {
- const QString key = pkg.name.toLower();
-
-- AppStream::Component &appstreamComponent = m_resourcesAppstreamData[key];
-- const AbstractResource::Type resType = toDiscoverResourceType(appstreamComponent);
-+ AppStream::Component &appsComponent = m_resourcesAppstreamData[key];
-+ const AbstractResource::Type resType = toDiscoverResourceType(appsComponent);
-+
-+ AlpineApkResource *res = m_resources.value(key, nullptr);
-+ if (res == nullptr) {
-+ // during first run of this function during initial load
-+ // m_resources hash is empty, so we need to insert new items
-+ res = new AlpineApkResource(pkg, appsComponent, resType, this);
-+ res->setCategoryName(QStringLiteral("alpine_packages"));
-+ res->setOriginSource(QStringLiteral("apk"));
-+ res->setSection(QStringLiteral("dummy"));
-+ m_resources.insert(key, res);
-+ QObject::connect(res, &AlpineApkResource::stateChanged,
-+ this, &AlpineApkBackend::updatesCountChanged);
-+ } else {
-+ // this is not an initial run, just update existing resource
-+ res->setAppStreamData(appsComponent);
-+ }
-+ }
-+ }
-+}
-
-- AlpineApkResource *res = new AlpineApkResource(pkg, appstreamComponent, resType, this);
-- res->setCategoryName(QStringLiteral("alpine_packages"));
-- res->setOriginSource(QStringLiteral("apk"));
-- res->setSection(QStringLiteral("dummy"));
-+void AlpineApkBackend::reloadAppStreamMetadata()
-+{
-+ // mark us as "Loading..."
-+ m_fetching = true;
-+ emit fetchingChanged();
-
-- m_resources.insert(key, res);
-- QObject::connect(res, &AlpineApkResource::stateChanged,
-- this, &AlpineApkBackend::updatesCountChanged);
-- }
-+ loadAppStreamComponents();
-+ parseAppStreamMetadata();
-+ fillResourcesAndApplyAppStreamData();
-+
-+ // mark us as "done loading"
-+ m_fetching = false;
-+ emit fetchingChanged();
-+}
-+
-+// this function is executed in the background thread
-+void AlpineApkBackend::loadResources()
-+{
-+ Q_EMIT this->passiveMessage(i18n("Loading, please wait..."));
-+
-+ qCDebug(LOG_ALPINEAPK) << "backend: loading AppStream metadata...";
-+
-+ loadAppStreamComponents();
-+
-+ qCDebug(LOG_ALPINEAPK) << "backend: populating resources...";
-+
-+ if (m_apkdb.open(QtApk::QTAPK_OPENF_READONLY)) {
-+ m_availablePackages = m_apkdb.getAvailablePackages();
-+ m_installedPackages = m_apkdb.getInstalledPackages();
-+ m_apkdb.close();
- }
-
-+ parseAppStreamMetadata();
-+
-+ qCDebug(LOG_ALPINEAPK) << " available" << m_availablePackages.size()
-+ << "packages";
-+ qCDebug(LOG_ALPINEAPK) << " installed" << m_installedPackages.size()
-+ << "packages";
-+}
-+
-+void AlpineApkBackend::onLoadResourcesFinished()
-+{
-+ qCDebug(LOG_ALPINEAPK) << "backend: appstream data loaded and sorted; fill in resources";
-+
-+ fillResourcesAndApplyAppStreamData();
-+
- // update "installed/not installed" state
- if (m_installedPackages.size() > 0) {
- for (const QtApk::Package &pkg: m_installedPackages) {
-@@ -221,6 +269,36 @@ void AlpineApkBackend::onLoadResourcesFinished()
-
- // schedule check for updates 1 sec after we've loaded all resources
- QTimer::singleShot(1000, this, &AlpineApkBackend::checkForUpdates);
-+
-+ // AppStream appdata downloader can download updated metadata files
-+ // in a background thread. When potential download is finished,
-+ // appstream data will be reloaded.
-+ m_appstreamDownloader = new AppstreamDataDownloader(nullptr);
-+ QObject::connect(m_appstreamDownloader, &AppstreamDataDownloader::downloadFinished,
-+ this, &AlpineApkBackend::onAppstreamDataDownloaded, Qt::QueuedConnection);
-+ m_appstreamDownloader->start();
-+}
-+
-+void AlpineApkBackend::onAppstreamDataDownloaded()
-+{
-+ if (m_appstreamDownloader) {
-+ if (m_appstreamDownloader->cacheWasUpdated()) {
-+ // it means we need to reload previously loaded appstream metadata
-+ // m_fetching is true if loadResources() is still executing
-+ // in a background thread
-+ if (!m_fetching) {
-+ qCDebug(LOG_ALPINEAPK) << "AppStream metadata was updated; re-applying it to all resources";
-+ reloadAppStreamMetadata();
-+ } else {
-+ qCWarning(LOG_ALPINEAPK) << "AppStream metadata was updated, but cannot apply it: still fetching";
-+ // it should not really happen, but if it happens,
-+ // then downloaded metadata will be used on the next
-+ // discover launch anyway.
-+ }
-+ }
-+ delete m_appstreamDownloader;
-+ m_appstreamDownloader = nullptr;
-+ }
- }
-
- QVector<Category *> AlpineApkBackend::category() const
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-index 2ec8b00b..07b6b7be 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.h
-@@ -22,8 +22,9 @@
- #define AlpineApkBackend_H
-
- #include <resources/AbstractResourcesBackend.h>
--#include <QVariantList>
-+
- #include <QFutureWatcher>
-+#include <QVariantList>
-
- #include <QtApk>
-
-@@ -32,6 +33,7 @@
- class AlpineApkReviewsBackend;
- class AlpineApkUpdater;
- class AlpineApkResource;
-+class AppstreamDataDownloader;
- class KJob;
- class QTimer;
-
-@@ -66,8 +68,13 @@ public Q_SLOTS:
-
- private Q_SLOTS:
- void finishCheckForUpdates();
-+ void loadAppStreamComponents();
-+ void parseAppStreamMetadata();
-+ void reloadAppStreamMetadata();
-+ void fillResourcesAndApplyAppStreamData();
- void loadResources();
- void onLoadResourcesFinished();
-+ void onAppstreamDataDownloaded();
-
- public:
- QtApk::Database *apkdb() { return &m_apkdb; }
-@@ -86,6 +93,7 @@ private:
- QList<AppStream::Component> m_appStreamComponents;
- // QVector<QString> m_collectedCategories;
- QFutureWatcher<void> m_voidFutureWatcher;
-+ AppstreamDataDownloader *m_appstreamDownloader;
- };
-
- #endif // AlpineApkBackend_H
---
-GitLab
-
-
-From 3dd8723919afdf3c19e1e75d4a8c72dae98dc082 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Mon, 1 Feb 2021 14:24:25 +0300
-Subject: [PATCH 57/62] AlpineApkUpdater: fix progress reporting for system
- upgrade
-
-Connect to progress updates from helper and implement
-AlpineApkUpdater::progress() getter function.
----
- .../AlpineApkBackend/AlpineApkUpdater.cpp | 23 +++++++++++++++----
- .../AlpineApkBackend/AlpineApkUpdater.h | 3 ++-
- 2 files changed, 21 insertions(+), 5 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-index 0bbbce1c..30399369 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-@@ -91,8 +91,7 @@ bool AlpineApkUpdater::hasUpdates() const
-
- qreal AlpineApkUpdater::progress() const
- {
-- qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
-- return 0.0;
-+ return m_upgradeProgress;
- }
-
- void AlpineApkUpdater::removeResources(const QList<AbstractResource *> &apps)
-@@ -171,10 +170,15 @@ void AlpineApkUpdater::start()
- // run upgrade with elevated privileges
- KAuth::ExecuteJob *reply = ActionFactory::createUpgradeAction();
- if (!reply) return;
-+
- QObject::connect(reply, &KAuth::ExecuteJob::result,
- this, &AlpineApkUpdater::handleKAuthUpgradeHelperReply);
-+ // qOverload is needed because of conflict with getter named percent()
-+ QObject::connect(reply, QOverload<KJob *, unsigned long>::of(&KAuth::ExecuteJob::percent),
-+ this, &AlpineApkUpdater::handleKAuthUpgradeHelperProgress);
-
- m_progressing = true;
-+ m_upgradeProgress = 0.0;
- Q_EMIT progressingChanged(m_progressing);
-
- reply->start();
-@@ -239,6 +243,17 @@ void AlpineApkUpdater::handleKAuthUpdateHelperProgress(KJob *job, unsigned long
- Q_EMIT progressChanged(static_cast<qreal>(percent));
- }
-
-+void AlpineApkUpdater::handleKAuthUpgradeHelperProgress(KJob *job, unsigned long percent)
-+{
-+ Q_UNUSED(job)
-+ qCDebug(LOG_ALPINEAPK) << " upgrade progress: " << percent;
-+ qreal newProgress = static_cast<qreal>(percent);
-+ if (newProgress != m_upgradeProgress) {
-+ m_upgradeProgress = newProgress;
-+ Q_EMIT progressChanged(m_upgradeProgress);
-+ }
-+}
-+
- void AlpineApkUpdater::handleKAuthUpgradeHelperReply(KJob *job)
- {
- KAuth::ExecuteJob *reply = static_cast<KAuth::ExecuteJob *>(job);
-@@ -258,8 +273,8 @@ void AlpineApkUpdater::handleKAuthUpgradeHelperReply(KJob *job)
- handleKAuthHelperError(reply, replyData);
- }
-
-- // we are not in the state "Fetching updates" now, update UI
-- Q_EMIT checkForUpdatesFinished();
-+ m_progressing = false;
-+ Q_EMIT progressingChanged(m_progressing);
- }
-
- void AlpineApkUpdater::handleKAuthHelperError(
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h
-index 0ee2fcb4..6ca3ce07 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.h
-@@ -159,6 +159,7 @@ public Q_SLOTS:
- void handleKAuthUpdateHelperProgress(KJob *job, unsigned long percent);
- // upgrade
- void handleKAuthUpgradeHelperReply(KJob *job);
-+ void handleKAuthUpgradeHelperProgress(KJob *job, unsigned long percent);
-
- //void transactionRemoved(Transaction* t);
- //void cleanup();
-@@ -186,7 +187,7 @@ private:
- // QSet<AbstractResource*> m_upgradeable;
- // QSet<AbstractResource*> m_pendingResources;
- bool m_progressing = false;
--// qreal m_progress;
-+ qreal m_upgradeProgress = 0.0;
- // QDateTime m_lastUpdate;
- // QTimer m_timer;
- // bool m_canCancel = false;
---
-GitLab
-
-
-From 92f4a2bf194c8bee7002f880eafa2e08b0f32ba7 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Mon, 1 Feb 2021 14:26:29 +0300
-Subject: [PATCH 58/62] AlpineApkUpdater: remove useless debug prints and
- comments
-
----
- .../backends/AlpineApkBackend/AlpineApkUpdater.cpp | 8 --------
- 1 file changed, 8 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-index 30399369..14df959c 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkUpdater.cpp
-@@ -40,8 +40,6 @@ AlpineApkUpdater::AlpineApkUpdater(AbstractResourcesBackend *parent)
-
- void AlpineApkUpdater::prepare()
- {
-- qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
--
- QtApk::Database *db = m_backend->apkdb();
-
- if (db->isOpen()) {
-@@ -85,7 +83,6 @@ void AlpineApkUpdater::prepare()
-
- bool AlpineApkUpdater::hasUpdates() const
- {
-- // qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO << m_updatesCount;
- return (m_updatesCount > 0);
- }
-
-@@ -96,22 +93,18 @@ qreal AlpineApkUpdater::progress() const
-
- void AlpineApkUpdater::removeResources(const QList<AbstractResource *> &apps)
- {
-- // qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
- const QSet<AbstractResource *> checkSet = kToSet(apps);
- m_markedToUpdate -= checkSet;
- }
-
- void AlpineApkUpdater::addResources(const QList<AbstractResource *> &apps)
- {
-- //Q_UNUSED(apps)
-- //qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
- const QSet<AbstractResource *> checkSet = kToSet(apps);
- m_markedToUpdate += checkSet;
- }
-
- QList<AbstractResource *> AlpineApkUpdater::toUpdate() const
- {
-- // qCDebug(LOG_ALPINEAPK) << Q_FUNC_INFO;
- return m_allUpdateable.values();
- }
-
-@@ -191,7 +184,6 @@ void AlpineApkUpdater::proceed()
-
- int AlpineApkUpdater::updatesCount()
- {
-- // qDebug(LOG_ALPINEAPK) << Q_FUNC_INFO << m_updatesCount;
- return m_updatesCount;
- }
-
---
-GitLab
-
-
-From b545c0833c9032abf671e3519216ed24e67b74b8 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Wed, 24 Feb 2021 14:51:27 +0300
-Subject: [PATCH 59/62] AlpineApkSourcesBackend: port away from QAction
-
-follow-up to 4bf3f59adb82e2ef38df98073ee39e6d20e56921
----
- .../AlpineApkBackend/AlpineApkSourcesBackend.cpp | 14 ++++++++------
- .../AlpineApkBackend/AlpineApkSourcesBackend.h | 9 ++++++---
- 2 files changed, 14 insertions(+), 9 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-index a126483a..3db9e607 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.cpp
-@@ -18,6 +18,8 @@
- * along with this program. If not, see <http://www.gnu.org/licenses/>. *
- ***************************************************************************/
-
-+#include "resources/DiscoverAction.h"
-+
- #include "AlpineApkSourcesBackend.h"
- #include "AlpineApkAuthActionFactory.h"
- #include "alpineapk_backend_logging.h" // generated by ECM
-@@ -36,16 +38,16 @@
- AlpineApkSourcesBackend::AlpineApkSourcesBackend(AbstractResourcesBackend *parent)
- : AbstractSourcesBackend(parent)
- , m_sourcesModel(new QStandardItemModel(this))
-- , m_refreshAction(new QAction(QIcon::fromTheme(QStringLiteral("view-refresh")),
-- QStringLiteral("Reload"), this))
-- , m_saveAction(new QAction(QIcon::fromTheme(QStringLiteral("document-save")),
-- QStringLiteral("Save"), this))
-+ , m_refreshAction(new DiscoverAction(QIcon::fromTheme(QStringLiteral("view-refresh")),
-+ QStringLiteral("Reload"), this))
-+ , m_saveAction(new DiscoverAction(QIcon::fromTheme(QStringLiteral("document-save")),
-+ QStringLiteral("Save"), this))
- // ^^ unfortunately QML side ignores icons for custom actions
- {
- loadSources();
-- QObject::connect(m_refreshAction, &QAction::triggered,
-+ QObject::connect(m_refreshAction, &DiscoverAction::triggered,
- this, &AlpineApkSourcesBackend::loadSources);
-- QObject::connect(m_saveAction, &QAction::triggered,
-+ QObject::connect(m_saveAction, &DiscoverAction::triggered,
- this, &AlpineApkSourcesBackend::saveSources);
- // track enabling/disabling repo source
- QObject::connect(m_sourcesModel, &QStandardItemModel::itemChanged,
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h
-index eacda22d..c655d3d1 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkSourcesBackend.h
-@@ -21,11 +21,14 @@
- #ifndef ALPINEAPKSOURCESBACKEND_H
- #define ALPINEAPKSOURCESBACKEND_H
-
--#include <resources/AbstractSourcesBackend.h>
-+#include "resources/AbstractSourcesBackend.h"
-+
- #include <QStandardItemModel>
-
- #include <QtApkRepository.h>
-
-+class DiscoverAction;
-+
- class AlpineApkSourcesBackend : public AbstractSourcesBackend
- {
- public:
-@@ -49,8 +52,8 @@ private:
- void onItemChanged(QStandardItem* item);
-
- QStandardItemModel *m_sourcesModel = nullptr;
-- QAction *m_refreshAction = nullptr;
-- QAction *m_saveAction = nullptr;
-+ DiscoverAction *m_refreshAction = nullptr;
-+ DiscoverAction *m_saveAction = nullptr;
- QVector<QtApk::Repository> m_repos;
- };
-
---
-GitLab
-
-
-From 9becc1e6738c0ce5f562ab39128d56e65d3b43b9 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Thu, 25 Feb 2021 07:39:50 +0300
-Subject: [PATCH 60/62] Use shorter backend name: it's now used in Install
- button
-
-See https://invent.kde.org/plasma/discover/-/commit/
-ce89d530de3414f25bb4b48a1933a52bf37be922
----
- libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-index 4bfe165b..f40fc355 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkBackend.cpp
-@@ -485,7 +485,7 @@ void AlpineApkBackend::finishCheckForUpdates()
-
- QString AlpineApkBackend::displayName() const
- {
-- return i18nc("Backend plugin display name", "Alpine APK backend");
-+ return i18nc("Backend plugin display name", "Alpine APK");
- }
-
- bool AlpineApkBackend::hasApplications() const
---
-GitLab
-
-
-From dc889612ab753018fa634c588220fd7cff4e2775 Mon Sep 17 00:00:00 2001
-From: Alexey Min <alexey.min@gmail.com>
-Date: Thu, 25 Feb 2021 07:40:41 +0300
-Subject: [PATCH 61/62] AlpineApkResource: use Alpine Linux logo for backend
- logo
-
----
- libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-index 8f493a49..45934706 100644
---- a/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-+++ b/libdiscover/backends/AlpineApkBackend/AlpineApkResource.cpp
-@@ -325,7 +325,7 @@ QString AlpineApkResource::author() const
-
- QString AlpineApkResource::sourceIcon() const
- {
-- return QStringLiteral("player-time");
-+ return QStringLiteral("alpine-linux-logo-icon");
- }
-
- QDate AlpineApkResource::releaseDate() const
---
-GitLab
-
-
-From 9af13ac3ed6ae302b51ab08eced5db959afaac7d Mon Sep 17 00:00:00 2001
-From: Alexey Minnekhanov <alexeymin@postmarketos.org>
-Date: Sat, 15 May 2021 05:52:54 +0300
-Subject: [PATCH 62/62] KAuth helper: don't ask for password
-
-Allow everyone to install/remove/upgrade packages without asking
-for password. Polkit-kde auth dialog is not mobile friendly.
-
-Fixes https://gitlab.com/postmarketOS/pmaports/-/issues/1036
----
- .../org.kde.discover.alpineapkbackend.actions | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-index c9bb5f9f..f9db78db 100644
---- a/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-+++ b/libdiscover/backends/AlpineApkBackend/org.kde.discover.alpineapkbackend.actions
-@@ -1,5 +1,5 @@
- [org.kde.discover.alpineapkbackend.pkgmgmt]
- Name=Package management
--Description=Install or remove packages, upgrade system
--Policy=auth_admin
-+Description=Install/remove/upgrade packages
-+Policy=yes
- Persistence=session
---
-GitLab
-