summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleix Pol <aleixpol@kde.org>2016-10-25 23:37:19 (GMT)
committerAleix Pol <aleixpol@kde.org>2016-10-25 23:37:19 (GMT)
commite42560d53d8ebe3d5fa910129ee07ebc6483db64 (patch)
treeb1dafcd1ab5773afce874c194f38da4ac4cccd2f
parent7fca278dae7696e1975cc61a03e4a99240fcd0a8 (diff)
Remove QApt backend
Even Kubuntu moved to PackageKit by nowadays, no need to keep it around, will make it possible to clean some API. RIP
-rw-r--r--CMakeLists.txt7
-rw-r--r--libdiscover/backends/ApplicationBackend/Application.cpp546
-rw-r--r--libdiscover/backends/ApplicationBackend/Application.h114
-rw-r--r--libdiscover/backends/ApplicationBackend/ApplicationBackend.cpp676
-rw-r--r--libdiscover/backends/ApplicationBackend/ApplicationBackend.h128
-rw-r--r--libdiscover/backends/ApplicationBackend/ApplicationNotifier.cpp172
-rw-r--r--libdiscover/backends/ApplicationBackend/ApplicationNotifier.h60
-rw-r--r--libdiscover/backends/ApplicationBackend/ApplicationUpdates.cpp467
-rw-r--r--libdiscover/backends/ApplicationBackend/ApplicationUpdates.h97
-rw-r--r--libdiscover/backends/ApplicationBackend/AptSourcesBackend.cpp244
-rw-r--r--libdiscover/backends/ApplicationBackend/AptSourcesBackend.h60
-rw-r--r--libdiscover/backends/ApplicationBackend/CMakeLists.txt53
-rw-r--r--libdiscover/backends/ApplicationBackend/ReviewsBackend.cpp411
-rw-r--r--libdiscover/backends/ApplicationBackend/ReviewsBackend.h105
-rw-r--r--libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.cpp147
-rw-r--r--libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.h57
-rw-r--r--libdiscover/backends/ApplicationBackend/distupgradeevent/releasechecker46
-rw-r--r--libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.cpp41
-rw-r--r--libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.h15
-rw-r--r--libdiscover/backends/ApplicationBackend/libmuonapt/CMakeLists.txt26
-rw-r--r--libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.cpp118
-rw-r--r--libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.h45
-rw-r--r--libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.cpp85
-rw-r--r--libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.h52
-rw-r--r--libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.cpp238
-rw-r--r--libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.h79
-rw-r--r--libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.cpp167
-rw-r--r--libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.h56
-rw-r--r--libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.cpp537
-rw-r--r--libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.h110
-rw-r--r--libdiscover/backends/ApplicationBackend/libmuonapt/policies/org.kde.muon.repo.action5
-rw-r--r--libdiscover/backends/ApplicationBackend/muonapplicationnotifier.notifyrc109
-rw-r--r--libdiscover/backends/ApplicationBackend/qapt-backend-categories.xml559
-rw-r--r--libdiscover/backends/ApplicationBackend/qapt-backend.desktop111
-rw-r--r--libdiscover/backends/ApplicationBackend/qoauth/CMakeLists.txt5
-rw-r--r--libdiscover/backends/ApplicationBackend/qoauth/src/interface.cpp1084
-rw-r--r--libdiscover/backends/ApplicationBackend/qoauth/src/interface.h119
-rw-r--r--libdiscover/backends/ApplicationBackend/qoauth/src/interface_p.h127
-rw-r--r--libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_global.h39
-rw-r--r--libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_namespace.h180
-rw-r--r--libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.cpp154
-rw-r--r--libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.h45
-rw-r--r--libdiscover/backends/ApplicationBackend/tests/CMakeLists.txt13
-rw-r--r--libdiscover/backends/ApplicationBackend/tests/NotifierTest.cpp41
-rw-r--r--libdiscover/backends/ApplicationBackend/tests/NotifierTest.h37
-rw-r--r--libdiscover/backends/ApplicationBackend/tests/ReviewsTest.cpp90
-rw-r--r--libdiscover/backends/ApplicationBackend/tests/ReviewsTest.h52
-rw-r--r--libdiscover/backends/ApplicationBackend/tests/SourcesTest.cpp101
-rw-r--r--libdiscover/backends/ApplicationBackend/tests/SourcesTest.h48
-rw-r--r--libdiscover/backends/ApplicationBackend/tests/popcontestratings.txtbin111487 -> 0 bytes
-rw-r--r--libdiscover/backends/ApplicationBackend/tests/rnrtestratings.txt6253
-rw-r--r--libdiscover/backends/ApplicationBackend/ubuntu_sso_dbus_interface.xml73
-rw-r--r--libdiscover/backends/CMakeLists.txt8
53 files changed, 0 insertions, 14212 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c367c76..af87809 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -21,13 +21,6 @@ find_package(KF5 5.24 REQUIRED CoreAddons Config Crash DBusAddons I18n Archive D
find_package(KF5Kirigami 1.1)
find_package(packagekitqt5)
-if (NOT packagekitqt5_FOUND)
- find_package(QApt 3.0.0)
- if(QApt_FOUND)
- find_package(DebconfKDE 1.0.0 REQUIRED)
- find_package(KF5 REQUIRED IconThemes Notifications KIO)
- endif()
-endif()
find_package(AppstreamQt 0.10)
find_package(KF5Attica 5.23)
find_package(KF5NewStuff 5.23)
diff --git a/libdiscover/backends/ApplicationBackend/Application.cpp b/libdiscover/backends/ApplicationBackend/Application.cpp
deleted file mode 100644
index ae1d95e..0000000
--- a/libdiscover/backends/ApplicationBackend/Application.cpp
+++ /dev/null
@@ -1,546 +0,0 @@
-/***************************************************************************
- * Copyright © 2010-2011 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 "Application.h"
-
-// Qt includes
-#include <QFile>
-#include <QJsonDocument>
-#include <QStandardPaths>
-#include <QStringList>
-#include <QThread>
-#include <QIcon>
-#include <QVector>
-
-// KDE includes
-#include <KIconLoader>
-#include <KService>
-#include <KServiceGroup>
-#include <KToolInvocation>
-#include <KLocalizedString>
-#include <KIO/Job>
-#include <KConfigGroup>
-#include <KFormat>
-
-// QApt includes
-#include <QApt/Backend>
-#include <QApt/Config>
-#include <QApt/Changelog>
-#include <qapt/qaptversion.h>
-
-#include <MuonDataSources.h>
-
-#include "ApplicationBackend.h"
-#include "resources/PackageState.h"
-
-Application::Application(const Appstream::Component &component, QApt::Backend* backend)
- : AbstractResource(nullptr)
- , m_data(component)
- , m_package(nullptr)
- , m_isValid(true)
- , m_isTechnical(component.kind() != Appstream::Component::KindDesktop)
- , m_isExtrasApp(false)
- , m_sourceHasScreenshot(true)
-{
- static QByteArray currentDesktop = qgetenv("XDG_CURRENT_DESKTOP");
-
- Q_ASSERT(component.packageNames().count() == 1);
- if (!component.packageNames().isEmpty())
- m_packageName = component.packageNames().at(0);
-
- m_package = backend->package(packageName());
- m_isValid = bool(m_package);
-}
-
-Application::Application(QApt::Package* package, QApt::Backend* backend)
- : AbstractResource(nullptr)
- , m_package(package)
- , m_packageName(m_package->name())
- , m_isValid(true)
- , m_isTechnical(true)
- , m_isExtrasApp(false)
-{
- QString arch = m_package->architecture();
- if (arch != backend->nativeArchitecture() && arch != QLatin1String("all")) {
- m_packageName.append(QLatin1Char(':'));
- m_packageName.append(arch);
- }
-
- if (m_package->origin() == QLatin1String("LP-PPA-app-review-board")) {
- if (!m_package->controlField(QLatin1String("Appname")).isEmpty()) {
- m_isExtrasApp = true;
- m_isTechnical = false;
- }
- }
-}
-
-QString Application::name()
-{
- QString name = m_data.isValid() ? m_data.name() : QString();
- if (name.isEmpty() && package()) {
- // extras.ubuntu.com packages can have this
- if (m_isExtrasApp)
- name = m_package->controlField(QLatin1String("Appname"));
- else
- name = m_package->name();
- }
-
- if (package() && m_package->isForeignArch())
- name = i18n("%1 (%2)", name, m_package->architecture());
-
- return name;
-}
-
-QString Application::comment()
-{
- QString comment = m_data.isValid() ? m_data.summary() : QString();
- if (comment.isEmpty()) {
- return package()->shortDescription();
- }
-
- return i18n(comment.toUtf8().constData());
-}
-
-QString Application::packageName() const
-{
- return m_packageName;
-}
-
-QApt::Package *Application::package()
-{
- if (!m_package && parent()) {
- m_package = backend()->package(packageName());
- Q_EMIT stateChanged();
- }
-
- // Packages removed from archive will remain in app-install-data until the
- // next refresh, so we can have valid .desktops with no package
- if (!m_package) {
- m_isValid = false;
- }
-
- return m_package;
-}
-
-QVariant Application::icon() const
-{
- QIcon ret;
-
- const auto icons = m_appdata.iconUrls();
- if (icons.isEmpty())
- return m_appdata.name();
- else {
- for (auto it = icons.constBegin(), itEnd = icons.constEnd(); it!=itEnd; ++it) {
- if (it->isLocalFile())
- ret.addFile(it->toLocalFile(), it.key());
- }
- }
- return ret;
-}
-
-QStringList Application::findProvides(Appstream::Provides::Kind kind) const
-{
- QStringList ret;
- Q_FOREACH (Appstream::Provides p, m_data.provides())
- if (p.kind() == kind)
- ret += p.value();
- return ret;
-}
-
-QStringList Application::mimetypes() const
-{
- return findProvides(Appstream::Provides::KindMimetype);
-}
-
-QStringList Application::categories()
-{
- QStringList categories = m_data.isValid() ? m_data.categories() : QStringList();
-
- if (categories.isEmpty()) {
- // extras.ubuntu.com packages can have this field
- if (m_isExtrasApp)
- categories = package()->controlField(QLatin1String("Category")).split(QLatin1Char(';'));
- }
- return categories;
-}
-
-QUrl Application::thumbnailUrl()
-{
- QUrl url(package()->controlField(QLatin1String("Thumbnail-Url")));
- if(m_sourceHasScreenshot) {
- url = QUrl(MuonDataSources::screenshotsSource().toString() + QStringLiteral("/thumbnail/") + packageName());
- }
- return url;
-}
-
-QUrl Application::screenshotUrl()
-{
- QUrl url(package()->controlField(QLatin1String("Screenshot-Url")));
- if(m_sourceHasScreenshot) {
- url = QUrl(MuonDataSources::screenshotsSource().toString() + QStringLiteral("/screenshot/") + packageName());
- }
- return url;
-}
-
-QString Application::license()
-{
- QString component = package()->component();
- if (component == QLatin1String("main") || component == QLatin1String("universe")) {
- return i18nc("@info license", "Open Source");
- } else if (component == QLatin1String("restricted")) {
- return i18nc("@info license", "Proprietary");
- } else {
- return i18nc("@info license", "Unknown");
- }
-}
-
-QApt::PackageList Application::addons()
-{
- QApt::PackageList addons;
-
- QApt::Package *pkg = package();
- if (!pkg) {
- return addons;
- }
-
- QStringList tempList;
- // Only add recommends or suggests to the list if they aren't already going to be
- // installed
- if (!backend()->config()->readEntry(QStringLiteral("APT::Install-Recommends"), true)) {
- tempList << m_package->recommendsList();
- }
- if (!backend()->config()->readEntry(QStringLiteral("APT::Install-Suggests"), false)) {
- tempList << m_package->suggestsList();
- }
- tempList << m_package->enhancedByList();
-
- QStringList languagePackages;
- QFile l10nFilterFile(QStringLiteral("/usr/share/language-selector/data/pkg_depends"));
-
- if (l10nFilterFile.open(QFile::ReadOnly)) {
- QString contents = QString::fromLatin1(l10nFilterFile.readAll());
-
- foreach (const QString &line, contents.split(QLatin1Char('\n'))) {
- if (line.startsWith(QLatin1Char('#'))) {
- continue;
- }
- languagePackages << line.split(QLatin1Char(':')).last();
- }
-
- languagePackages.removeAll(QString());
- }
-
- foreach (const QString &addon, tempList) {
- bool shouldShow = true;
- QApt::Package *package = backend()->package(addon);
-
- if (!package || QString(package->section()).contains(QLatin1String("lib")) || addons.contains(package)) {
- continue;
- }
-
- foreach (const QString &langpack, languagePackages) {
- if (addon.contains(langpack)) {
- shouldShow = false;
- break;
- }
- }
-
- if (shouldShow) {
- addons << package;
- }
- }
-
- return addons;
-}
-
-QList<PackageState> Application::addonsInformation()
-{
- QList<PackageState> ret;
- QApt::PackageList pkgs = addons();
- foreach(QApt::Package* p, pkgs) {
- ret += PackageState(p->name(), p->shortDescription(), p->isInstalled());
- }
- return ret;
-}
-
-bool Application::isValid() const
-{
- return m_isValid;
-}
-
-bool Application::isTechnical() const
-{
- return m_isTechnical;
-}
-
-QUrl Application::homepage()
-{
- if(!m_package) return QUrl();
- return QUrl(m_package->homepage());
-}
-
-QString Application::origin() const
-{
- if(!m_package) return QString();
- return m_package->origin();
-}
-
-QString Application::longDescription()
-{
- const QString comment = m_data.isValid() ? m_data.description() : QString();
- if(!comment.isEmpty()) return comment;
- if(m_package) return QString();
- return m_package->longDescription();
-}
-
-QString Application::availableVersion() const
-{
- if(!m_package) return QString();
- return m_package->availableVersion();
-}
-
-QString Application::installedVersion() const
-{
- if(!m_package) return QString();
- return m_package->installedVersion();
-}
-
-QString Application::sizeDescription()
-{
- KFormat f;
- if (!isInstalled()) {
- return i18nc("@info app size", "%1 to download, %2 on disk",
- f.formatByteSize(package()->downloadSize()),
- f.formatByteSize(package()->availableInstalledSize()));
- } else {
- return i18nc("@info app size", "%1 on disk",
- f.formatByteSize(package()->currentInstalledSize()));
- }
-}
-
-int Application::size()
-{
- return m_package->downloadSize();
-}
-
-void Application::clearPackage()
-{
- m_package = nullptr;
-}
-
-QVector<KService::Ptr> Application::findExecutables() const
-{
- QVector<KService::Ptr> ret;
- if (!m_package) {
- qWarning() << "trying to find the executables for an uninitialized package!" << packageName();
- return ret;
- }
-
- QRegExp rx(QStringLiteral(".+\\.desktop$"), Qt::CaseSensitive);
- foreach (const QString &desktop, m_package->installedFilesList().filter(rx)) {
- // Important to use serviceByStorageId to ensure we get a service even
- // if the KSycoca database doesn't have our .desktop file yet.
- KService::Ptr service = KService::serviceByStorageId(desktop);
- if (service &&
- service->isApplication() &&
- !service->noDisplay() &&
- !service->exec().isEmpty())
- {
- ret << service;
- }
- }
- return ret;
-}
-
-void Application::emitStateChanged()
-{
- emit stateChanged();
-}
-
-void Application::invokeApplication() const
-{
- QVector< KService::Ptr > execs = findExecutables();
- Q_ASSERT(!execs.isEmpty());
- KToolInvocation::startServiceByDesktopName(execs.first()->desktopEntryName());
-}
-
-bool Application::canExecute() const
-{
- return !findExecutables().isEmpty();
-}
-
-QString Application::section()
-{
- return package()->section();
-}
-
-AbstractResource::State Application::state()
-{
- if (!package())
- return Broken;
-
- int s = package()->state();
-
- if (s & QApt::Package::Upgradeable) {
-#if QAPT_VERSION >= QT_VERSION_CHECK(3, 1, 0)
- if (package()->isInUpdatePhase())
- return Upgradeable;
-#else
- return Upgradeable;
-#endif
- }
-
- if (s & QApt::Package::Installed) {
- return Installed;
- }
-
- return None; // Actually: none of interest to us here in plasma-discover.
-}
-
-void Application::fetchScreenshots()
-{
- if(!m_sourceHasScreenshot)
- return;
-
- QString dest = QStandardPaths::locate(QStandardPaths::TempLocation, QStringLiteral("screenshots.")+m_packageName);
- const QUrl packageUrl(MuonDataSources::screenshotsSource().toString() + QStringLiteral("/json/package/")+m_packageName);
- KIO::StoredTransferJob* job = KIO::storedGet(packageUrl, KIO::NoReload, KIO::HideProgressInfo);
- connect(job, &KIO::StoredTransferJob::finished, this, &Application::downloadingScreenshotsFinished);
-}
-
-void Application::downloadingScreenshotsFinished(KJob* j)
-{
- KIO::StoredTransferJob* job = qobject_cast< KIO::StoredTransferJob* >(j);
- bool done = false;
- if(job) {
- QJsonParseError error;
- QJsonDocument doc = QJsonDocument::fromJson(job->data(), &error);
- if(error.error != QJsonParseError::NoError) {
- QVariantMap values = doc.toVariant().toMap();
- QVariantList screenshots = values[QStringLiteral("screenshots")].toList();
-
- QList<QUrl> thumbnailUrls, screenshotUrls;
- foreach(const QVariant& screenshot, screenshots) {
- QVariantMap s = screenshot.toMap();
- thumbnailUrls += s[QStringLiteral("small_image_url")].toUrl();
- screenshotUrls += s[QStringLiteral("large_image_url")].toUrl();
- }
- emit screenshotsFetched(thumbnailUrls, screenshotUrls);
- done = true;
- }
- }
- if(!done) {
- QList<QUrl> thumbnails, screenshots;
- if(!thumbnailUrl().isEmpty()) {
- thumbnails += thumbnailUrl();
- screenshots += screenshotUrl();
- }
- emit screenshotsFetched(thumbnails, screenshots);
- }
-
-}
-
-void Application::setHasScreenshot(bool has)
-{
- m_sourceHasScreenshot = has;
-}
-
-QStringList Application::executables() const
-{
- QStringList ret;
- const QVector<KService::Ptr> exes = findExecutables();
- for(KService::Ptr exe : exes) {
- ret += exe->exec();
- }
- return ret;
-}
-
-bool Application::isFromSecureOrigin() const
-{
- Q_FOREACH (const QString &archive, m_package->archives()) {
- if (archive.contains(QLatin1String("security"))) {
- return true;
- }
- }
- return false;
-}
-
-void Application::fetchChangelog()
-{
- KIO::StoredTransferJob* getJob = KIO::storedGet(m_package->changelogUrl(), KIO::NoReload, KIO::HideProgressInfo);
- connect(getJob, &KIO::StoredTransferJob::result, this, &Application::processChangelog);
-}
-
-void Application::processChangelog(KJob* j)
-{
- KIO::StoredTransferJob* job = qobject_cast<KIO::StoredTransferJob*>(j);
- if (!m_package || !job) {
- return;
- }
-
- QString changelog;
- if(j->error()==0)
- changelog = buildDescription(job->data(), m_package->sourcePackage());
-
- if (changelog.isEmpty()) {
- if (m_package->origin() == QStringLiteral("Ubuntu")) {
- changelog = xi18nc("@info/rich", "The list of changes is not yet available. "
- "Please use <link url='%1'>Launchpad</link> instead.",
- QStringLiteral("http://launchpad.net/ubuntu/+source/") + m_package->sourcePackage());
- } else {
- changelog = xi18nc("@info", "The list of changes is not yet available.");
- }
- }
- emit changelogFetched(changelog);
-}
-
-QString Application::buildDescription(const QByteArray& data, const QString& source)
-{
- QApt::Changelog changelog(QString::fromLatin1(data), source);
- QString description;
-
- QApt::ChangelogEntryList entries = changelog.newEntriesSince(m_package->installedVersion());
-
- if (entries.size() < 1) {
- return description;
- }
-
- foreach(const QApt::ChangelogEntry &entry, entries) {
- description += i18nc("@info:label Refers to a software version, Ex: Version 1.2.1:",
- "Version %1:", entry.version());
-
- KFormat f;
- QString issueDate = entry.issueDateTime().toString(Qt::DefaultLocaleShortDate);
- description += QLatin1String("<p>") +
- i18nc("@info:label", "This update was issued on %1", issueDate) +
- QLatin1String("</p>");
-
- QString updateText = entry.description();
- updateText.replace(QLatin1Char('\n'), QLatin1String("<br/>"));
- description += QLatin1String("<p><pre>") + updateText + QLatin1String("</pre></p>");
- }
-
- return description;
-}
-
-QApt::Backend *Application::backend() const
-{
- return qobject_cast<ApplicationBackend*>(parent())->backend();
-}
diff --git a/libdiscover/backends/ApplicationBackend/Application.h b/libdiscover/backends/ApplicationBackend/Application.h
deleted file mode 100644
index 7414280..0000000
--- a/libdiscover/backends/ApplicationBackend/Application.h
+++ /dev/null
@@ -1,114 +0,0 @@
-/***************************************************************************
- * Copyright © 2010-2011 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 APPLICATION_H
-#define APPLICATION_H
-
-#include <QtCore/QByteArray>
-#include <QtCore/QHash>
-#include <QtCore/QStringList>
-
-#include <KService>
-
-#include <AppstreamQt/component.h>
-#include <QApt/Package>
-
-#include "discovercommon_export.h"
-#include "resources/AbstractResource.h"
-
-class KJob;
-class KConfig;
-namespace QApt {
- class Backend;
-}
-
-class DISCOVERCOMMON_EXPORT Application : public AbstractResource
-{
-Q_OBJECT
-public:
- explicit Application(const Appstream::Component &component, QApt::Backend *backend);
- explicit Application(QApt::Package *package, QApt::Backend *backend);
-
- QString name() override;
- QString comment() override;
- QApt::Package *package();
- QVariant icon() const override;
- QStringList mimetypes() const override;
- QStringList categories() override;
- QString license() override;
- QUrl screenshotUrl() override;
- QUrl thumbnailUrl() override;
- QList< PackageState > addonsInformation() override;
- bool isValid() const;
- bool isTechnical() const override;
- QString packageName() const override;
-
- //QApt::Package forwarding
- QUrl homepage() override;
- QString longDescription() override;
- QString installedVersion() const override;
- QString availableVersion() const override;
- QString sizeDescription() override;
- QString origin() const override;
- int size() override;
-
- bool hasScreenshot() const { return m_sourceHasScreenshot; }
- void setHasScreenshot(bool has);
-
- void clearPackage();
- QVector<KService::Ptr> findExecutables() const;
- QStringList executables() const override;
-
- /** Used to trigger the stateChanged signal from the ApplicationBackend */
- void emitStateChanged();
-
- void invokeApplication() const override;
-
- bool canExecute() const override;
- QString section() override;
-
- State state() override;
- void fetchScreenshots() override;
- void fetchChangelog() override;
-
- bool isFromSecureOrigin() const;
-
-private Q_SLOTS:
- void processChangelog(KJob*);
- void downloadingScreenshotsFinished(KJob*);
-
-private:
- QApt::Backend *backend() const;
- QStringList findProvides(Appstream::Provides::Kind kind) const;
- QString buildDescription(const QByteArray& data, const QString& source);
-
- const Appstream::Component m_data;
- QApt::Package *m_package;
- QString m_packageName;
-
- bool m_isValid;
- bool m_isTechnical;
- bool m_isExtrasApp;
- bool m_sourceHasScreenshot;
-
- QApt::PackageList addons();
-};
-
-#endif
diff --git a/libdiscover/backends/ApplicationBackend/ApplicationBackend.cpp b/libdiscover/backends/ApplicationBackend/ApplicationBackend.cpp
deleted file mode 100644
index c5993e5..0000000
--- a/libdiscover/backends/ApplicationBackend/ApplicationBackend.cpp
+++ /dev/null
@@ -1,676 +0,0 @@
-/***************************************************************************
- * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 "ApplicationBackend.h"
-
-// Qt includes
-#include <QtConcurrentRun>
-#include <QtCore/QDir>
-#include <QtCore/QStringBuilder>
-#include <QtCore/QStringList>
-#include <QtCore/QUuid>
-#include <QTimer>
-#include <QSignalMapper>
-#include <QJsonDocument>
-#include <QAction>
-
-// KDE includes
-#include <KLocalizedString>
-#include <KMessageBox>
-#include <KProcess>
-#include <KProtocolManager>
-#include <KIO/Job>
-#include <KActionCollection>
-#include <KIconLoader>
-#include <KXmlGuiWindow>
-
-#include <AppstreamQt/database.h>
-
-// QApt/DebconfKDE includes
-#include <QApt/Backend>
-#include <QApt/Transaction>
-#include <DebconfGui.h>
-
-//libmuonapt includes
-#include "MuonStrings.h"
-#include "ChangesDialog.h"
-#include "QAptActions.h"
-
-// Own includes
-#include "AptSourcesBackend.h"
-#include "Application.h"
-#include "ReviewsBackend.h"
-#include "Transaction/Transaction.h"
-#include "Transaction/TransactionModel.h"
-#include "ApplicationUpdates.h"
-#include <resources/SourcesModel.h>
-#include <MuonDataSources.h>
-
-MUON_BACKEND_PLUGIN(ApplicationBackend)
-
-class AptTransaction : public Transaction
-{
-public:
- AptTransaction(QObject *parent, AbstractResource *resource, Transaction::Role role, const AddonList &addons = {})
- : Transaction(parent, resource, role, addons), m_aptTrans(nullptr) {}
-
- void cancel() {
- m_aptTrans->cancel();
- }
-
- QApt::Transaction *aptTrans() const { return m_aptTrans; }
- void setAptTrans(QApt::Transaction *t) { m_aptTrans = t; }
-
-private:
- QApt::Transaction *m_aptTrans;
-};
-
-ApplicationBackend::ApplicationBackend(QObject* parent)
- : AbstractResourcesBackend(parent)
- , m_backend(new QApt::Backend(this))
- , m_reviewsBackend(new ReviewsBackend(this))
- , m_isFetching(true)
- , m_currentTransaction(nullptr)
- , m_backendUpdater(new ApplicationUpdates(this))
- , m_aptify(nullptr)
- , m_aptBackendInitialized(false)
-{
- KIconLoader::global()->reconfigure(QString(), QStringList(QStringLiteral("/usr/share/app-install/icons/")));
-
- m_watcher = new QFutureWatcher<QVector<Application*> >(this);
- connect(m_watcher, &QFutureWatcher<QVector<Application*> >::finished, this, &ApplicationBackend::setApplications);
- connect(m_reviewsBackend, &ReviewsBackend::ratingsReady, this, &AbstractResourcesBackend::emitRatingsReady);
-
- QTimer::singleShot(10, this, SLOT(initBackend()));
-}
-
-ApplicationBackend::~ApplicationBackend()
-{
- qDeleteAll(m_appList);
-}
-
-QVector<Application *> init(QApt::Backend *backend, QThread* thread)
-{
- Appstream::Database appdata;
- bool opened = appdata.open();
- Q_ASSERT(opened);
-
- QVector<Application *> tempList;
- QSet<QString> packages;
- foreach(const Appstream::Component &component, appdata.allComponents()) {
- if (component.packageNames().isEmpty())
- continue;
- Application *app = new Application(component, backend);
- packages.insert(app->packageName());
- tempList << app;
- }
-
- foreach (QApt::Package *package, backend->availablePackages()) {
- //Don't create applications twice
- if(packages.contains(package->name()))
- continue;
-
- if (package->isMultiArchDuplicate())
- continue;
-
- Application *app = new Application(package, backend);
- tempList << app;
- }
-
- // To be added an Application must have a package that:
- // a) exists
- // b) is not on the blacklist
- // c) if not downloadable, then it must already be installed
- QVector<Application *> appList;
- appList.reserve(tempList.size());
- Q_FOREACH (Application *app, tempList) {
- QApt::Package *pkg = app->package();
- if (app->isValid() && pkg)
- {
- appList << app;
- app->moveToThread(thread);
- }
- else
- delete app;
- }
-
- return appList;
-}
-
-void ApplicationBackend::setApplications()
-{
- m_appList = m_watcher->future().result();
- Q_FOREACH (Application* app, m_appList)
- app->setParent(this);
-
- KIO::StoredTransferJob* job = KIO::storedGet(QUrl(MuonDataSources::screenshotsSource().toString() + QStringLiteral("/json/packages")),KIO::NoReload, KIO::DefaultFlags|KIO::HideProgressInfo);
- connect(job, &KIO::StoredTransferJob::finished, this, &ApplicationBackend::initAvailablePackages);
-
- if (m_aptify)
- QAptActions::self()->setCanExit(true);
- setFetching(false);
-}
-
-void ApplicationBackend::reload()
-{
- if(isFetching()) {
- qWarning() << "Reloading while already reloading... Please report.";
- return;
- }
- setFetching(true);
- if (m_aptify)
- QAptActions::self()->setCanExit(false);
- foreach(Application* app, m_appList)
- app->clearPackage();
- qDeleteAll(m_transQueue);
- m_transQueue.clear();
- m_reviewsBackend->stopPendingJobs();
-
- if (!m_backend->reloadCache())
- QAptActions::self()->initError();
-
- foreach(Application* app, m_appList)
- app->package();
-
- if (m_aptify)
- QAptActions::self()->setCanExit(true);
- setFetching(false);
-}
-
-bool ApplicationBackend::isFetching() const
-{
- return m_isFetching;
-}
-
-bool ApplicationBackend::isValid() const
-{
- // ApplicationBackend will force an application quit if it is invalid, so
- // if it has not done that, the backend is valid.
- return true;
-}
-
-void ApplicationBackend::aptTransactionsChanged(QString active)
-{
- // Find the newly-active QApt transaction in our list
- AptTransaction* discTrans = nullptr;
-
- Q_FOREACH (AptTransaction *t, m_transQueue) {
- if (t->aptTrans()->transactionId() == active) {
- discTrans = t;
- break;
- }
- }
-
- if (!discTrans || discTrans == m_currentTransaction)
- return;
-
- m_currentTransaction = discTrans;
- QApt::Transaction *trans = discTrans->aptTrans();
- connect(trans, &QApt::Transaction::statusChanged, this, &ApplicationBackend::transactionEvent);
- connect(trans, &QApt::Transaction::errorOccurred, this, &ApplicationBackend::errorOccurred);
- connect(trans, &QApt::Transaction::progressChanged, this, &ApplicationBackend::updateProgress);
- // FIXME: untrusted packages, conf file prompt, media change
-}
-
-void ApplicationBackend::transactionEvent(QApt::TransactionStatus status)
-{
- if (!m_currentTransaction->aptTrans())
- return;
-
- TransactionModel *transModel = TransactionModel::global();
-
- switch (status) {
- case QApt::SetupStatus:
- case QApt::AuthenticationStatus:
- case QApt::WaitingStatus:
- case QApt::WaitingLockStatus:
- case QApt::WaitingMediumStatus:
- case QApt::WaitingConfigFilePromptStatus:
- case QApt::LoadingCacheStatus:
- m_currentTransaction->setStatus(Transaction::SetupStatus);
- break;
- case QApt::RunningStatus:
- m_currentTransaction->setStatus(Transaction::QueuedStatus);
- break;
- case QApt::DownloadingStatus:
- m_currentTransaction->setStatus(Transaction::DownloadingStatus);
- m_currentTransaction->setCancellable(false);
- break;
- case QApt::CommittingStatus:
- m_currentTransaction->setStatus(Transaction::CommittingStatus);
-
- // Set up debconf
- m_debconfGui = new DebconfKde::DebconfGui(m_currentTransaction->aptTrans()->debconfPipe());
- m_debconfGui->connect(m_debconfGui, &DebconfKde::DebconfGui::activated, m_debconfGui, &DebconfKde::DebconfGui::show);
- m_debconfGui->connect(m_debconfGui, &DebconfKde::DebconfGui::deactivated, m_debconfGui, &DebconfKde::DebconfGui::hide);
- break;
- case QApt::FinishedStatus:
- m_currentTransaction->setStatus(Transaction::DoneStatus);
-
- // Clean up manually created debconf pipe
- QApt::Transaction *trans = m_currentTransaction->aptTrans();
- if (!trans->debconfPipe().isEmpty())
- QFile::remove(trans->debconfPipe());
-
- // Cleanup
- trans->deleteLater();
-
- if (trans->exitStatus() == QApt::ExitCancelled)
- transModel->cancelTransaction(m_currentTransaction);
- else
- transModel->removeTransaction(m_currentTransaction);
- m_transQueue.removeAll(m_currentTransaction);
-
- qobject_cast<Application*>(m_currentTransaction->resource())->emitStateChanged();
- delete m_currentTransaction;
- m_currentTransaction = nullptr;
-
- if (m_transQueue.isEmpty())
- reload();
- break;
- }
-}
-
-void ApplicationBackend::errorOccurred(QApt::ErrorCode error)
-{
- if (m_transQueue.isEmpty()) // Shouldn't happen
- return;
-
- if( error == QApt::AuthError){
- m_currentTransaction->cancel();
- m_transQueue.removeAll(m_currentTransaction);
- m_currentTransaction->deleteLater();
- m_currentTransaction = nullptr;
- }
- QAptActions::self()->displayTransactionError(error, m_currentTransaction->aptTrans());
-}
-
-void ApplicationBackend::updateProgress(int percentage)
-{
- if(!m_currentTransaction) {
- qDebug() << "missing transaction";
- return;
- }
- m_currentTransaction->setProgress(percentage);
-}
-
-bool ApplicationBackend::confirmRemoval(QApt::StateChanges changes)
-{
- const QApt::PackageList removeList = changes.value(QApt::Package::ToRemove);
- if (removeList.isEmpty())
- return true;
-
- QApt::StateChanges removals;
- removals[QApt::Package::ToRemove] = removeList;
-
- QPointer<ChangesDialog> dialog = new ChangesDialog(mainWindow(), removals);
- bool ret = dialog->exec() == QDialog::Accepted;
- delete dialog;
- return ret;
-}
-
-void ApplicationBackend::markTransaction(Transaction *transaction)
-{
- Application *app = qobject_cast<Application*>(transaction->resource());
-
- switch (transaction->role()) {
- case Transaction::InstallRole:
- app->package()->setInstall();
- markLangpacks(transaction);
- break;
- case Transaction::RemoveRole:
- app->package()->setRemove();
- break;
- default:
- break;
- }
-
- AddonList addons = transaction->addons();
-
- Q_FOREACH (const QString &pkgStr, addons.addonsToInstall()) {
- QApt::Package *package = m_backend->package(pkgStr);
- package->setInstall();
- }
-
- Q_FOREACH (const QString &pkgStr, addons.addonsToRemove()) {
- QApt::Package *package = m_backend->package(pkgStr);
- package->setRemove();
- }
-}
-
-void ApplicationBackend::markLangpacks(Transaction *transaction)
-{
- QString prog = QStandardPaths::findExecutable(QStringLiteral("check-language-support"));
- if (prog.isEmpty()){
- prog = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("discover/scripts/check-language-support"));
- if ( prog.isEmpty()){
- return;
- }
- }
-
- QString language = QLocale().name();
- QString pkgName = transaction->resource()->packageName();
-
- QStringList args;
- args << prog << QLatin1String("-l") << language << QLatin1String("-p") << pkgName;
-
- KProcess proc;
- proc.setOutputChannelMode(KProcess::OnlyStdoutChannel);
- proc.setProgram(args);
- proc.start();
- proc.waitForFinished();
-
- QString res = QString::fromLatin1(proc.readAllStandardOutput());
- res.remove(QString());
-
- m_backend->setCompressEvents(true);
- foreach(const QString &pkg, res.split(QLatin1Char(' ')))
- {
- QApt::Package *langPack = m_backend->package(pkg.trimmed());
-
- if (langPack)
- langPack->setInstall();
- }
- m_backend->setCompressEvents(false);
-}
-
-void ApplicationBackend::addTransaction(AptTransaction *transaction)
-{
- if(!transaction){
- return;
- }
- QApt::CacheState oldCacheState = m_backend->currentCacheState();
- m_backend->saveCacheState();
-
- markTransaction(transaction);
-
- // Find changes due to markings
- QApt::PackageList excluded;
- excluded.append(qobject_cast<Application*>(transaction->resource())->package());
- // Exclude addons being marked
- Q_FOREACH (const QString &pkgStr, transaction->addons().addonsToInstall()) {
- QApt::Package *addon = m_backend->package(pkgStr);
-
- if (addon)
- excluded.append(addon);
- }
-
- Q_FOREACH (const QString &pkgStr, transaction->addons().addonsToRemove()) {
- QApt::Package *addon = m_backend->package(pkgStr);
-
- if (addon)
- excluded.append(addon);
- }
-
- QApt::StateChanges changes = m_backend->stateChanges(oldCacheState, excluded);
-
- if (!confirmRemoval(changes)) {
- m_backend->restoreCacheState(oldCacheState);
- transaction->deleteLater();
- return;
- }
-
- Application *app = qobject_cast<Application*>(transaction->resource());
-
- if (app->package()->wouldBreak()) {
- m_backend->restoreCacheState(oldCacheState);
- //TODO Notify of error
- }
-
- QApt::Transaction *aptTrans = m_backend->commitChanges();
- setupTransaction(aptTrans);
- transaction->setAptTrans(aptTrans);
- TransactionModel::global()->addTransaction(transaction);
- aptTrans->run();
- m_backend->restoreCacheState(oldCacheState); // Undo temporary simulation marking
-
- if (m_transQueue.count() == 1) {
- aptTransactionsChanged(aptTrans->transactionId());
- m_currentTransaction = transaction;
- }
-}
-
-QApt::Backend* ApplicationBackend::backend() const
-{
- return m_backend;
-}
-
-AbstractReviewsBackend *ApplicationBackend::reviewsBackend() const
-{
- return m_reviewsBackend;
-}
-
-QVector<AbstractResource*> ApplicationBackend::allResources() const
-{
- QVector<AbstractResource*> ret;
-
- Q_FOREACH (Application* app, m_appList) {
- ret += app;
- }
- return ret;
-}
-
-void ApplicationBackend::installApplication(AbstractResource* res, const AddonList& addons)
-{
- Application* app = qobject_cast<Application*>(res);
- Transaction::Role role = app->package()->isInstalled() ? Transaction::ChangeAddonsRole : Transaction::InstallRole;
- addTransaction(new AptTransaction(this, res, role, addons));
-}
-
-void ApplicationBackend::installApplication(AbstractResource* app)
-{
- addTransaction(new AptTransaction(this, app, Transaction::InstallRole));
-}
-
-void ApplicationBackend::removeApplication(AbstractResource* app)
-{
- addTransaction(new AptTransaction(this, app, Transaction::RemoveRole));
-}
-
-int ApplicationBackend::updatesCount() const
-{
- if(m_isFetching)
- return 0;
-
- int count = 0;
- foreach(Application* app, m_appList) {
- count += app->canUpgrade();
- }
- return count;
-}
-
-AbstractResource* ApplicationBackend::resourceByPackageName(const QString& name) const
-{
- foreach(Application* app, m_appList) {
- if(app->packageName()==name)
- return app;
- }
- return nullptr;
-}
-
-QList<AbstractResource*> ApplicationBackend::searchPackageName(const QString& searchText)
-{
- QList<AbstractResource*> resources;
- if(m_isFetching) {
- qWarning() << "searching while fetching!!!";
- return resources;
- }
-
- QSet<QApt::Package*> packages = m_backend->search(searchText).toSet();
-
- foreach(Application* a, m_appList) {
- if(packages.contains(a->package())) {
- resources += a;
- }
- }
- return resources;
-}
-
-AbstractBackendUpdater* ApplicationBackend::backendUpdater() const
-{
- return m_backendUpdater;
-}
-
-void ApplicationBackend::integrateActions(KActionCollection* w)
-{
- m_aptify = w;
- QAptActions* apt = QAptActions::self();
- apt->setActionCollection(w);
- if(!m_aptBackendInitialized)
- connect(this, &ApplicationBackend::aptBackendInitialized, apt, &QAptActions::setBackend);
- if (apt->reloadWhenSourcesEditorFinished())
- connect(apt, &QAptActions::sourcesEditorClosed, this, &ApplicationBackend::reload);
- QAction* updateAction = w->addAction(QStringLiteral("update"));
- updateAction->setIcon(QIcon::fromTheme(QStringLiteral("system-software-update")));
- updateAction->setText(i18nc("@action Checks the Internet for updates", "Check for Updates"));
- updateAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R));
- updateAction->setEnabled(apt->isConnected());
- connect(updateAction, &QAction::triggered, this, &ApplicationBackend::checkForUpdates);
- connect(apt, &QAptActions::shouldConnect, updateAction, &QAction::setEnabled);
-}
-
-QWidget* ApplicationBackend::mainWindow() const
-{
- return QAptActions::self()->mainWindow();
-}
-
-void ApplicationBackend::initBackend()
-{
- setFetching(true);
- if (m_aptify) {
- QAptActions::self()->setCanExit(false);
- QAptActions::self()->setReloadWhenEditorFinished(true);
- }
-
- QAptActions::self()->setBackend(m_backend);
- if (m_backend->xapianIndexNeedsUpdate())
- m_backend->updateXapianIndex();
-
- m_aptBackendInitialized = true;
- emit aptBackendInitialized(m_backend);
-
- m_backend->setUndoRedoCacheSize(1);
- m_reviewsBackend->setAptBackend(m_backend);
- m_backendUpdater->setBackend(m_backend);
-
- QFuture<QVector<Application*> > future = QtConcurrent::run(init, m_backend, QThread::currentThread());
- m_watcher->setFuture(future);
- connect(m_backend, &QApt::Backend::transactionQueueChanged, this, &ApplicationBackend::aptTransactionsChanged);
- connect(m_backend, &QApt::Backend::xapianUpdateFinished, this, &ApplicationBackend::searchInvalidated);
-
- SourcesModel::global()->addSourcesBackend(new AptSourcesBackend(this));
-}
-
-void ApplicationBackend::setupTransaction(QApt::Transaction *trans)
-{
- // Provide proxy/locale to the transaction
- if (KProtocolManager::proxyType() == KProtocolManager::ManualProxy) {
- trans->setProxy(KProtocolManager::proxyFor(QStringLiteral("http")));
- }
-
- trans->setLocale(QLatin1String(setlocale(LC_MESSAGES, nullptr)));
-
- // Debconf
- QString uuid = QUuid::createUuid().toString();
- uuid.remove(QLatin1Char('{')).remove(QLatin1Char('}')).remove(QLatin1Char('-'));
- QFile pipe(QDir::tempPath() % QLatin1String("/qapt-sock-") % uuid);
- pipe.open(QFile::ReadWrite);
- pipe.close();
- trans->setDebconfPipe(pipe.fileName());
-}
-
-void ApplicationBackend::sourcesEditorClosed()
-{
- reload();
- emit sourcesEditorFinished();
-}
-
-void ApplicationBackend::initAvailablePackages(KJob* j)
-{
- KIO::StoredTransferJob* job = qobject_cast<KIO::StoredTransferJob*>(j);
- Q_ASSERT(job);
-
- QJsonParseError error;
- QJsonDocument doc = QJsonDocument::fromJson(job->data(), &error);
- if(error.error != QJsonParseError::NoError)
- qWarning() << "errors!" << error.errorString();
- else {
- QVariantList data = doc.toVariant().toMap().value(QStringLiteral("packages")).toList();
- Q_ASSERT(!m_appList.isEmpty());
- QSet<QString> packages;
- foreach(const QVariant& v, data) {
- packages += v.toMap().value(QStringLiteral("name")).toString();
- }
- Q_ASSERT(packages.count()==data.count());
- Q_FOREACH (Application* a, m_appList) {
- a->setHasScreenshot(packages.contains(a->packageName()));
- }
- }
-}
-
-void ApplicationBackend::checkForUpdates()
-{
- QApt::Transaction* transaction = backend()->updateCache();
- m_backendUpdater->setupTransaction(transaction);
- transaction->run();
- m_backendUpdater->setProgressing(true);
- connect(transaction, &QApt::Transaction::finished, this, &ApplicationBackend::updateFinished);
-}
-
-void ApplicationBackend::updateFinished(QApt::ExitStatus status)
-{
- if(status != QApt::ExitSuccess) {
- qWarning() << "updating was not successful";
- }
- m_backendUpdater->setProgressing(false);
-}
-
-void ApplicationBackend::setFetching(bool f)
-{
- if(m_isFetching != f) {
- m_isFetching = f;
- emit fetchingChanged();
- if(!m_isFetching) {
- emit searchInvalidated();
- emit updatesCountChanged();
- }
- }
-}
-
-QList<QAction*> ApplicationBackend::messageActions() const
-{
- QList<QAction*> ret;
- //high priority
- ret += QAptActions::self()->actionCollection()->action(QStringLiteral("dist-upgrade"));
-
- //normal priority
- ret += QAptActions::self()->actionCollection()->action(QStringLiteral("update"));
-
- //low priority
- ret += QAptActions::self()->actionCollection()->action(QStringLiteral("software_properties"));
- ret += QAptActions::self()->actionCollection()->action(QStringLiteral("load_archives"));
- ret += QAptActions::self()->actionCollection()->action(QStringLiteral("save_package_list"));
- ret += QAptActions::self()->actionCollection()->action(QStringLiteral("download_from_list"));
- ret += QAptActions::self()->actionCollection()->action(QStringLiteral("history"));
- Q_ASSERT(!ret.contains(nullptr));
- return ret;
-}
-
-#include "ApplicationBackend.moc"
diff --git a/libdiscover/backends/ApplicationBackend/ApplicationBackend.h b/libdiscover/backends/ApplicationBackend/ApplicationBackend.h
deleted file mode 100644
index 6e0b732..0000000
--- a/libdiscover/backends/ApplicationBackend/ApplicationBackend.h
+++ /dev/null
@@ -1,128 +0,0 @@
-/***************************************************************************
- * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 APPLICATIONBACKEND_H
-#define APPLICATIONBACKEND_H
-
-#include <QFutureWatcher>
-#include <QtCore/QObject>
-#include <QtCore/QPointer>
-#include <QtCore/QQueue>
-#include <QtCore/QSet>
-#include <QtCore/QStringList>
-#include <QtCore/QVector>
-
-#include <QApt/Package>
-#include <QApt/Backend>
-
-#include "resources/AbstractResourcesBackend.h"
-
-namespace QApt {
- class Backend;
- class Transaction;
-}
-namespace DebconfKde {
- class DebconfGui;
-}
-
-class Application;
-class ApplicationUpdates;
-class ReviewsBackend;
-class Transaction;
-class AptTransaction;
-class QAptActions;
-class KJob;
-
-class ApplicationBackend : public AbstractResourcesBackend
-{
- Q_OBJECT
- Q_PROPERTY(QObject* backend READ backend)
-public:
- explicit ApplicationBackend(QObject *parent = nullptr);
- ~ApplicationBackend() override;
-
- bool isValid() const override;
- AbstractReviewsBackend *reviewsBackend() const override;
- Q_SCRIPTABLE AbstractResource* resourceByPackageName(const QString& name) const override;
- QApt::Backend* backend() const;
-
- int updatesCount() const override;
-
- bool confirmRemoval(QApt::StateChanges changes);
- bool isFetching() const override;
- void markTransaction(Transaction *transaction);
- void markLangpacks(Transaction *transaction);
-
- QVector< AbstractResource* > allResources() const override;
- QList<AbstractResource*> searchPackageName(const QString& searchText) override;
-
- void installApplication(AbstractResource *res, const AddonList& addons) override;
- void installApplication(AbstractResource *app) override;
- void removeApplication(AbstractResource *app) override;
-
- AbstractBackendUpdater* backendUpdater() const override;
- void integrateActions(KActionCollection* w) override;
- QWidget* mainWindow() const;
- QList<QAction*> messageActions() const override;
-
-private:
- void setFetching(bool f);
-
- QApt::Backend *m_backend;
- ReviewsBackend *m_reviewsBackend;
- bool m_isFetching;
-
- QFutureWatcher<QVector<Application*> >* m_watcher;
- QVector<Application *> m_appList;
-
- // Transactions
- QVector<AptTransaction *> m_transQueue;
- QPointer<AptTransaction> m_currentTransaction;
-
- DebconfKde::DebconfGui *m_debconfGui;
- ApplicationUpdates* m_backendUpdater;
- KActionCollection *m_aptify;
- bool m_aptBackendInitialized;
-
-public Q_SLOTS:
- void reload();
- void addTransaction(AptTransaction *transaction);
- //helper functions
- void initAvailablePackages(KJob*);
-
-private Q_SLOTS:
- void setApplications();
- void aptTransactionsChanged(QString active);
- void transactionEvent(QApt::TransactionStatus status);
- void errorOccurred(QApt::ErrorCode error);
- void updateProgress(int percentage);
- void initBackend();
- void setupTransaction(QApt::Transaction *trans);
- void sourcesEditorClosed();
- void checkForUpdates();
- void updateFinished(QApt::ExitStatus);
-
-Q_SIGNALS:
- void startingFirstTransaction();
- void sourcesEditorFinished();
- void aptBackendInitialized(QApt::Backend* backend);
-};
-
-#endif
diff --git a/libdiscover/backends/ApplicationBackend/ApplicationNotifier.cpp b/libdiscover/backends/ApplicationBackend/ApplicationNotifier.cpp
deleted file mode 100644
index aba5dbc..0000000
--- a/libdiscover/backends/ApplicationBackend/ApplicationNotifier.cpp
+++ /dev/null
@@ -1,172 +0,0 @@
-/***************************************************************************
- * Copyright © 2013 Lukas Appelhans <l.appelhans@gmx.de> *
- * *
- * 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 "ApplicationNotifier.h"
-
-// Qt includes
-#include <QtCore/QFile>
-#include <QtCore/QTimer>
-#include <QtCore/QDebug>
-#include <QtCore/QStandardPaths>
-#include <QtCore/QProcess>
-#include <QtGui/QIcon>
-
-// KDE includes
-#include <KDirWatch>
-#include <KLocalizedString>
-#include <KPluginFactory>
-#include <KNotification>
-
-ApplicationNotifier::ApplicationNotifier(QObject* parent)
- : BackendNotifierModule(parent)
- , m_checkerProcess(Q_NULLPTR)
- , m_updateCheckerProcess(Q_NULLPTR)
- , m_securityUpdates(0)
- , m_normalUpdates(0)
-{
- KDirWatch *stampDirWatch = new KDirWatch(this);
- stampDirWatch->addFile(QStringLiteral("/var/lib/update-notifier/dpkg-run-stamp"));
- connect(stampDirWatch, &KDirWatch::dirty, this, &ApplicationNotifier::distUpgradeEvent);
-
- QTimer* t = new QTimer(this);
- t->setSingleShot(true);
- t->setInterval(2000);
- connect(t, &QTimer::timeout, this, &ApplicationNotifier::recheckSystemUpdateNeeded);
-
- stampDirWatch = new KDirWatch(this);
- stampDirWatch->addDir(QStringLiteral("/var/lib/apt/lists/"));
- stampDirWatch->addDir(QStringLiteral("/var/lib/apt/lists/partial/"));
- stampDirWatch->addFile(QStringLiteral("/var/lib/update-notifier/updates-available"));
- stampDirWatch->addFile(QStringLiteral("/var/lib/update-notifier/dpkg-run-stamp"));
- connect(stampDirWatch, &KDirWatch::dirty, t, static_cast<void(QTimer::*)()>(&QTimer::start));
-// connect(stampDirWatch, &KDirWatch::dirty, this, [](const QString& dirty){ qDebug() << "dirty path" << dirty;});
-
- m_updateCheckerProcess = new QProcess(this);
- m_updateCheckerProcess->setProgram(QStringLiteral("/usr/lib/update-notifier/apt-check"));
- connect(m_updateCheckerProcess, static_cast<void(QProcess::*)(int)>(&QProcess::finished), this, &ApplicationNotifier::parseUpdateInfo);
-
- init();
-}
-
-ApplicationNotifier::~ApplicationNotifier() = default;
-
-void ApplicationNotifier::init()
-{
- recheckSystemUpdateNeeded();
- distUpgradeEvent();
-}
-
-void ApplicationNotifier::distUpgradeEvent()
-{
- QString checkerFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("libdiscover/applicationsbackend/releasechecker"));
- if (checkerFile.isEmpty()) {
- qWarning() << "Couldn't find the releasechecker" << checkerFile << QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
- return;
- }
- m_checkerProcess = new QProcess(this);
- connect(m_checkerProcess, static_cast<void (QProcess::*)(int)>(&QProcess::finished), this, &ApplicationNotifier::checkUpgradeFinished);
- m_checkerProcess->start(QStringLiteral("/usr/bin/python3"), QStringList() << checkerFile);
-}
-
-void ApplicationNotifier::checkUpgradeFinished(int exitStatus)
-{
- if (exitStatus == 0) {
- KNotification *n = KNotification::event(QStringLiteral("DistUpgrade"),
- i18n("System update available!"),
- i18nc("Notification when a new version of Kubuntu is available",
- "A new version of Kubuntu is available"),
- QStringLiteral("system-software-update"),
- nullptr,
- KNotification::CloseOnTimeout,
- QStringLiteral("muonapplicationnotifier"));
- n->setActions(QStringList() << i18n("Upgrade"));
- connect(n, &KNotification::action1Activated, this, &ApplicationNotifier::upgradeActivated);
- }
-
- m_checkerProcess->deleteLater();
- m_checkerProcess = nullptr;
-}
-
-void ApplicationNotifier::upgradeActivated()
-{
- const QString kdesu = QFile::decodeName(CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/kdesu");
- QProcess::startDetached(kdesu, { QStringLiteral("--"), QStringLiteral("do-release-upgrade"), QStringLiteral("-m"), QStringLiteral("desktop"), QStringLiteral("-f"), QStringLiteral("DistUpgradeViewKDE") });
-}
-
-void ApplicationNotifier::recheckSystemUpdateNeeded()
-{
- qDebug() << "should recheck..." << m_updateCheckerProcess << m_updateCheckerProcess->state();
-
- if (m_updateCheckerProcess->state() == QProcess::Running)
- return;
-
- m_updateCheckerProcess->start();
-}
-
-void ApplicationNotifier::parseUpdateInfo()
-{
- if (!m_updateCheckerProcess)
- return;
-
-#warning why does this parse stdout and not use qapt, wtf...
- // Weirdly enough, apt-check gives output on stderr
- QByteArray line = m_updateCheckerProcess->readAllStandardError();
- if (line.isEmpty())
- return;
-
- // Format updates;security
- int eqpos = line.indexOf(';');
-
- if (eqpos > 0) {
- QByteArray updatesString = line.left(eqpos);
- QByteArray securityString = line.right(line.size() - eqpos - 1);
-
- int securityUpdates = securityString.toInt();
- setUpdates(updatesString.toInt() - securityUpdates, securityUpdates);
- } else {
- //if the format is wrong consider as up to date
- setUpdates(0, 0);
- }
-}
-
-void ApplicationNotifier::setUpdates(int normal, int security)
-{
- if (m_normalUpdates != normal || security != m_securityUpdates) {
- m_normalUpdates = normal;
- m_securityUpdates = security;
- emit foundUpdates();
- }
-}
-
-bool ApplicationNotifier::isSystemUpToDate() const
-{
- return (m_securityUpdates+m_normalUpdates)==0;
-}
-
-uint ApplicationNotifier::securityUpdatesCount()
-{
- return m_securityUpdates;
-}
-
-uint ApplicationNotifier::updatesCount()
-{
- return m_normalUpdates;
-}
-
-#include "ApplicationNotifier.moc"
diff --git a/libdiscover/backends/ApplicationBackend/ApplicationNotifier.h b/libdiscover/backends/ApplicationBackend/ApplicationNotifier.h
deleted file mode 100644
index 3b46ac3..0000000
--- a/libdiscover/backends/ApplicationBackend/ApplicationNotifier.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/***************************************************************************
- * Copyright © 2013 Lukas Appelhans <l.appelhans@gmx.de> *
- * *
- * 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 APPLICATIONNOTIFIER_H
-#define APPLICATIONNOTIFIER_H
-
-#include <BackendNotifierModule.h>
-#include <QVariantList>
-
-class DistUpgradeEvent;
-class UpdateEvent;
-class QProcess;
-
-class ApplicationNotifier : public BackendNotifierModule
-{
- Q_OBJECT
- Q_PLUGIN_METADATA(IID "org.kde.discover.BackendNotifierModule")
- Q_INTERFACES(BackendNotifierModule)
-public:
- explicit ApplicationNotifier(QObject* parent = nullptr);
- ~ApplicationNotifier() override;
-
- bool isSystemUpToDate() const final;
- uint securityUpdatesCount() final;
- uint updatesCount() final;
-
-private Q_SLOTS:
- void checkUpgradeFinished(int exitStatus);
- void distUpgradeEvent();
- void recheckSystemUpdateNeeded() final;
- void parseUpdateInfo();
- void upgradeActivated();
- void init();
-
-private:
- void setUpdates(int normal, int security);
-
- QProcess *m_checkerProcess;
- QProcess *m_updateCheckerProcess;
- int m_securityUpdates;
- int m_normalUpdates;
-};
-
-#endif
diff --git a/libdiscover/backends/ApplicationBackend/ApplicationUpdates.cpp b/libdiscover/backends/ApplicationBackend/ApplicationUpdates.cpp
deleted file mode 100644
index b283473..0000000
--- a/libdiscover/backends/ApplicationBackend/ApplicationUpdates.cpp
+++ /dev/null
@@ -1,467 +0,0 @@
-/***************************************************************************
- * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.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 "ApplicationUpdates.h"
-
-// Qt includes
-#include <QIcon>
-#include <QAction>
-#include <QApplication>
-
-// KDE includes
-#include <KProtocolManager>
-#include <KMessageBox>
-#include <KActionCollection>
-#include <KLocalizedString>
-#include <KXmlGuiWindow>
-
-// Own includes
-#include <QApt/Transaction>
-
-#include <ChangesDialog.h>
-#include <MuonStrings.h>
-#include <QAptActions.h>
-
-#include "Application.h"
-#include "ApplicationBackend.h"
-
-ApplicationUpdates::ApplicationUpdates(ApplicationBackend* parent)
- : AbstractBackendUpdater(parent)
- , m_aptBackend(nullptr)
- , m_appBackend(parent)
- , m_lastRealProgress(0)
- , m_eta(0)
- , m_progressing(false)
-{
- connect(m_appBackend, &ApplicationBackend::fetchingChanged, this, &ApplicationUpdates::fetchingChanged);
-}
-
-bool ApplicationUpdates::hasUpdates() const
-{
- return m_appBackend->updatesCount()>0;
-}
-
-qreal ApplicationUpdates::progress() const
-{
- return m_lastRealProgress;
-}
-
-long unsigned int ApplicationUpdates::remainingTime() const
-{
- return m_eta;
-}
-
-void ApplicationUpdates::setBackend(QApt::Backend* backend)
-{
- Q_ASSERT(!m_aptBackend || m_aptBackend==backend);
- m_aptBackend = backend;
- // FIXME: Debconf support was lost during the port
- QApt::FrontendCaps caps = (QApt::FrontendCaps)(QApt::MediumPromptCap |
- QApt::ConfigPromptCap | QApt::UntrustedPromptCap);
- m_aptBackend->setFrontendCaps(caps);
-}
-
-QList<AbstractResource*> ApplicationUpdates::toUpdate() const
-{
- return m_toUpdate;
-}
-
-void ApplicationUpdates::restoreToCleanCache()
-{
- if(!m_updatesCache.isEmpty())
- m_aptBackend->restoreCacheState(m_updatesCache);
- else {
- //this is my best bet for retrieving a clean cache, I'm unsure if there's a better way
- m_updatesCache = m_aptBackend->currentCacheState();
- }
- Q_ASSERT(m_aptBackend->markedPackages().isEmpty());
-}
-
-void ApplicationUpdates::prepare()
-{
- restoreToCleanCache();
-
- m_aptBackend->markPackagesForDistUpgrade();
- calculateUpdates();
-}
-
-void ApplicationUpdates::start()
-{
- Q_ASSERT(!m_updatesCache.isEmpty());
- auto changes = m_aptBackend->stateChanges(m_updatesCache, QApt::PackageList());
- if(changes.isEmpty()) {
- qWarning() << "couldn't find any apt updates";
- setProgressing(false);
- return;
- }
- for(auto it=changes.begin(); it!=changes.end(); ) {
- if(it.key()&QApt::Package::ToUpgrade) {
- it = changes.erase(it);
- } else {
- ++it;
- }
- }
- // Confirm additional changes beyond upgrading the files
- if(!changes.isEmpty()) {
- ChangesDialog d(m_appBackend->mainWindow(), changes);
- if(d.exec()==QDialog::Rejected) {
- setProgressing(false);
- return;
- }
- }
-
- // Create and run the transaction
- setupTransaction(m_aptBackend->commitChanges());
- m_trans->run();
- setProgressing(true);
-}
-
-void ApplicationUpdates::addResources(const QList<AbstractResource*>& apps)
-{
- if (apps.size() > 1) {
- QApplication::setOverrideCursor(Qt::WaitCursor);
- }
- QList<QApt::Package*> packages;
- foreach(AbstractResource* res, apps) {
- Application* app = qobject_cast<Application*>(res);
- Q_ASSERT(app);
- packages += app->package();
- }
- m_aptBackend->markPackages(packages, QApt::Package::ToInstall);
- QApplication::restoreOverrideCursor();
-}
-
-void ApplicationUpdates::removeResources(const QList<AbstractResource*>& apps)
-{
- QList<QApt::Package*> packages;
- foreach(AbstractResource* res, apps) {
- Application* app = qobject_cast<Application*>(res);
- Q_ASSERT(app);
- packages += app->package();
- }
- m_aptBackend->markPackages(packages, QApt::Package::ToKeep);
-}
-
-void ApplicationUpdates::setProgress(int progress)
-{
- if (progress > 100)
- return;
-
- if (progress > m_lastRealProgress || progress<0) {
- m_lastRealProgress = progress;
- emit progressChanged((qreal)progress);
- }
-}
-
-void ApplicationUpdates::etaChanged(quint64 eta)
-{
- if(m_eta != eta) {
- m_eta = eta;
- emit remainingTimeChanged();
- }
-}
-
-void ApplicationUpdates::installMessage(const QString& msg)
-{
- setStatusMessage(msg);
-}
-
-void ApplicationUpdates::errorOccurred(QApt::ErrorCode error)
-{
- if(error!=QApt::Success) {
- QAptActions::self()->displayTransactionError(error, m_trans);
- setProgressing(false);
- }
-}
-
-void ApplicationUpdates::setupTransaction(QApt::Transaction *trans)
-{
- Q_ASSERT(trans);
- m_trans = trans;
-
- // Provide proxy/locale to the transaction
- if (KProtocolManager::proxyType() == KProtocolManager::ManualProxy) {
- trans->setProxy(KProtocolManager::proxyFor(QStringLiteral("http")));
- }
-
- trans->setLocale(QLatin1String(setlocale(LC_MESSAGES, nullptr)));
-
- connect(trans, SIGNAL(errorOccurred(QApt::ErrorCode)),
- SLOT(errorOccurred(QApt::ErrorCode)));
- connect(trans, SIGNAL(progressChanged(int)), SLOT(setProgress(int)));
- connect(trans, SIGNAL(statusDetailsChanged(QString)), SLOT(installMessage(QString)));
- connect(trans, SIGNAL(cancellableChanged(bool)), SIGNAL(cancelableChanged(bool)));
- connect(trans, SIGNAL(finished(QApt::ExitStatus)), trans, SLOT(deleteLater()));
- connect(trans, SIGNAL(statusChanged(QApt::TransactionStatus)),
- this, SLOT(statusChanged(QApt::TransactionStatus)));
- connect(trans, SIGNAL(mediumRequired(QString,QString)),
- this, SLOT(provideMedium(QString,QString)));
- connect(trans, SIGNAL(promptUntrusted(QStringList)),
- this, SLOT(untrustedPrompt(QStringList)));
- connect(trans, SIGNAL(configFileConflict(QString,QString)),
- this, SLOT(configFileConflict(QString,QString)));
- connect(trans, SIGNAL(downloadSpeedChanged(quint64)),
- this, SIGNAL(downloadSpeedChanged(quint64)));
- connect(trans, SIGNAL(finished(QApt::ExitStatus)),
- this, SLOT(transactionFinished(QApt::ExitStatus)));
-}
-
-void ApplicationUpdates::transactionFinished(QApt::ExitStatus )
-{
- m_lastRealProgress = 0;
- m_updatesCache.clear();
- m_toUpdate.clear();
- m_appBackend->reload();
- setProgressing(false);
-}
-
-
-QDateTime ApplicationUpdates::lastUpdate() const
-{
- return m_aptBackend->timeCacheLastUpdated();
-}
-
-bool ApplicationUpdates::isCancelable() const
-{
- return m_trans && m_trans->isCancellable();
-}
-
-bool ApplicationUpdates::isProgressing() const
-{
- return m_progressing;
-}
-
-void ApplicationUpdates::provideMedium(const QString &label, const QString &medium)
-{
- QString title = i18nc("@title:window", "Media Change Required");
- QString text = xi18nc("@label", "Please insert %1 into <filename>%2</filename>",
- label, medium);
-
- KMessageBox::information(QAptActions::self()->mainWindow(), text, title);
- m_trans->provideMedium(medium);
-}
-
-void ApplicationUpdates::untrustedPrompt(const QStringList &untrustedPackages)
-{
- QString title = i18nc("@title:window", "Warning - Unverified Software");
- QString text = xi18ncp("@label",
- "The following piece of software cannot be verified. "
- "<warning>Installing unverified software represents a "
- "security risk, as the presence of unverifiable software "
- "can be a sign of tampering.</warning> Do you wish to continue?",
- "The following pieces of software cannot be verified. "
- "<warning>Installing unverified software represents a "
- "security risk, as the presence of unverifiable software "
- "can be a sign of tampering.</warning> Do you wish to continue?",
- untrustedPackages.size());
- int result = KMessageBox::warningContinueCancelList(QAptActions::self()->mainWindow(),
- text, untrustedPackages, title);
-
- bool installUntrusted = (result == KMessageBox::Continue);
- m_trans->replyUntrustedPrompt(installUntrusted);
-}
-
-void ApplicationUpdates::configFileConflict(const QString &currentPath, const QString &newPath)
-{
- QString title = i18nc("@title:window", "Configuration File Changed");
- QString text = xi18nc("@label Notifies a config file change",
- "A new version of the configuration file "
- "<filename>%1</filename> is available, but your version has "
- "been modified. Would you like to keep your current version "
- "or install the new version?", currentPath);
-
- KGuiItem useNew(i18nc("@action Use the new config file", "Use New Version"));
- KGuiItem useOld(i18nc("@action Keep the old config file", "Keep Old Version"));
-
- // TODO: diff current and new paths
- Q_UNUSED(newPath)
-
- int ret = KMessageBox::questionYesNo(QAptActions::self()->mainWindow(), text, title, useNew, useOld);
-
- m_trans->resolveConfigFileConflict(currentPath, (ret == KMessageBox::Yes));
-}
-
-void ApplicationUpdates::statusChanged(QApt::TransactionStatus status)
-{
- switch (status) {
- case QApt::SetupStatus:
- setProgressing(true);
- setStatusMessage(i18nc("@info Status info, widget title",
- "Starting"));
- setProgress(-1);
- break;
- case QApt::AuthenticationStatus:
- setStatusMessage(i18nc("@info Status info, widget title",
- "Waiting for Authentication"));
- setProgress(-1);
- break;
- case QApt::WaitingStatus:
- setStatusMessage(i18nc("@info Status information, widget title",
- "Waiting"));
- setStatusDetail(i18nc("@info Status info",
- "Waiting for other transactions to finish"));
- setProgress(-1);
- break;
- case QApt::WaitingLockStatus:
- setStatusMessage(i18nc("@info Status information, widget title",
- "Waiting"));
- setStatusDetail(i18nc("@info Status info",
- "Waiting for other software managers to quit"));
- setProgress(-1);
- break;
- case QApt::WaitingMediumStatus:
- setStatusMessage(i18nc("@info Status information, widget title",
- "Waiting"));
- setStatusDetail(i18nc("@info Status info",
- "Waiting for required medium"));
- setProgress(-1);
- break;
- case QApt::WaitingConfigFilePromptStatus:
- setStatusMessage(i18nc("@info Status information, widget title",
- "Waiting"));
- setStatusDetail(i18nc("@info Status info",
- "Waiting for configuration file"));
- setProgress(-1);
- break;
- case QApt::RunningStatus:
- setStatusMessage(QString());
- setStatusDetail(QString());
- break;
- case QApt::LoadingCacheStatus:
- setStatusDetail(QString());
- setStatusMessage(i18nc("@info Status info",
- "Loading Software List"));
- break;
- case QApt::DownloadingStatus:
- switch (m_trans->role()) {
- case QApt::UpdateCacheRole:
- setStatusMessage(i18nc("@info Status information, widget title",
- "Updating software sources"));
- break;
- case QApt::DownloadArchivesRole:
- case QApt::CommitChangesRole:
- setStatusMessage(i18nc("@info Status information, widget title",
- "Downloading Packages"));
- break;
- default:
- break;
- }
- break;
- case QApt::CommittingStatus:
- emit downloadSpeedChanged(-1);
- setStatusMessage(i18nc("@info Status information, widget title",
- "Applying Changes"));
- setStatusDetail(QString());
- break;
- case QApt::FinishedStatus:
- setProgress(100);
- setStatusMessage(i18nc("@info Status information, widget title",
- "Finished"));
- break;
- }
-}
-
-void ApplicationUpdates::setProgressing(bool progressing)
-{
- if(progressing!=m_progressing) {
- m_progressing = progressing;
- emit progressingChanged(progressing);
-
- if(m_progressing)
- setProgress(-1);
- else
- restoreToCleanCache();
- }
-}
-
-void ApplicationUpdates::setStatusDetail(const QString& msg)
-{
- if(m_statusDetail!=msg) {
- m_statusDetail = msg;
- emit statusDetailChanged(msg);
- }
-}
-
-void ApplicationUpdates::setStatusMessage(const QString& msg)
-{
- if(m_statusMessage!=msg) {
- m_statusMessage = msg;
- emit statusMessageChanged(msg);
- }
-}
-
-QString ApplicationUpdates::statusDetail() const
-{
- return m_statusDetail;
-}
-
-QString ApplicationUpdates::statusMessage() const
-{
- return m_statusMessage;
-}
-
-void ApplicationUpdates::cancel()
-{
- Q_ASSERT(m_trans->isCancellable());
- m_trans->cancel();
-}
-
-quint64 ApplicationUpdates::downloadSpeed() const
-{
- return m_trans->downloadSpeed();
-}
-
-void ApplicationUpdates::fetchingChanged()
-{
- if(m_appBackend && m_appBackend->isFetching())
- return;
-
- calculateUpdates();
- setProgressing(false);
-}
-
-void ApplicationUpdates::calculateUpdates()
-{
- m_toUpdate.clear();
- auto changes = m_aptBackend->stateChanges(m_updatesCache, QApt::PackageList());
- Q_FOREACH (const auto &pkgList, changes) {
- Q_FOREACH (QApt::Package* it, pkgList) {
- AbstractResource* res = m_appBackend->resourceByPackageName(it->name());
- if(!res) //If we couldn't find it by its name, try with
- res = m_appBackend->resourceByPackageName(QStringLiteral("%1:%2").arg(it->name()).arg(it->architecture()));
-
- if(res) {
- if (res->state() == Application::Upgradeable)
- m_toUpdate += res;
- } else {
- qWarning() << "Couldn't find the package:" << it->name();
- }
- Q_ASSERT(res);
- }
- }
-}
-
-bool ApplicationUpdates::isMarked(AbstractResource* res) const
-{
- Q_ASSERT(!res->backend()->isFetching());
- Application* app = qobject_cast<Application*>(res);
- Q_ASSERT(app);
- return app->package()->state() & QApt::Package::ToInstall;
-}
diff --git a/libdiscover/backends/ApplicationBackend/ApplicationUpdates.h b/libdiscover/backends/ApplicationBackend/ApplicationUpdates.h
deleted file mode 100644
index e30b8a4..0000000
--- a/libdiscover/backends/ApplicationBackend/ApplicationUpdates.h
+++ /dev/null
@@ -1,97 +0,0 @@
-/***************************************************************************
- * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.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 APPLICATIONUPDATES_H
-#define APPLICATIONUPDATES_H
-
-// Qt includes
-#include <QtCore/QObject>
-#include <QPointer>
-
-// QApt includes
-#include <QApt/Globals>
-
-// Own includes
-#include "resources/AbstractBackendUpdater.h"
-
-namespace QApt {
- class Backend;
- class Transaction;
-}
-
-class ApplicationBackend;
-
-class ApplicationUpdates : public AbstractBackendUpdater
-{
- Q_OBJECT
-public:
- explicit ApplicationUpdates(ApplicationBackend* parent);
-
- bool hasUpdates() const override;
- qreal progress() const override;
- void start() override;
- void setBackend(QApt::Backend* backend);
- long unsigned int remainingTime() const override;
- void addResources(const QList<AbstractResource*>& apps) override;
- void removeResources(const QList<AbstractResource*>& apps) override;
- QList<AbstractResource*> toUpdate() const override;
- QDateTime lastUpdate() const override;
- bool isCancelable() const override;
- bool isProgressing() const override;
- QString statusDetail() const override;
- QString statusMessage() const override;
- void cancel() override;
- quint64 downloadSpeed() const override;
- void prepare() override;
- void setupTransaction(QApt::Transaction *trans);
- bool isMarked(AbstractResource* res) const override;
- void setProgressing(bool progressing);
-
-private:
- void restoreToCleanCache();
-
- QPointer<QApt::Transaction> m_trans;
- QApt::Backend* m_aptBackend;
- ApplicationBackend* m_appBackend;
- int m_lastRealProgress;
- long unsigned int m_eta;
- QApt::CacheState m_updatesCache;
- bool m_progressing;
- QString m_statusMessage;
- QString m_statusDetail;
- QList<AbstractResource*> m_toUpdate;
-
-private Q_SLOTS:
- void errorOccurred(QApt::ErrorCode error);
- void setProgress(int progress);
- void etaChanged(quint64 eta);
- void installMessage(const QString& message);
- void provideMedium(const QString &label, const QString &medium);
- void untrustedPrompt(const QStringList &untrustedPackages);
- void configFileConflict(const QString &currentPath, const QString &newPath);
- void statusChanged(QApt::TransactionStatus status);
- void setStatusMessage(const QString& msg);
- void setStatusDetail(const QString& msg);
- void fetchingChanged();
- void calculateUpdates();
- void transactionFinished(QApt::ExitStatus);
-};
-
-#endif // APPLICATIONUPDATES_H
diff --git a/libdiscover/backends/ApplicationBackend/AptSourcesBackend.cpp b/libdiscover/backends/ApplicationBackend/AptSourcesBackend.cpp
deleted file mode 100644
index 067a69a..0000000
--- a/libdiscover/backends/ApplicationBackend/AptSourcesBackend.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/***************************************************************************
- * Copyright © 2014 Aleix Pol Gonzalez <aleixpol@blue-systems.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 "AptSourcesBackend.h"
-#include "ApplicationBackend.h"
-#include <QAptActions.h>
-#include <qapt/sourceentry.h>
-#include <kauthexecutejob.h>
-#include <KActionCollection>
-#include <KLocalizedString>
-#include <KMessageWidget>
-#include <KMessageBox>
-#include <QProcess>
-
-class EntryItem : public QStandardItem
-{
-public:
- explicit EntryItem(const QApt::SourceEntry &sEntry)
- : m_sEntry(sEntry)
- {}
- QApt::SourceEntry& sourceEntry() { return m_sEntry; }
-
-private:
- QApt::SourceEntry m_sEntry;
-};
-
-class SourceItem : public QStandardItem
-{
-public:
- explicit SourceItem(QUrl uri)
- : m_uri(std::move(uri))
- {}
-
- QVariant data(int role = Qt::UserRole + 1) const override;
- QUrl uri() const { return m_uri; }
-
-private:
- QUrl m_uri;
-};
-
-AptSourcesBackend::AptSourcesBackend(ApplicationBackend* backend)
- : AbstractSourcesBackend(backend)
- , m_sources(new QStandardItemModel(this))
-{
- connect(backend, SIGNAL(fetchingChanged()), SLOT(load()), Qt::UniqueConnection);
- if (!backend->isFetching()) {
- load();
- }
-}
-
-void AptSourcesBackend::load()
-{
- m_sources->clear();
-
- Q_FOREACH (const QApt::SourceEntry &sEntry, m_sourcesList.entries()) {
- if (!sEntry.isValid()) {
- continue;
-}
-
- SourceItem* newSource = sourceForUri(sEntry.uri());
- auto entry = new EntryItem(sEntry);
- newSource->appendRow(entry);
- }
-}
-
-SourceItem* AptSourcesBackend::sourceForUri(const QString& uri)
-{
- QUrl uriUrl(uri);
-
- for(int r = 0, c = m_sources->rowCount(); r<c; ++r) {
- SourceItem* s = static_cast<SourceItem*>(m_sources->item(r));
- if(s->uri()==uriUrl)
- return s;
- }
- SourceItem* s = new SourceItem(uriUrl);
- s->setData(uriUrl, UriRole);
- m_sources->appendRow(s);
- return s;
-}
-
-QAbstractItemModel* AptSourcesBackend::sources()
-{
- return m_sources;
-}
-
-bool AptSourcesBackend::removeSource(const QString& repository)
-{
- KAuth::Action readAction(QStringLiteral("org.kde.discover.repo.modify"));
- readAction.setHelperId(QStringLiteral("org.kde.discover.repo"));
- QVariantMap args = {
- { QStringLiteral("repository"), repository },
- { QStringLiteral("action"), QStringLiteral("remove") }
- };
- readAction.setArguments(args);
- qDebug() << "removing..." << args;
- KAuth::ExecuteJob* reply = readAction.execute();
- removalDone(reply->error());
- return true;
-}
-
-bool AptSourcesBackend::addSource(const QString& repository)
-{
- KAuth::Action readAction(QStringLiteral("org.kde.discover.repo.modify"));
- readAction.setHelperId(QStringLiteral("org.kde.discover.repo"));
- QVariantMap args = {
- { QStringLiteral("repository"), repository },
- { QStringLiteral("action"), QStringLiteral("add") }
- };
- readAction.setArguments(args);
- qDebug() << "adding..." << args;
- KAuth::ExecuteJob* reply = readAction.execute();
- additionDone(reply->error());
- return true;
-}
-
-void AptSourcesBackend::additionDone(int processErrorCode)
-{
- if(processErrorCode==0) {
- load();
- QMetaObject::invokeMethod(appsBackend(), "reload");
- } else {
- QProcess* p = qobject_cast<QProcess*>(sender());
- Q_ASSERT(p);
- QByteArray errorMessage = p->readAllStandardOutput();
- if(!errorMessage.isEmpty())
- KMessageBox::error(0, QString::fromUtf8(errorMessage), i18n("Adding Origins..."));
- }
-}
-
-void AptSourcesBackend::removalDone(int processErrorCode)
-{
- if(processErrorCode==0) {
- load();
- QMetaObject::invokeMethod(appsBackend(), "reload");
- } else {
- QProcess* p = qobject_cast<QProcess*>(sender());
- Q_ASSERT(p);
- QByteArray errorMessage = p->readAllStandardOutput();
- if(!errorMessage.isEmpty())
- KMessageBox::error(0, QString::fromUtf8(errorMessage), i18n("Removing Origins..."));
- }
-}
-
-ApplicationBackend* AptSourcesBackend::appsBackend() const
-{
- return qobject_cast<ApplicationBackend*>(parent());
-}
-
-QVariant SourceItem::data(int role) const
-{
- switch(role) {
- case Qt::DisplayRole: {
-// modelData.name=="" ? modelData.uri : i18n("%1. %2", modelData.name, modelData.uri)
- QApt::Backend* backend = qobject_cast<AptSourcesBackend*>(model()->parent())->appsBackend()->backend();
- QStringList origins = !m_uri.host().isEmpty() ? backend->originsForHost(m_uri.host()) : QStringList();
-
- if(origins.size()==1)
- return origins.first();
- else if(origins.size()==0)
- return m_uri.toDisplayString();
- else {
- QString path = m_uri.path();
- int firstSlash = path.indexOf(QLatin1Char('/'), 1);
- int secondSlash = path.indexOf(QLatin1Char('/'), firstSlash+1);
- QString launchpadifyUri = path.mid(1,secondSlash-1).replace(QLatin1Char('/'), QLatin1Char('-'));
- QStringList results = origins.filter(launchpadifyUri, Qt::CaseInsensitive);
- if(results.isEmpty()) {
- launchpadifyUri = path.mid(1,firstSlash-1).replace(QLatin1Char('/'), QLatin1Char('-'));
- results = origins.filter(launchpadifyUri, Qt::CaseInsensitive);
- }
- return results.isEmpty() ? QString() : results.first();
- }
- }
- case Qt::ToolTipRole: {
- QMap<QString, int> vals;
- for(int i=0, c=rowCount(); i<c; ++i) {
- EntryItem* entry = static_cast<EntryItem*>(child(i));
-
- QString suite = entry->sourceEntry().dist();
- if(!vals.contains(suite))
- vals[suite]=0;
-
- bool hasSource = entry->sourceEntry().type() == QLatin1String("deb-src");
- if(hasSource)
- vals[suite] += 2;
- else
- vals[suite] += 1;
- }
- QStringList ret;
- Q_FOREACH (const QString& e, vals.keys()) {
- if(vals[e]>1)
- ret.append(e);
- else
- ret.append(i18n("%1 (Binary)", e));
- }
-
- return ret.join(QStringLiteral(", "));
- }
- default:
- return QStandardItem::data(role);
- }
-}
-
-QString AptSourcesBackend::idDescription()
-{
- return i18n( "<sourceline> - The apt repository source line to add. This is one of:\n"
- " a complete apt line, \n"
- " a repo url and areas (areas defaults to 'main')\n"
- " a PPA shortcut.\n\n"
-
- " Examples:\n"
- " deb http://myserver/path/to/repo stable myrepo\n"
- " http://myserver/path/to/repo myrepo\n"
- " https://packages.medibuntu.org free non-free\n"
- " http://extras.ubuntu.com/ubuntu\n"
- " ppa:user/repository");
-}
-
-QString AptSourcesBackend::name() const
-{
- return i18n("Software Management");
-}
-
-QList<QAction*> AptSourcesBackend::actions() const
-{
- return { QAptActions::self()->actionCollection()->action(QStringLiteral("software_properties")) };
-}
diff --git a/libdiscover/backends/ApplicationBackend/AptSourcesBackend.h b/libdiscover/backends/ApplicationBackend/AptSourcesBackend.h
deleted file mode 100644
index b7dcc82..0000000
--- a/libdiscover/backends/ApplicationBackend/AptSourcesBackend.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/***************************************************************************
- * Copyright © 2014 Aleix Pol Gonzalez <aleixpol@blue-systems.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 APTSOURCESBACKEND_H
-#define APTSOURCESBACKEND_H
-
-#include <QStandardItemModel>
-#include <resources/AbstractSourcesBackend.h>
-#include <QApt/SourcesList>
-
-class ApplicationBackend;
-class SourceItem;
-
-class AptSourcesBackend : public AbstractSourcesBackend
-{
-Q_OBJECT
-public:
- enum Roles {
- UriRole
- };
-
- explicit AptSourcesBackend(ApplicationBackend* backend);
- QAbstractItemModel* sources() override;
- bool removeSource(const QString& repository) override;
- bool addSource(const QString& repository) override;
- QString idDescription() override;
- QString name() const override;
- ApplicationBackend* appsBackend() const;
- QList<QAction*> actions() const override;
-
-private Q_SLOTS:
- void load();
- void removalDone(int processErrorCode);
- void additionDone(int processErrorCode);
-
-private:
- SourceItem* sourceForUri(const QString& uri);
-
- QStandardItemModel* m_sources;
- QApt::SourcesList m_sourcesList;
-};
-
-#endif // APTSOURCESBACKEND_H
diff --git a/libdiscover/backends/ApplicationBackend/CMakeLists.txt b/libdiscover/backends/ApplicationBackend/CMakeLists.txt
deleted file mode 100644
index cc7b35f..0000000
--- a/libdiscover/backends/ApplicationBackend/CMakeLists.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-# we will have our own fork of the library now, because they haven't still made their mind out of Qt5
-# find_package(QtOAuth REQUIRED)
-add_subdirectory(qoauth)
-add_subdirectory(libmuonapt)
-
-include_directories(.)
-
-add_subdirectory(tests)
-
-set(appsbackend_SRCS
- ApplicationBackend.cpp
- Application.cpp
- ApplicationUpdates.cpp
- ReviewsBackend.cpp #TODO: rename to AptReviewsBackend
- UbuntuLoginBackend.cpp
- AptSourcesBackend.cpp
-)
-
-qt5_add_dbus_interface(appsbackend_SRCS ubuntu_sso_dbus_interface.xml ubuntu_sso OPTIONS -i "LoginMetaTypes.h")
-
-add_library(qapt-backend MODULE ${appsbackend_SRCS})
-target_link_libraries(qapt-backend Qt5::Widgets Qt5::DBus Qt5::Concurrent
- KF5::Archive KF5::KIOWidgets KF5::XmlGui DebconfKDE::Main KF5::IconThemes AppstreamQt
- Muon::QOAuth QApt::Main Discover::Common MuonApt
-)
-target_include_directories(qapt-backend PRIVATE /usr/include/Qca-qt5/QtCrypto)
-
-install(TARGETS qapt-backend DESTINATION ${PLUGIN_INSTALL_DIR}/discover)
-install(FILES qapt-backend.desktop DESTINATION ${DATA_INSTALL_DIR}/libdiscover/backends)
-install(FILES distupgradeevent/releasechecker DESTINATION ${DATA_INSTALL_DIR}/libdiscover/applicationsbackend/
- PERMISSIONS
- OWNER_EXECUTE OWNER_READ OWNER_WRITE
- GROUP_EXECUTE GROUP_READ
- WORLD_EXECUTE WORLD_READ
-)
-
-foreach(testing IN ITEMS ON OFF)
- set(name MuonApplicationNotifier)
- set(type MODULE)
- if(${testing})
- set(name MuonApplicationNotifierTestLib)
- set(type STATIC)
- endif()
- add_library(${name} ${type} ApplicationNotifier.cpp)
- target_compile_definitions(${name} PRIVATE -DCMAKE_INSTALL_FULL_LIBEXECDIR_KF5=\"${CMAKE_INSTALL_FULL_LIBEXECDIR_KF5}\")
- target_link_libraries(${name} KF5::CoreAddons KF5::I18n KF5::Notifications KF5::IconThemes Discover::Notifiers)
-endforeach()
-
-install(TARGETS MuonApplicationNotifier DESTINATION ${PLUGIN_INSTALL_DIR}/discover-notifier)
-install(FILES muonapplicationnotifier.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR})
-
-install(FILES ../PackageKitBackend/packagekit-backend-categories.xml DESTINATION ${DATA_INSTALL_DIR}/libdiscover/categories/ RENAME qapt-backend-categories.xml)
-# add_subdirectory(${CMAKE_SOURCE_DIR}/libdiscover/backends/PackageKitBackend/categoryimages)
diff --git a/libdiscover/backends/ApplicationBackend/ReviewsBackend.cpp b/libdiscover/backends/ApplicationBackend/ReviewsBackend.cpp
deleted file mode 100644
index ae97868..0000000
--- a/libdiscover/backends/ApplicationBackend/ReviewsBackend.cpp
+++ /dev/null
@@ -1,411 +0,0 @@
-/***************************************************************************
- * Copyright © 2011 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 "ReviewsBackend.h"
-
-#include <QtCore/QStringBuilder>
-#include <QtCore/QLocale>
-#include <QDebug>
-#include <QJsonDocument>
-#include <QTemporaryFile>
-#include <QStandardPaths>
-#include <QFileInfo>
-#include <QDir>
-
-#include <KIO/Job>
-#include <KLocalizedString>
-#include <KCompressionDevice>
-
-#include <QApt/Backend>
-
-#include <qoauth/src/interface.h>
-
-#include <Application.h>
-#include <ReviewsBackend/Rating.h>
-#include <ReviewsBackend/Review.h>
-#include <ReviewsBackend/AbstractLoginBackend.h>
-#include <ReviewsBackend/PopConParser.h>
-#include "UbuntuLoginBackend.h"
-#include <resources/AbstractResourcesBackend.h>
-#include <MuonDataSources.h>
-
-static QString getCodename(const QString& value)
-{
- QString ret;
- QFile f(QStringLiteral("/etc/os-release"));
- if(f.open(QIODevice::ReadOnly|QIODevice::Text)) {
- QRegExp rx(QStringLiteral("%1=(.+)\n").arg(value));
- while(!f.atEnd()) {
- QString line = QString::fromLatin1(f.readLine());
- if(rx.exactMatch(line)) {
- ret = rx.cap(1);
- break;
- }
- }
- }
- return ret;
-}
-
-ReviewsBackend::ReviewsBackend(QObject *parent)
- : AbstractReviewsBackend(parent)
- , m_aptBackend(nullptr)
- , m_serverBase(MuonDataSources::rnRSource())
-{
- m_distId = getCodename(QStringLiteral("ID"));
- m_loginBackend = new UbuntuLoginBackend(this);
- connect(m_loginBackend, &AbstractLoginBackend::connectionStateChanged, this, &ReviewsBackend::loginStateChanged);
- connect(m_loginBackend, &AbstractLoginBackend::connectionStateChanged, this, &ReviewsBackend::refreshConsumerKeys);
- m_oauthInterface = new QOAuth::Interface(this);
-
- QMetaObject::invokeMethod(this, "fetchRatings", Qt::QueuedConnection);
-}
-
-ReviewsBackend::~ReviewsBackend() = default;
-
-void ReviewsBackend::refreshConsumerKeys()
-{
- if(m_loginBackend->hasCredentials()) {
- m_oauthInterface->setConsumerKey(m_loginBackend->consumerKey());
- m_oauthInterface->setConsumerSecret(m_loginBackend->consumerSecret());
-
- QList<QPair<QString, QVariantMap> >::const_iterator it, itEnd;
- for(it=m_pendingRequests.constBegin(), itEnd=m_pendingRequests.constEnd(); it!=itEnd; ++it) {
- postInformation(it->first, it->second);
- }
- m_pendingRequests.clear();
- }
-}
-
-void ReviewsBackend::setAptBackend(QApt::Backend *aptBackend)
-{
- m_aptBackend = aptBackend;
-}
-
-// void ReviewsBackend::clearReviewCache()
-// {
-// foreach (QList<Review *> reviewList, m_reviewsCache) {
-// qDeleteAll(reviewList);
-// }
-//
-// m_reviewsCache.clear();
-// }
-
-void ReviewsBackend::fetchRatings()
-{
- QString ratingsCache = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/libdiscover/ratings.txt");
- QFileInfo file(ratingsCache);
- QDir::temp().mkpath(file.dir().path());
- QUrl ratingsUrl(m_serverBase.toString()+QStringLiteral("review-stats/"));
- //default to popcon if not using ubuntu
- if(m_distId.toLower() == QLatin1String("ubuntu")){
- refreshConsumerKeys();
- // First, load our old ratings cache in case we don't have net connectivity
- loadRatingsFromFile();
- // Try to fetch the latest ratings from the internet
- } else {
- ratingsUrl = QUrl(QStringLiteral("http://popcon.debian.org/all-popcon-results.gz"));
- }
- KIO::FileCopyJob *getJob = KIO::file_copy(ratingsUrl, QUrl::fromLocalFile(ratingsCache), -1,
- KIO::Overwrite | KIO::HideProgressInfo);
- connect(getJob, &KIO::FileCopyJob::result, this, &ReviewsBackend::ratingsFetched);
-}
-
-void ReviewsBackend::ratingsFetched(KJob *job)
-{
- if (job->error()) {
- qWarning() << "Couldn't fetch the ratings" << job->errorString();
- return;
- }
-
- loadRatingsFromFile();
-}
-
-void ReviewsBackend::loadRatingsFromFile()
-{
- QString ratingsCache = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+QStringLiteral("/libdiscover/ratings.txt");
- QScopedPointer<QIODevice> dev(new KCompressionDevice(ratingsCache, KCompressionDevice::GZip));
- if (!dev->open(QIODevice::ReadOnly)) {
- qWarning() << "Couldn't open ratings.txt" << ratingsCache;
- return;
- }
- if(m_distId.toLower() == QLatin1String("ubuntu")) {
- QJsonParseError error;
- QJsonDocument doc = QJsonDocument::fromJson(dev->readAll(), &error);
-
- if (error.error != QJsonParseError::NoError) {
- qDebug() << "error while parsing ratings: " << ratingsCache;
- return;
- }
-
- QVariant ratings = doc.toVariant();
- qDeleteAll(m_ratings);
- m_ratings.clear();
- foreach (const QVariant &data, ratings.toList()) {
- Rating *rating = new Rating(data.toMap());
- if (rating->ratingCount() == 0u) {
- delete rating;
- continue;
- }
- rating->setParent(this);
- m_ratings[rating->packageName()] = rating;
- }
- } else {
- qDeleteAll(m_ratings);
- m_ratings = PopConParser::parsePopcon(this, dev.data());
- }
- emit ratingsReady();
-}
-
-Rating *ReviewsBackend::ratingForApplication(AbstractResource* app) const
-{
- return m_ratings.value(app->packageName());
-}
-
-void ReviewsBackend::stopPendingJobs()
-{
- for(auto it = m_jobHash.constBegin(); it != m_jobHash.constEnd(); ++it) {
- disconnect(it.key(), SIGNAL(result(KJob*)), this, SLOT(changelogFetched(KJob*)));
- }
- m_jobHash.clear();
-}
-
-void ReviewsBackend::fetchReviews(AbstractResource* res, int page)
-{
- Q_ASSERT(!res->backend()->isFetching());
- Application* app = qobject_cast<Application*>(res);
-
- const QList<Review*> revs = m_reviewsCache.value(app);
- if (revs.size()>(page*10)) { //there are 10 reviews per page
- emit reviewsReady(app, revs.mid(page*10, 10));
- return;
- }
-
- QString lang = getLanguage();
- QString origin = app->package()->origin().toLower();
-
- QString version = QLatin1String("any");
- QString packageName = app->package()->name();
- QString appName = app->name();
- // Replace spaces with %2B for the url
- appName.replace(QLatin1Char(' '), QLatin1String("%2B"));
-
- // Figuring out how this damn Django url was put together took more
- // time than figuring out QJson...
- // But that could be because the Ubuntu Software Center (which I used to
- // figure it out) is written in python, so you have to go hunting to where
- // a variable was initially initialized with a primitive to figure out its type.
- QUrl reviewsUrl(m_serverBase.toString() + QLatin1String("/reviews/filter/") % lang % QLatin1Char('/')
- % origin % QLatin1Char('/') % QLatin1String("any") % QLatin1Char('/') % version % QLatin1Char('/') % packageName
- % QLatin1Char(';') % appName % QLatin1String("/page/") % QString::number(page));
-
- KIO::StoredTransferJob* getJob = KIO::storedGet(reviewsUrl, KIO::NoReload, KIO::Overwrite | KIO::HideProgressInfo);
- m_jobHash[getJob] = app;
- connect(getJob, &KIO::StoredTransferJob::result, this, &ReviewsBackend::reviewsFetched);
-}
-
-static Review* constructReview(const QVariantMap& data)
-{
- QString reviewUsername = data.value(QStringLiteral("reviewer_username")).toString();
- QString reviewDisplayName = data.value(QStringLiteral("reviewer_displayname")).toString();
- QString reviewer = reviewDisplayName.isEmpty() ? reviewUsername : reviewDisplayName;
- return new Review(
- data.value(QStringLiteral("app_name")).toString(),
- data.value(QStringLiteral("package_name")).toString(),
- data.value(QStringLiteral("language")).toString(),
- data.value(QStringLiteral("summary")).toString(),
- data.value(QStringLiteral("review_text")).toString(),
- reviewer,
- QDateTime::fromString(data.value(QStringLiteral("date_created")).toString(), QStringLiteral("yyyy-MM-dd HH:mm:ss")),
- !data.value(QStringLiteral("hide")).toBool(),
- data.value(QStringLiteral("id")).toULongLong(),
- data.value(QStringLiteral("rating")).toInt() * 2,
- data.value(QStringLiteral("usefulness_total")).toInt(),
- data.value(QStringLiteral("usefulness_favorable")).toInt(),
- data.value(QStringLiteral("version")).toString());
-}
-
-void ReviewsBackend::reviewsFetched(KJob *j)
-{
- KIO::StoredTransferJob* job = qobject_cast<KIO::StoredTransferJob*>(j);
- Application *app = m_jobHash.take(job);
- if (job->error() || !app) {
- return;
- }
-
- QJsonParseError error;
- QJsonDocument doc = QJsonDocument::fromJson(job->data(), &error);
-
- if (error.error != QJsonParseError::NoError) {
- return;
- }
- QVariant reviews = doc.toVariant();
-
- QList<Review *> reviewsList;
- foreach (const QVariant &data, reviews.toList()) {
- reviewsList << constructReview(data.toMap());
- }
-
- m_reviewsCache[app].append(reviewsList);
-
- emit reviewsReady(app, reviewsList);
-}
-
-QString ReviewsBackend::getLanguage()
-{
- // The reviews API abbreviates all langs past the _ char except these
- const QStringList fullLangs = { QStringLiteral("pt_BR"), QStringLiteral("zh_CN"), QStringLiteral("zh_TW") };
-
- QString language = QLocale().bcp47Name();
-
- if (fullLangs.contains(language)) {
- return language;
- }
-
- return language.split(QLatin1Char('_')).first();
-}
-
-void ReviewsBackend::submitUsefulness(Review* r, bool useful)
-{
- QVariantMap data = { { QStringLiteral("useful"), useful } };
-
- postInformation(QStringLiteral("reviews/%1/recommendations/").arg(r->id()), data);
-}
-
-void ReviewsBackend::submitReview(AbstractResource* application, const QString& summary,
- const QString& review_text, const QString& rating)
-{
- Application* app = qobject_cast<Application*>(application);
-
- QVariantMap data = {
- { QStringLiteral("app_name"), app->name() },
- { QStringLiteral("package_name"), app->packageName() },
- { QStringLiteral("summary"), summary },
- { QStringLiteral("version"), app->package()->version() },
- { QStringLiteral("review_text"), review_text },
- { QStringLiteral("rating"), rating },
- { QStringLiteral("language"), getLanguage() },
- { QStringLiteral("origin"), app->package()->origin() }
- };
-
- QString distroSeries = getCodename(QStringLiteral("VERSION"));
- if(!distroSeries.isEmpty()){
- data[QStringLiteral("distroseries")] = distroSeries.split(QLatin1Char(' ')).last().remove(QLatin1Char('(')).remove(QLatin1Char(')'));
- }else{
- data[QStringLiteral("distroseries")] = getCodename(QStringLiteral("PRETTY_NAME")).split(QLatin1Char(' ')).last();
- }
- data[QStringLiteral("arch_tag")] = app->package()->architecture();
-
- postInformation(QStringLiteral("reviews/"), data);
-}
-
-void ReviewsBackend::deleteReview(Review* r)
-{
- postInformation(QStringLiteral("reviews/delete/%1/").arg(r->id()), QVariantMap());
-}
-
-void ReviewsBackend::flagReview(Review* r, const QString& reason, const QString& text)
-{
- QVariantMap data = {
- { QStringLiteral("reason"), reason },
- { QStringLiteral("text"), text }
- };
-
- postInformation(QStringLiteral("reviews/%1/flags/").arg(r->id()), data);
-}
-
-QByteArray authorization(QOAuth::Interface* oauth, const QUrl& url, AbstractLoginBackend* login)
-{
- return oauth->createParametersString(url.url(), QOAuth::POST, login->token(), login->tokenSecret(),
- QOAuth::HMAC_SHA1, QOAuth::ParamMap(), QOAuth::ParseForHeaderArguments);
-}
-
-void ReviewsBackend::postInformation(const QString& path, const QVariantMap& data)
-{
- if(!hasCredentials()) {
- m_pendingRequests += qMakePair(path, data);
- login();
- return;
- }
-
- QUrl url(m_serverBase.toString() +QLatin1Char('/')+ path);
- url.setScheme(QStringLiteral("https"));
-
- KIO::StoredTransferJob* job = KIO::storedHttpPost(QJsonDocument::fromVariant(data).toJson(), url, KIO::Overwrite | KIO::HideProgressInfo); //TODO port to QJsonDocument
- job->addMetaData(QStringLiteral("content-type"), QStringLiteral("Content-Type: application/json") );
- job->addMetaData(QStringLiteral("customHTTPHeader"), QStringLiteral("Authorization: ") + QString::fromLatin1(authorization(m_oauthInterface, url, m_loginBackend)));
- connect(job, &KIO::StoredTransferJob::result, this, &ReviewsBackend::informationPosted);
- job->start();
-}
-
-void ReviewsBackend::informationPosted(KJob* j)
-{
- KIO::StoredTransferJob* job = qobject_cast<KIO::StoredTransferJob*>(j);
- if(job->error()==0) {
- qDebug() << "success" << job->data();
- } else {
- qDebug() << "error..." << job->error() << job->errorString() << job->errorText();
- }
-}
-
-bool ReviewsBackend::isFetching() const
-{
- return !m_jobHash.isEmpty();
-}
-
-bool ReviewsBackend::hasCredentials() const
-{
- return m_loginBackend->hasCredentials();
-}
-
-QString ReviewsBackend::userName() const
-{
- Q_ASSERT(m_loginBackend->hasCredentials());
- return m_loginBackend->displayName();
-}
-
-void ReviewsBackend::login()
-{
- Q_ASSERT(!m_loginBackend->hasCredentials());
- m_loginBackend->login();
-}
-
-void ReviewsBackend::registerAndLogin()
-{
- Q_ASSERT(!m_loginBackend->hasCredentials());
- m_loginBackend->registerAndLogin();
-}
-
-void ReviewsBackend::logout()
-{
- Q_ASSERT(m_loginBackend->hasCredentials());
- m_loginBackend->logout();
-}
-
-QString ReviewsBackend::errorMessage() const
-{
- return i18n("No reviews available for Debian.");
-}
-
-bool ReviewsBackend::isReviewable() const
-{
- QString m_distId = getCodename(QLatin1String("ID"));
- return m_distId == QLatin1String("ubuntu");
-}
-
diff --git a/libdiscover/backends/ApplicationBackend/ReviewsBackend.h b/libdiscover/backends/ApplicationBackend/ReviewsBackend.h
deleted file mode 100644
index 3164831..0000000
--- a/libdiscover/backends/ApplicationBackend/ReviewsBackend.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/***************************************************************************
- * Copyright © 2011 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 REVIEWSBACKEND_H
-#define REVIEWSBACKEND_H
-
-#include <QtCore/QString>
-#include <QtCore/QUrl>
-#include <QtCore/QVariant>
-
-#include "discovercommon_export.h"
-#include <ReviewsBackend/AbstractReviewsBackend.h>
-
-namespace QOAuth {
- class Interface;
-}
-
-class KJob;
-class KTemporaryFile;
-
-namespace QApt {
- class Backend;
-}
-
-class AbstractLoginBackend;
-class Application;
-class Rating;
-class Review;
-
-class DISCOVERCOMMON_EXPORT ReviewsBackend : public AbstractReviewsBackend
-{
- Q_OBJECT
-public:
- explicit ReviewsBackend(QObject *parent);
- ~ReviewsBackend() override;
-
- Rating *ratingForApplication(AbstractResource *app) const override;
-
- void setAptBackend(QApt::Backend *aptBackend);
- void fetchReviews(AbstractResource* res, int page=1) override;
-// void clearReviewCache();
- void stopPendingJobs();
- bool isFetching() const override;
-
- QString userName() const override;
- bool hasCredentials() const override;
- QString errorMessage() const override;
- bool isReviewable() const override;
-
-Q_SIGNALS:
- void ratingsReady();
-
-private:
- QApt::Backend *m_aptBackend;
-
- QString m_distId;
- const QUrl m_serverBase;
- QHash<QString, Rating *> m_ratings;
- // cache key is package name + app name, since both by their own may not be unique
- QHash<Application*, QList<Review *> > m_reviewsCache;
- QHash<KJob *, Application *> m_jobHash;
-
- void loadRatingsFromFile();
- QString getLanguage();
- AbstractLoginBackend* m_loginBackend;
- QOAuth::Interface* m_oauthInterface;
- QList<QPair<QString, QVariantMap> > m_pendingRequests;
-
-private Q_SLOTS:
- void ratingsFetched(KJob *job);
- void reviewsFetched(KJob *j);
- void informationPosted(KJob* j);
- void postInformation(const QString& path, const QVariantMap& data);
- void fetchRatings();
-
-public Q_SLOTS:
- void login() override;
- void registerAndLogin() override;
- void logout() override;
- void submitUsefulness(Review* r, bool useful) override;
- void submitReview(AbstractResource* application, const QString& summary,
- const QString& review_text, const QString& rating) override;
- void deleteReview(Review* r) override;
- void flagReview(Review* r, const QString& reason, const QString &text) override;
- void refreshConsumerKeys();
-};
-
-#endif
diff --git a/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.cpp b/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.cpp
deleted file mode 100644
index f73a8cb..0000000
--- a/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.cpp
+++ /dev/null
@@ -1,147 +0,0 @@
-/***************************************************************************
- * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.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 "UbuntuLoginBackend.h"
-#include <QDebug>
-#include <QDBusMetaType>
-#include <QApplication>
-#include <QWidget>
-#include <KLocalizedString>
-#include "ubuntu_sso.h"
-
-//NOTE: this is needed because the method is called register. see the xml file for more info
-struct HackedComUbuntuSsoCredentialsManagementInterface : public ComUbuntuSsoCredentialsManagementInterface
-{
- HackedComUbuntuSsoCredentialsManagementInterface(const QString& service, const QString& path, const QDBusConnection& connection, QObject* parent = nullptr)
- : ComUbuntuSsoCredentialsManagementInterface(service, path, connection, parent)
- {}
-
- inline QDBusPendingReply<> register_hack(const QString &app_name, const QMap<QString,QString>& args)
- {
- QList<QVariant> argumentList;
- argumentList << QVariant::fromValue(app_name) << QVariant::fromValue(args);
- return asyncCallWithArgumentList(QLatin1String("register"), argumentList);
- }
-};
-
-UbuntuLoginBackend::UbuntuLoginBackend(QObject* parent)
- : AbstractLoginBackend(parent)
-{
- qDBusRegisterMetaType< QMap<QString,QString> >();
- m_interface = new HackedComUbuntuSsoCredentialsManagementInterface( QStringLiteral("com.ubuntu.sso"), QStringLiteral("/com/ubuntu/sso/credentials"), QDBusConnection::sessionBus(), this);
- connect(m_interface, &HackedComUbuntuSsoCredentialsManagementInterface::CredentialsError, this, &UbuntuLoginBackend::credentialsError);
- connect(m_interface, &HackedComUbuntuSsoCredentialsManagementInterface::AuthorizationDenied, this, &UbuntuLoginBackend::authorizationDenied);
- connect(m_interface, &HackedComUbuntuSsoCredentialsManagementInterface::CredentialsFound, this, &UbuntuLoginBackend::successfulLogin);
-
- m_interface->find_credentials(appname(), QMap<QString,QString>());
-}
-
-void UbuntuLoginBackend::login()
-{
- QMap<QString,QString> data;
- data[QStringLiteral("help_text")] = i18n("Log in to the Ubuntu SSO service");
- data[QStringLiteral("window_id")] = winId();
- QDBusPendingReply< void > ret = m_interface->login(appname(), data);
-}
-
-void UbuntuLoginBackend::registerAndLogin()
-{
- QMap<QString,QString> data;
- data[QStringLiteral("help_text")] = i18n("Log in to the Ubuntu SSO service");
- data[QStringLiteral("window_id")] = winId();
- m_interface->register_hack(appname(), data);
-}
-
-QString UbuntuLoginBackend::displayName() const
-{
- return m_credentials[QStringLiteral("name")];
-}
-
-bool UbuntuLoginBackend::hasCredentials() const
-{
- return !m_credentials.isEmpty();
-}
-
-void UbuntuLoginBackend::successfulLogin(const QString& app, const QMap<QString,QString>& credentials)
-{
-// qDebug() << "logged in" << appname() << app << credentials;
- if(app==appname()) {
- m_credentials = credentials;
- emit connectionStateChanged();
- }
-}
-
-QString UbuntuLoginBackend::appname() const
-{
- return QCoreApplication::instance()->applicationName();
-}
-
-QString UbuntuLoginBackend::winId() const
-{
- QString windowId;
- QApplication *app = qobject_cast<QApplication*>(qApp);
-
- if (app->activeWindow())
- windowId = QString::number(app->activeWindow()->winId());
-
- return windowId;
-}
-
-void UbuntuLoginBackend::authorizationDenied(const QString& app)
-{
- qDebug() << "denied" << app;
- if(app==appname())
- emit connectionStateChanged();
-}
-
-void UbuntuLoginBackend::credentialsError(const QString& app, const QMap<QString,QString>& a)
-{
- //TODO: provide error message?
- qDebug() << "error" << app << a;
- if(app==appname())
- emit connectionStateChanged();
-}
-
-void UbuntuLoginBackend::logout()
-{
- m_interface->clear_credentials(appname(), QMap<QString,QString>());
- m_credentials.clear();
- emit connectionStateChanged();
-}
-
-QByteArray UbuntuLoginBackend::token() const
-{
- return m_credentials[QStringLiteral("token")].toLatin1();
-}
-
-QByteArray UbuntuLoginBackend::tokenSecret() const
-{
- return m_credentials[QStringLiteral("token_secret")].toLatin1();
-}
-
-QByteArray UbuntuLoginBackend::consumerKey() const
-{
- return m_credentials[QStringLiteral("consumer_key")].toLatin1();
-}
-
-QByteArray UbuntuLoginBackend::consumerSecret() const
-{
- return m_credentials[QStringLiteral("consumer_secret")].toLatin1();
-}
diff --git a/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.h b/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.h
deleted file mode 100644
index 741bb00..0000000
--- a/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.h
+++ /dev/null
@@ -1,57 +0,0 @@
-/***************************************************************************
- * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.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 UBUNTULOGINBACKEND_H
-#define UBUNTULOGINBACKEND_H
-
-#include <ReviewsBackend/AbstractLoginBackend.h>
-#include <QVariant>
-
-struct HackedComUbuntuSsoCredentialsManagementInterface;
-class UbuntuLoginBackend : public AbstractLoginBackend
-{
- Q_OBJECT
- public:
- explicit UbuntuLoginBackend(QObject* parent=nullptr);
-
- void login() override;
- void registerAndLogin() override;
- void logout() override;
- QString displayName() const override;
- bool hasCredentials() const override;
-
- QByteArray token() const override;
- QByteArray tokenSecret() const override;
- QByteArray consumerKey() const override;
- QByteArray consumerSecret() const override;
-
- private Q_SLOTS:
- void credentialsError(const QString& app, const QMap<QString,QString>& a);
- void authorizationDenied(const QString& app);
- void successfulLogin(const QString& app, const QMap<QString,QString>& credentials);
-
- private:
- QString appname() const;
- QString winId() const;
- HackedComUbuntuSsoCredentialsManagementInterface* m_interface;
- QMap<QString,QString> m_credentials;
-};
-
-#endif // UBUNTULOGINBACKEND_H
diff --git a/libdiscover/backends/ApplicationBackend/distupgradeevent/releasechecker b/libdiscover/backends/ApplicationBackend/distupgradeevent/releasechecker
deleted file mode 100644
index d045f37..0000000
--- a/libdiscover/backends/ApplicationBackend/distupgradeevent/releasechecker
+++ /dev/null
@@ -1,46 +0,0 @@
-#! /usr/bin/python3
-
-# releasechecker.py
-#
-# Copyright (c) 2010 Jonathan Thomas <echidnaman@kubuntu.org>
-#
-# Author: Jonathan Thomas <echidnaman@kubuntu.org>
-#
-# 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/>.
-
-import sys, time
-sys.path.insert(0, '/usr/lib/python3/dist-packages/')
-
-from UpdateManager.Core.MetaRelease import MetaReleaseCore
-from UpdateManager.Core.utils import init_proxy
-
-if __name__ == "__main__":
- """ check for updates, if there are any say so """
-
- init_proxy()
- #FIXME: implement command line options for MetaReleaseCore args
- metaRelease = MetaReleaseCore(False, False)
- while metaRelease.downloading:
- time.sleep(0.5)
- new_dist = metaRelease.new_dist
-
- if new_dist is not None:
- print("Found a release")
- sys.exit(0)
- else:
- sys.exit(1)
-
diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.cpp
deleted file mode 100644
index 7b43707..0000000
--- a/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-#include "AddRepositoryHelper.h"
-#include <QProcess>
-#include <QDebug>
-#include <unistd.h>
-#include <stdlib.h>
-#include <kauthhelpersupport.h>
-
-ActionReply AddRepositoryHelper::modify(QVariantMap args)
-{
- ActionReply reply = ActionReply::SuccessReply();
- if(args[QStringLiteral("repository")].isNull() || args[QStringLiteral("action")].isNull()) {
- reply.setErrorDescription(QStringLiteral("Invalid action arguments."));
- reply = ActionReply::HelperErrorReply();
- return reply;
- }
- QProcess *p = new QProcess(this);
- p->setProcessChannelMode(QProcess::MergedChannels);
- QString modRepo(QStringLiteral("apt-add-repository"));
- QStringList arguments;
- if(args[QStringLiteral("action")].toString() == QLatin1String("add")) {
- arguments.append(QStringLiteral("-y"));
- arguments.append(args[QStringLiteral("repository")].toString());
- } else {
- if(args[QStringLiteral("action")] == QLatin1String("remove"))
- {
- arguments.append(QStringLiteral("--remove"));
- arguments.append(QStringLiteral("-y"));
- arguments.append(args[QStringLiteral("repository")].toString());
- }
- }
- p->start(modRepo,arguments);
- p->waitForFinished();
- if(p->exitCode() != 0) {
- reply.setErrorDescription(QStringLiteral("Could not modify source."));
- reply= ActionReply::HelperErrorReply();
- }
- p->deleteLater();
- return reply;
-}
-
-KAUTH_HELPER_MAIN("org.kde.muon.repo", AddRepositoryHelper)
diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.h b/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.h
deleted file mode 100644
index 4244ca4..0000000
--- a/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.h
+++ /dev/null
@@ -1,15 +0,0 @@
-#ifndef ADDREPOSITORYHELPER_H
-#define ADDREPOSITORYHELPER_H
-
-#include <kauthactionreply.h>
-
-using namespace KAuth;
-
-class AddRepositoryHelper : public QObject
-{
- Q_OBJECT
-public Q_SLOTS:
- ActionReply modify(QVariantMap args);
-};
-
-#endif //ADDREPOSITORYHELPER_H \ No newline at end of file
diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/CMakeLists.txt b/libdiscover/backends/ApplicationBackend/libmuonapt/CMakeLists.txt
deleted file mode 100644
index 536a5c6..0000000
--- a/libdiscover/backends/ApplicationBackend/libmuonapt/CMakeLists.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-add_definitions(-DTRANSLATION_DOMAIN=\"libmuon\")
-
-add_library(MuonApt STATIC ChangesDialog.cpp
- MuonStrings.cpp
- QAptActions.cpp
- HistoryView/HistoryProxyModel.cpp
- HistoryView/HistoryView.cpp)
-
-target_link_libraries(MuonApt Qt5::Core
- KF5::KIOWidgets KF5::XmlGui
- QApt::Main KF5::I18n
-)
-
-target_compile_definitions(MuonApt PRIVATE -DCMAKE_INSTALL_FULL_LIBEXECDIR_KF5=\"${CMAKE_INSTALL_FULL_LIBEXECDIR_KF5}\")
-
-target_include_directories(MuonApt PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
-
-add_executable(muon_repo_helper AddRepositoryHelper.cpp)
-target_link_libraries(muon_repo_helper Qt5::Core KF5::Auth)
-
-install(TARGETS muon_repo_helper DESTINATION ${LIBEXEC_INSTALL_DIR})
-kauth_install_actions(org.kde.muon.repo policies/org.kde.muon.repo.action)
-kauth_install_helper_files(muon_repo_helper org.kde.muon.repo root)
-
-install(TARGETS MuonApt ${INSTALL_TARGETS_DEFAULT_ARGS})
-
diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.cpp
deleted file mode 100644
index 048decc..0000000
--- a/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.cpp
+++ /dev/null
@@ -1,118 +0,0 @@
-/***************************************************************************
- * Copyright © 2011 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 "ChangesDialog.h"
-
-// Qt includes
-#include <QtWidgets/QLabel>
-#include <QtWidgets/QPushButton>
-#include <QtWidgets/QTreeView>
-#include <QtWidgets/QVBoxLayout>
-
-// KDE includes
-#include <KLocalizedString>
-#include <KStandardGuiItem>
-
-// Own includes
-#include "../libmuonapt/MuonStrings.h"
-
-ChangesDialog::ChangesDialog(QWidget *parent, const QApt::StateChanges &changes)
- : QDialog(parent)
-{
- setWindowTitle(i18nc("@title:window", "Confirm Additional Changes"));
- QVBoxLayout *layout = new QVBoxLayout(this);
- setLayout(layout);
-
- QLabel *headerLabel = new QLabel(this);
- headerLabel->setText(i18nc("@info", "<h2>Mark additional changes?</h2>"));
-
- int count = countChanges(changes);
- QLabel *label = new QLabel(this);
- label->setText(i18np("This action requires a change to another package:",
- "This action requires changes to other packages:",
- count));
-
- QTreeView *packageView = new QTreeView(this);
- packageView->setHeaderHidden(true);
- packageView->setRootIsDecorated(false);
-
- QWidget *bottomBox = new QWidget(this);
- QHBoxLayout *bottomLayout = new QHBoxLayout(bottomBox);
- bottomLayout->setSpacing(0);
- bottomLayout->setMargin(0);
- bottomBox->setLayout(bottomLayout);
-
- QWidget *bottomSpacer = new QWidget(bottomBox);
- bottomSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
-
- QPushButton *okButton = new QPushButton(bottomBox);
- KGuiItem okItem = KStandardGuiItem::ok();
- okButton->setText(okItem.text());
- okButton->setIcon(okItem.icon());
- connect(okButton, &QPushButton::clicked, this, &ChangesDialog::accept);
-
- QPushButton *cancelButton = new QPushButton(bottomBox);
- KGuiItem cancelItem = KStandardGuiItem::cancel();
- cancelButton->setText(cancelItem.text());
- cancelButton->setIcon(cancelItem.icon());
- connect(cancelButton, &QPushButton::clicked, this, &ChangesDialog::reject);
-
- bottomLayout->addWidget(bottomSpacer);
- bottomLayout->addWidget(okButton);
- bottomLayout->addWidget(cancelButton);
-
- m_model = new QStandardItemModel(this);
- packageView->setModel(m_model);
- addPackages(changes);
- packageView->expandAll();
- packageView->setEditTriggers(QAbstractItemView::NoEditTriggers);
-
- layout->addWidget(headerLabel);
- layout->addWidget(label);
- layout->addWidget(packageView);
- layout->addWidget(bottomBox);
-}
-
-void ChangesDialog::addPackages(const QApt::StateChanges &changes)
-{
- for (auto i = changes.constBegin(); i != changes.constEnd(); ++i) {
- QStandardItem *root = new QStandardItem;
- root->setText(MuonStrings::global()->packageStateName(i.key()));
-
- QFont font = root->font();
- font.setBold(true);
- root->setFont(font);
-
- Q_FOREACH (QApt::Package *package, *i) {
- root->appendRow(new QStandardItem(QIcon::fromTheme(QStringLiteral("muon")), package->name()));
- }
-
- m_model->appendRow(root);
- }
-}
-
-int ChangesDialog::countChanges(const QApt::StateChanges &changes)
-{
- int count = 0;
- foreach (const QApt::PackageList& pkgs, changes) {
- count += pkgs.size();
- }
- return count;
-}
diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.h b/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.h
deleted file mode 100644
index ed17c46..0000000
--- a/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/***************************************************************************
- * Copyright © 2011 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 CHANGESDIALOG_H
-#define CHANGESDIALOG_H
-
-// Qt includes
-#include <QStandardItemModel>
-#include <QDialog>
-
-// QApt includes
-#include <QApt/Package>
-
-class QStandardItemModel;
-
-class ChangesDialog : public QDialog
-{
-public:
- ChangesDialog(QWidget *parent, const QApt::StateChanges &changes);
-
-private:
- QStandardItemModel *m_model;
-
- void addPackages(const QApt::StateChanges &changes);
- int countChanges(const QApt::StateChanges &changes);
-};
-
-#endif // CHANGESDIALOG_H
diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.cpp
deleted file mode 100644
index 09c9037..0000000
--- a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.cpp
+++ /dev/null
@@ -1,85 +0,0 @@
-/***************************************************************************
- * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 "HistoryProxyModel.h"
-
-#include <QStandardItemModel>
-#include <QStandardItem>
-
-HistoryProxyModel::HistoryProxyModel(QObject *parent)
- : QSortFilterProxyModel(parent)
- , m_stateFilter(static_cast<QApt::Package::State>(0))
-{
-}
-
-HistoryProxyModel::~HistoryProxyModel() = default;
-
-void HistoryProxyModel::search(const QString &searchText)
-{
- m_searchText = searchText;
- invalidate();
-}
-
-void HistoryProxyModel::setStateFilter(QApt::Package::State state)
-{
- m_stateFilter = state;
- invalidate();
-}
-
-bool HistoryProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const
-{
- QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent);
- for(int i = 0 ; i < sourceModel()->rowCount(sourceIndex); i++) {
- if (filterAcceptsRow(i, sourceIndex)) {
- return true;
- }
- }
-
- //Our "main"-method
- QStandardItem *item = static_cast<QStandardItemModel *>(sourceModel())->itemFromIndex(sourceModel()->index(sourceRow, 0, sourceParent));
-
- if (!item) {
- return false;
- }
-
- if (!m_stateFilter == 0) {
- if ((bool)(item->data(HistoryActionRole).toInt() & m_stateFilter) == false) {
- return false;
- }
- }
-
- if (!m_searchText.isEmpty()) {
- if ((bool)(item->data(Qt::DisplayRole).toString().contains(m_searchText)) == false) {
- return false;
- }
- }
-
- return true;
-}
-
-bool HistoryProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
-{
- QStandardItemModel *parentModel = dynamic_cast<QStandardItemModel *>(sourceModel());
-
- QStandardItem *leftItem = parentModel->itemFromIndex(left);
- QStandardItem *rightItem = parentModel->itemFromIndex(right);
-
- return (leftItem->data(HistoryDateRole).toDateTime() > rightItem->data(HistoryDateRole).toDateTime());
-}
diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.h b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.h
deleted file mode 100644
index f5e2cc6..0000000
--- a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/***************************************************************************
- * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 HISTORYPROXYMODEL_H
-#define HISTORYPROXYMODEL_H
-
-#include <QSortFilterProxyModel>
-
-#include <QApt/Package>
-
-class HistoryProxyModel : public QSortFilterProxyModel
-{
- Q_OBJECT
-public:
- enum {
- HistoryDateRole = Qt::UserRole + 1,
- HistoryActionRole = Qt::UserRole + 2
- };
- explicit HistoryProxyModel(QObject *parent);
- ~HistoryProxyModel() override;
-
- void search(const QString &searchText);
- void setStateFilter(QApt::Package::State state);
-
- bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override;
-
-protected:
- bool lessThan(const QModelIndex &left, const QModelIndex &right) const override;
-
-private:
- QString m_searchText;
- QApt::Package::State m_stateFilter;
-};
-
-#endif
diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.cpp
deleted file mode 100644
index 88e6cc5..0000000
--- a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.cpp
+++ /dev/null
@@ -1,238 +0,0 @@
-/***************************************************************************
- * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 "HistoryView.h"
-
-#include <QtCore/QTimer>
-#include <QtWidgets/QLabel>
-#include <QListView>
-#include <QtWidgets/QTreeView>
-#include <QtWidgets/QVBoxLayout>
-#include <QtWidgets/QLineEdit>
-#include <QtWidgets/QComboBox>
-#include <QStandardItemModel>
-
-#include <KLocalizedString>
-
-#include <QApt/History>
-
-#include "HistoryProxyModel.h"
-
-HistoryView::HistoryView(QWidget *parent)
- : QWidget(parent)
-{
- QVBoxLayout* layout = new QVBoxLayout(this);
- setLayout(layout);
- m_history = new QApt::History(this);
-
- QWidget *headerWidget = new QWidget(this);
- QHBoxLayout *headerLayout = new QHBoxLayout(headerWidget);
- headerWidget->setLayout(headerLayout);
-
- QLabel *headerLabel = new QLabel(headerWidget);
- headerLabel->setText(xi18nc("@info", "<title>History</title>"));
-
- QWidget *headerSpacer = new QWidget(headerWidget);
- headerSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
-
- m_searchEdit = new QLineEdit(headerWidget);
- m_searchEdit->setPlaceholderText(i18nc("@label Line edit click message", "Search"));
- m_searchEdit->setClearButtonEnabled(true);
-
- m_searchTimer = new QTimer(this);
- m_searchTimer->setInterval(300);
- m_searchTimer->setSingleShot(true);
- connect(m_searchTimer, &QTimer::timeout, this, &HistoryView::startSearch);
- connect(m_searchEdit, &QLineEdit::textChanged, m_searchTimer, static_cast<void(QTimer::*)()>(&QTimer::start));
-
- m_filterBox = new QComboBox(headerWidget);
- m_filterBox->insertItem(AllChangesItem, QIcon::fromTheme(QStringLiteral("bookmark-new-list")),
- i18nc("@item:inlistbox Filters all changes in the history view",
- "All changes"),
- 0);
- m_filterBox->insertItem(InstallationsItem, QIcon::fromTheme(QStringLiteral("download")),
- i18nc("@item:inlistbox Filters installations in the history view",
- "Installations"),
- QApt::Package::ToInstall);
- m_filterBox->insertItem(UpdatesItem, QIcon::fromTheme(QStringLiteral("system-software-update")),
- i18nc("@item:inlistbox Filters updates in the history view",
- "Updates"),
- QApt::Package::ToUpgrade);
- m_filterBox->insertItem(RemovalsItem, QIcon::fromTheme(QStringLiteral("edit-delete")),
- i18nc("@item:inlistbox Filters removals in the history view",
- "Removals"),
- (QApt::Package::State)(QApt::Package::ToRemove | QApt::Package::ToPurge));
- connect(m_filterBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &HistoryView::setStateFilter);
-
- headerLayout->addWidget(headerLabel);
- headerLayout->addWidget(headerSpacer);
- headerLayout->addWidget(m_searchEdit);
- headerLayout->addWidget(m_filterBox);
-
- m_historyModel = new QStandardItemModel(this);
- m_historyModel->setColumnCount(1);
- m_historyModel->setHeaderData(0, Qt::Horizontal, i18nc("@title:column", "Date"));
- m_historyView = new QTreeView(this);
-
- layout->addWidget(headerWidget);
- layout->addWidget(m_historyView);
-
- QIcon itemIcon(QIcon::fromTheme(QStringLiteral("applications-other")));
-
- QHash<QString, QString> categoryHash;
-
- QHash<PastActions, QString> actionHash;
- actionHash[InstalledAction] = i18nc("@info:status describes a past-tense action", "Installed");
- actionHash[UpgradedAction] = i18nc("@info:status describes a past-tense action", "Upgraded");
- actionHash[DowngradedAction] = i18nc("@status describes a past-tense action", "Downgraded");
- actionHash[RemovedAction] = i18nc("@status describes a past-tense action", "Removed");
- actionHash[PurgedAction] = i18nc("@status describes a past-tense action", "Purged");
-
- Q_FOREACH (const QApt::HistoryItem &item, m_history->historyItems()) {
- QDateTime startDateTime = item.startDate();
- QString formattedTime = startDateTime.toString();
- QString category;
-
- QString date = startDateTime.date().toString();
- if (categoryHash.contains(date)) {
- category = categoryHash.value(date);
- } else {
- category = startDateTime.date().toString(Qt::DefaultLocaleShortDate);
- categoryHash[date] = category;
- }
-
- QStandardItem *parentItem = nullptr;
-
- if (!m_categoryHash.contains(category)) {
- parentItem = new QStandardItem;
- parentItem->setEditable(false);
- parentItem->setText(category);
- parentItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole);
-
- m_historyModel->appendRow(parentItem);
- m_categoryHash[category] = parentItem;
- } else {
- parentItem = m_categoryHash.value(category);
- }
-
- foreach (const QString &package, item.installedPackages()) {
- QStandardItem *historyItem = new QStandardItem;
- historyItem->setEditable(false);
- historyItem->setIcon(itemIcon);
-
- QString action = actionHash.value(InstalledAction);
- QString text = i18nc("@item example: muon installed at 16:00", "%1 %2 at %3",
- package, action, formattedTime);
- historyItem->setText(text);
- historyItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole);
- historyItem->setData(QApt::Package::ToInstall, HistoryProxyModel::HistoryActionRole);
-
- parentItem->appendRow(historyItem);
- }
-
- foreach (const QString &package, item.upgradedPackages()) {
- QStandardItem *historyItem = new QStandardItem;
- historyItem->setEditable(false);
- historyItem->setIcon(itemIcon);
-
- QString action = actionHash.value(UpgradedAction);
- QString text = i18nc("@item example: muon installed at 16:00", "%1 %2 at %3",
- package, action, formattedTime);
- historyItem->setText(text);
- historyItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole);
- historyItem->setData(QApt::Package::ToUpgrade, HistoryProxyModel::HistoryActionRole);
-
- parentItem->appendRow(historyItem);
- }
-
- foreach (const QString &package, item.downgradedPackages()) {
- QStandardItem *historyItem = new QStandardItem;
- historyItem->setEditable(false);
- historyItem->setIcon(itemIcon);
-
- QString action = actionHash.value(DowngradedAction);
- QString text = i18nc("@item example: muon installed at 16:00", "%1 %2 at %3",
- package, action, formattedTime);
- historyItem->setText(text);
- historyItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole);
- historyItem->setData(QApt::Package::ToDowngrade, HistoryProxyModel::HistoryActionRole);
-
- parentItem->appendRow(historyItem);
- }
-
- foreach (const QString &package, item.removedPackages()) {
- QStandardItem *historyItem = new QStandardItem;
- historyItem->setEditable(false);
- historyItem->setIcon(itemIcon);
-
- QString action = actionHash.value(RemovedAction);
- QString text = i18nc("@item example: muon installed at 16:00", "%1 %2 at %3",
- package, action, formattedTime);
- historyItem->setText(text);
- historyItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole);
- historyItem->setData(QApt::Package::ToRemove, HistoryProxyModel::HistoryActionRole);
-
- parentItem->appendRow(historyItem);
- }
-
- foreach (const QString &package, item.purgedPackages()) {
- QStandardItem *historyItem = new QStandardItem;
- historyItem->setEditable(false);
- historyItem->setIcon(itemIcon);
-
- QString action = actionHash.value(PurgedAction);
- QString text = i18nc("@item example: muon installed at 16:00", "%1 %2 at %3",
- package, action, formattedTime);
- historyItem->setText(text);
- historyItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole);
- historyItem->setData(QApt::Package::ToPurge, HistoryProxyModel::HistoryActionRole);
-
- parentItem->appendRow(historyItem);
- }
- }
-
- m_historyView->setMouseTracking(true);
- m_historyView->setVerticalScrollMode(QListView::ScrollPerPixel);
-
- m_proxyModel = new HistoryProxyModel(this);
- m_proxyModel->setSourceModel(m_historyModel);
- m_proxyModel->sort(0);
-
- m_historyView->setModel(m_proxyModel);
-
- setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
-}
-
-QSize HistoryView::sizeHint() const
-{
- return QWidget::sizeHint().expandedTo(QSize(500, 500));
-}
-
-void HistoryView::setStateFilter(int index)
-{
- QApt::Package::State state = (QApt::Package::State)m_filterBox->itemData(index).toInt();
- m_proxyModel->setStateFilter(state);
-}
-
-void HistoryView::startSearch()
-{
- m_proxyModel->search(m_searchEdit->text());
-}
-
diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.h b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.h
deleted file mode 100644
index 7ffb2b0..0000000
--- a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/***************************************************************************
- * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 HISTORYVIEW_H
-#define HISTORYVIEW_H
-
-#include <QtCore/QHash>
-
-#include <QWidget>
-
-class QStandardItem;
-class QStandardItemModel;
-class QTimer;
-class QTreeView;
-class QLineEdit;
-class QComboBox;
-
-namespace QApt {
- class History;
-}
-
-class HistoryProxyModel;
-
-class HistoryView : public QWidget
-{
- Q_OBJECT
-public:
- enum ComboItems {
- AllChangesItem = 0,
- InstallationsItem = 1,
- UpdatesItem = 2,
- RemovalsItem = 3
- };
- enum PastActions {
- InvalidAction = 0,
- InstalledAction = 1,
- UpgradedAction = 2,
- DowngradedAction = 3,
- RemovedAction = 4,
- PurgedAction = 5
- };
- explicit HistoryView(QWidget *parent);
-
- QSize sizeHint() const override;
-
-private:
- QApt::History *m_history;
- QStandardItemModel *m_historyModel;
- HistoryProxyModel *m_proxyModel;
- QHash<QString, QStandardItem *> m_categoryHash;
-
- QLineEdit *m_searchEdit;
- QTimer *m_searchTimer;
- QComboBox *m_filterBox;
- QTreeView *m_historyView;
-
-private Q_SLOTS:
- void setStateFilter(int index);
- void startSearch();
-};
-
-#endif
diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.cpp
deleted file mode 100644
index 16eb44f..0000000
--- a/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.cpp
+++ /dev/null
@@ -1,167 +0,0 @@
-/***************************************************************************
- * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 "MuonStrings.h"
-
-#include <KLocalizedString>
-#include <QDebug>
-
-#include <QApt/Transaction>
-
-Q_GLOBAL_STATIC_WITH_ARGS(MuonStrings, globalMuonStrings, (0))
-
-using namespace QApt;
-
-MuonStrings *MuonStrings::global()
-{
- return globalMuonStrings;
-}
-
-MuonStrings::MuonStrings(QObject *parent)
- : QObject(parent)
- , m_stateHash(stateHash())
-{
-}
-
-QHash<int, QString> MuonStrings::stateHash()
-{
- QHash<int, QString> hash;
- hash[Package::ToKeep] = i18nc("@info:status Package state", "No Change");
- hash[Package::ToInstall] = i18nc("@info:status Requested action", "Install");
- hash[Package::NewInstall] = i18nc("@info:status Requested action", "Install");
- hash[Package::ToReInstall] = i18nc("@info:status Requested action", "Reinstall");
- hash[Package::ToUpgrade] = i18nc("@info:status Requested action", "Upgrade");
- hash[Package::ToDowngrade] = i18nc("@info:status Requested action", "Downgrade");
- hash[Package::ToRemove] = i18nc("@info:status Requested action", "Remove");
- hash[Package::Held] = i18nc("@info:status Package state" , "Held");
- hash[Package::Installed] = i18nc("@info:status Package state", "Installed");
- hash[Package::Upgradeable] = i18nc("@info:status Package state", "Upgradeable");
- hash[Package::NowBroken] = i18nc("@info:status Package state", "Broken");
- hash[Package::InstallBroken] = i18nc("@info:status Package state", "Install Broken");
- hash[Package::Orphaned] = i18nc("@info:status Package state", "Orphaned");
- hash[Package::Pinned] = i18nc("@info:status Package state", "Locked");
- hash[Package::New] = i18nc("@info:status Package state", "New in repository");
- hash[Package::ResidualConfig] = i18nc("@info:status Package state", "Residual Configuration");
- hash[Package::NotDownloadable] = i18nc("@info:status Package state", "Not Downloadable");
- hash[Package::ToPurge] = i18nc("@info:status Requested action", "Purge");
- hash[Package::IsImportant] = i18nc("@info:status Package state", "Important for base install");
- hash[Package::OverrideVersion] = i18nc("@info:status Package state", "Version overridden");
- hash[Package::IsAuto] = i18nc("@info:status Package state", "Required by other packages");
- hash[Package::IsGarbage] = i18nc("@info:status Package state", "Installed (auto-removable)");
- hash[Package::NowPolicyBroken] = i18nc("@info:status Package state", "Policy Broken");
- hash[Package::InstallPolicyBroken] = i18nc("@info:status Package state", "Policy Broken");
- hash[Package::NotInstalled] = i18nc("@info:status Package state" , "Not Installed");
- hash[Package::IsPinned] = i18nc("@info:status Package locked at a certain version",
- "Locked");
- hash[Package::IsManuallyHeld] = i18nc("@info:status Package state", "Manually held back");
-
- return hash;
-}
-
-QString MuonStrings::packageStateName(Package::State state) const
-{
- return m_stateHash.value(state);
-}
-
-QString MuonStrings::packageChangeStateName(Package::State state) const
-{
- int ns = state & (Package::ToKeep | Package::ToInstall | Package::ToReInstall | Package::NewInstall
- | Package::ToUpgrade | Package::ToRemove
- | Package::ToPurge | Package::ToDowngrade);
- return m_stateHash.value(ns);
-}
-
-QString MuonStrings::errorTitle(ErrorCode error) const
-{
- switch (error) {
- case InitError:
- return i18nc("@title:window", "Initialization Error");
- case LockError:
- return i18nc("@title:window", "Unable to Obtain Package System Lock");
- case DiskSpaceError:
- return i18nc("@title:window", "Low Disk Space");
- case FetchError:
- case CommitError:
- return i18nc("@title:window", "Failed to Apply Changes");
- case AuthError:
- return i18nc("@title:window", "Authentication error");
- case WorkerDisappeared:
- return i18nc("@title:window", "Unexpected Error");
- case UntrustedError:
- return i18nc("@title:window", "Untrusted Packages");
- case UnknownError:
- default:
- return i18nc("@title:window", "Unknown Error");
- }
-}
-
-QString MuonStrings::errorText(ErrorCode error, Transaction *trans) const
-{
- QString text;
-
- switch (error) {
- case InitError:
- text = i18nc("@label", "The package system could not be initialized, your "
- "configuration may be broken.");
- break;
- case LockError:
- text = i18nc("@label",
- "Another application seems to be using the package "
- "system at this time. You must close all other package "
- "managers before you will be able to install or remove "
- "any packages.");
- break;
- case DiskSpaceError:
- text = i18nc("@label",
- "You do not have enough disk space in the directory "
- "at %1 to continue with this operation.", trans->errorDetails());
- break;
- case FetchError:
- text = i18nc("@label", "Could not download packages");
- break;
- case CommitError:
- text = i18nc("@label", "An error occurred while applying changes:");
- break;
- case AuthError:
- text = i18nc("@label",
- "This operation cannot continue since proper "
- "authorization was not provided");
- break;
- case WorkerDisappeared:
- text = i18nc("@label", "It appears that the QApt worker has either crashed "
- "or disappeared. Please report a bug to the QApt maintainers");
- break;
- case UntrustedError:
- text = i18ncp("@label",
- "The following package has not been verified by its author. "
- "Downloading untrusted packages has been disallowed "
- "by your current configuration.",
- "The following packages have not been verified by "
- "their authors. "
- "Downloading untrusted packages has "
- "been disallowed by your current configuration.",
- trans->untrustedPackages().size());
- break;
- default:
- break;
- }
-
- return text;
-}
diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.h b/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.h
deleted file mode 100644
index d7886d3..0000000
--- a/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.h
+++ /dev/null
@@ -1,56 +0,0 @@
-/***************************************************************************
- * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 MUONSTRINGS_H
-#define MUONSTRINGS_H
-
-#include <QtCore/QHash>
-
-#include <QApt/Package>
-
-namespace QApt {
- class Transaction;
-}
-
-class MuonStrings : public QObject
-{
- Q_OBJECT
-public:
- explicit MuonStrings(QObject *parent);
-
- static MuonStrings* global();
-
- /** @returns the state name for a given @p state, for displaying it to the user */
- QString packageStateName(QApt::Package::State state) const;
-
- /** @returns the state name for the given @p state changes, for displaying it to the user
- * This means, the flags that are related to a state change, like ToInstall, ToUpgrade, etc
- */
- QString packageChangeStateName(QApt::Package::State state) const;
- QString errorTitle(QApt::ErrorCode error) const;
- QString errorText(QApt::ErrorCode error, QApt::Transaction *trans) const;
-
-private:
- const QHash<int, QString> m_stateHash;
-
- static QHash<int, QString> stateHash();
-};
-
-#endif
diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.cpp
deleted file mode 100644
index 74810c7..0000000
--- a/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.cpp
+++ /dev/null
@@ -1,537 +0,0 @@
-/***************************************************************************
- * Copyright © 2012 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 "QAptActions.h"
-#include "MuonStrings.h"
-#include "HistoryView/HistoryView.h"
-
-// Qt includes
-#include <QtCore/QDir>
-#include <QtCore/QStringBuilder>
-#include <QAction>
-#include <QDebug>
-#include <QDialog>
-#include <QFileDialog>
-#include <QStandardPaths>
-#include <QDialogButtonBox>
-#include <QLayout>
-#include <QNetworkConfigurationManager>
-#include <QApplication>
-
-// KDE includes
-#include <KActionCollection>
-#include <KConfigGroup>
-#include <KLocalizedString>
-#include <KMessageBox>
-#include <KProcess>
-#include <KStandardAction>
-#include <KSharedConfig>
-#include <KXmlGuiWindow>
-#include <KWindowConfig>
-
-// QApt includes
-#include <QApt/Backend>
-#include <QApt/DebFile>
-#include <QApt/Transaction>
-
-QAptActions::QAptActions()
- : QObject(nullptr)
- , m_backend(nullptr)
- , m_actionsDisabled(false)
- , m_reloadWhenEditorFinished(false)
- , m_historyDialog(nullptr)
- , m_distUpgradeAvailable(false)
- , m_config(new QNetworkConfigurationManager(this))
-{
- connect(m_config, &QNetworkConfigurationManager::onlineStateChanged, this, &QAptActions::shouldConnect);
-}
-
-QAptActions* QAptActions::self()
-{
- static QPointer<QAptActions> self;
- if(!self) {
- self = new QAptActions;
- }
- return self;
-}
-
-void QAptActions::setActionCollection(KActionCollection* actions)
-{
- setParent(actions);
- m_actionCollection = actions;
-
- setupActions();
-}
-
-QWidget* QAptActions::mainWindow() const
-{
- return nullptr;
-}
-
-void QAptActions::setBackend(QApt::Backend* backend)
-{
- if(backend == m_backend)
- return;
- m_backend = backend;
- if (!m_backend->init())
- initError();
-
- connect(m_backend, SIGNAL(packageChanged()), this, SLOT(setActionsEnabled()));
-
- setOriginalState(m_backend->currentCacheState());
-
- setReloadWhenEditorFinished(true);
- // Some actions need an initialized backend to be able to set their enabled state
- setActionsEnabled(true);
- checkDistUpgrade();
-}
-
-void QAptActions::setupActions()
-{
- QAction* undoAction = KStandardAction::undo(this, SLOT(undo()), actionCollection());
- actionCollection()->addAction(QStringLiteral("undo"), undoAction);
- m_actions.append(undoAction);
-
- QAction* redoAction = KStandardAction::redo(this, SLOT(redo()), actionCollection());
- actionCollection()->addAction(QStringLiteral("redo"), redoAction);
- m_actions.append(redoAction);
-
- QAction* revertAction = actionCollection()->addAction(QStringLiteral("revert"));
- revertAction->setIcon(QIcon::fromTheme(QStringLiteral("document-revert")));
- revertAction->setText(i18nc("@action Reverts all potential changes to the cache", "Unmark All"));
- connect(revertAction, &QAction::triggered, this, &QAptActions::revertChanges);
- m_actions.append(revertAction);
-
- QAction* softwarePropertiesAction = actionCollection()->addAction(QStringLiteral("software_properties"));
- softwarePropertiesAction->setPriority(QAction::LowPriority);
- softwarePropertiesAction->setIcon(QIcon::fromTheme(QStringLiteral("configure")));
- softwarePropertiesAction->setText(i18nc("@action Opens the software sources configuration dialog", "Configure Software Sources"));
- connect(softwarePropertiesAction, &QAction::triggered, this, &QAptActions::runSourcesEditor);
- m_actions.append(softwarePropertiesAction);
-
- QAction* loadSelectionsAction = actionCollection()->addAction(QStringLiteral("open_markings"));
- loadSelectionsAction->setIcon(QIcon::fromTheme(QStringLiteral("document-open")));
- loadSelectionsAction->setText(i18nc("@action", "Read Markings..."));
- connect(loadSelectionsAction, &QAction::triggered, this, &QAptActions::loadSelections);
- m_actions.append(loadSelectionsAction);
-
- QAction* saveSelectionsAction = actionCollection()->addAction(QStringLiteral("save_markings"));
- saveSelectionsAction->setIcon(QIcon::fromTheme(QStringLiteral("document-save-as")));
- saveSelectionsAction->setText(i18nc("@action", "Save Markings As..."));
- connect(saveSelectionsAction, &QAction::triggered, this, &QAptActions::saveSelections);
- m_actions.append(saveSelectionsAction);
-
- QAction* createDownloadListAction = actionCollection()->addAction(QStringLiteral("save_download_list"));
- createDownloadListAction->setPriority(QAction::LowPriority);
- createDownloadListAction->setIcon(QIcon::fromTheme(QStringLiteral("document-save-as")));
- createDownloadListAction->setText(i18nc("@action", "Save Package Download List..."));
- connect(createDownloadListAction, &QAction::triggered, this, &QAptActions::createDownloadList);
- m_actions.append(createDownloadListAction);
-
- QAction* downloadListAction = actionCollection()->addAction(QStringLiteral("download_from_list"));
- downloadListAction->setPriority(QAction::LowPriority);
- downloadListAction->setIcon(QIcon::fromTheme(QStringLiteral("download")));
- downloadListAction->setText(i18nc("@action", "Download Packages From List..."));
- connect(downloadListAction, &QAction::triggered, this, &QAptActions::downloadPackagesFromList);
- downloadListAction->setEnabled(isConnected());
- connect(this, &QAptActions::shouldConnect, downloadListAction, &QAction::setEnabled);
- m_actions.append(downloadListAction);
-
- QAction* loadArchivesAction = actionCollection()->addAction(QStringLiteral("load_archives"));
- loadArchivesAction->setPriority(QAction::LowPriority);
- loadArchivesAction->setIcon(QIcon::fromTheme(QStringLiteral("document-open")));
- loadArchivesAction->setText(i18nc("@action", "Add Downloaded Packages"));
- connect(loadArchivesAction, &QAction::triggered, this, &QAptActions::loadArchives);
- m_actions.append(loadArchivesAction);
-
- QAction* saveInstalledAction = actionCollection()->addAction(QStringLiteral("save_package_list"));
- saveInstalledAction->setPriority(QAction::LowPriority);
- saveInstalledAction->setIcon(QIcon::fromTheme(QStringLiteral("document-save-as")));
- saveInstalledAction->setText(i18nc("@action", "Save Installed Packages List..."));
- connect(saveInstalledAction, &QAction::triggered, this, &QAptActions::saveInstalledPackagesList);
-
- QAction* historyAction = actionCollection()->addAction(QStringLiteral("history"));
- historyAction->setPriority(QAction::LowPriority);
- historyAction->setIcon(QIcon::fromTheme(QStringLiteral("view-history")));
- historyAction->setText(i18nc("@action::inmenu", "History..."));
- actionCollection()->setDefaultShortcut(historyAction, QKeySequence(Qt::CTRL + Qt::Key_H));
- connect(historyAction, &QAction::triggered, this, &QAptActions::showHistoryDialog);
-
- QAction *distUpgradeAction = actionCollection()->addAction(QStringLiteral("dist-upgrade"));
- distUpgradeAction->setIcon(QIcon::fromTheme(QStringLiteral("system-software-update")));
- distUpgradeAction->setText(i18nc("@action", "Upgrade"));
- distUpgradeAction->setPriority(QAction::HighPriority);
- distUpgradeAction->setWhatsThis(i18nc("Notification when a new version of Kubuntu is available",
- "A new version of Kubuntu is available."));
- distUpgradeAction->setEnabled(m_distUpgradeAvailable);
- connect(distUpgradeAction, &QAction::triggered, this, &QAptActions::launchDistUpgrade);
-
- m_actions.append(saveInstalledAction);
-}
-
-void QAptActions::setActionsEnabled(bool enabled)
-{
- m_actionsDisabled = !enabled;
-
- Q_FOREACH (QAction *action, m_actions) {
- action->setEnabled(enabled);
- }
-
- if (!enabled || !actionCollection())
- return;
-
- actionCollection()->action(QStringLiteral("update"))->setEnabled(isConnected() && enabled);
-
- actionCollection()->action(QStringLiteral("undo"))->setEnabled(m_backend && !m_backend->isUndoStackEmpty());
- actionCollection()->action(QStringLiteral("redo"))->setEnabled(m_backend && !m_backend->isRedoStackEmpty());
- actionCollection()->action(QStringLiteral("revert"))->setEnabled(m_backend && !m_backend->isUndoStackEmpty());
-
- actionCollection()->action(QStringLiteral("save_download_list"))->setEnabled(isConnected());
-
- bool changesPending = m_backend && m_backend->areChangesMarked();
- actionCollection()->action(QStringLiteral("save_markings"))->setEnabled(changesPending);
- actionCollection()->action(QStringLiteral("save_download_list"))->setEnabled(changesPending);
- actionCollection()->action(QStringLiteral("dist-upgrade"))->setEnabled(m_distUpgradeAvailable);
-}
-
-bool QAptActions::reloadWhenSourcesEditorFinished() const
-{
- return m_reloadWhenEditorFinished;
-}
-
-bool QAptActions::isConnected() const
-{
- return m_config->isOnline();
-}
-
-bool QAptActions::saveSelections()
-{
- QString filename = QFileDialog::getSaveFileName(mainWindow(), i18nc("@title:window", "Save Markings As"));
-
- if (filename.isEmpty()) {
- return false;
- }
-
- if (!m_backend->saveSelections(filename)) {
- QString text = xi18nc("@label", "The document could not be saved, as it "
- "was not possible to write to "
- "<filename>%1</filename>\n\nCheck "
- "that you have write access to this file "
- "or that enough disk space is available.",
- filename);
- KMessageBox::error(mainWindow(), text, QString());
- return false;
- }
-
- return true;
-}
-
-bool QAptActions::saveInstalledPackagesList()
-{
- QString filename;
-
- filename = QFileDialog::getSaveFileName(mainWindow(),
- i18nc("@title:window", "Save Installed Packages List As"));
-
- if (filename.isEmpty()) {
- return false;
- }
-
- if (!m_backend->saveInstalledPackagesList(filename)) {
- QString text = xi18nc("@label", "The document could not be saved, as it "
- "was not possible to write to "
- "<filename>%1</filename>\n\nCheck "
- "that you have write access to this file "
- "or that enough disk space is available.",
- filename);
- KMessageBox::error(mainWindow(), text, QString());
- return false;
- }
-
- return true;
-}
-
-bool QAptActions::createDownloadList()
-{
- QString filename;
- filename = QFileDialog::getSaveFileName(mainWindow(),
- i18nc("@title:window", "Save Download List As"));
-
- if (filename.isEmpty()) {
- return false;
- }
-
- if (!m_backend->saveDownloadList(filename)) {
- QString text = xi18nc("@label", "The document could not be saved, as it "
- "was not possible to write to "
- "<filename>%1</filename>\n\nCheck "
- "that you have write access to this file "
- "or that enough disk space is available.",
- filename);
- KMessageBox::error(mainWindow(), text, QString());
- return false;
- }
-
- return true;
-}
-
-void QAptActions::downloadPackagesFromList()
-{
- QString filename = QFileDialog::getOpenFileName(mainWindow(), i18nc("@title:window", "Open File"));
-
- if (filename.isEmpty()) {
- return;
- }
-
- QString dirName = filename.left(filename.lastIndexOf(QLatin1Char('/')));
-
- setActionsEnabled(false);
- QApt::Transaction *trans = m_backend->downloadArchives(filename, dirName % QLatin1String("/packages"));
-
- if (trans)
- emit downloadArchives(trans);
-}
-
-void QAptActions::loadSelections()
-{
- QString filename = QFileDialog::getOpenFileName(mainWindow(), i18nc("@title:window", "Open File"));
-
- if (filename.isEmpty()) {
- return;
- }
-
- m_backend->saveCacheState();
- if (!m_backend->loadSelections(filename)) {
- QString text = i18nc("@label", "Could not mark changes. Please make sure "
- "that the file is a markings file created by "
- "either the Muon Package Manager or the "
- "Synaptic Package Manager.");
- KMessageBox::error(mainWindow(), text, QString());
- }
-}
-
-void QAptActions::loadArchives()
-{
- QString dirName = QFileDialog::getExistingDirectory(mainWindow(),
- i18nc("@title:window", "Choose a Directory"));
-
- if (dirName.isEmpty()) {
- // User canceled
- return;
- }
-
- QDir dir(dirName);
- QStringList archiveFiles = dir.entryList(QDir::Files, QDir::Name);
-
- int successCount = 0;
- foreach (const QString &archiveFile, archiveFiles) {
- const QApt::DebFile debFile(dirName % QLatin1Char('/') % archiveFile);
-
- if (debFile.isValid()) {
- if (m_backend->addArchiveToCache(debFile)) {
- successCount++;
- }
- }
- }
-
- if (successCount != 0) {
- QString message = i18ncp("@label",
- "%1 package was successfully added to the cache",
- "%1 packages were successfully added to the cache",
- successCount);
- KMessageBox::information(mainWindow(), message, QString());
- } else {
- QString message = i18nc("@label",
- "No valid packages could be found in this directory. "
- "Please make sure the packages are compatible with your "
- "computer and are at the latest version.");
- KMessageBox::error(mainWindow(), message, i18nc("@title:window",
- "Packages Could Not be Found"));
- }
-}
-
-void QAptActions::undo()
-{
- m_backend->undo();
-}
-
-void QAptActions::redo()
-{
- m_backend->redo();
-}
-
-void QAptActions::revertChanges()
-{
- m_backend->restoreCacheState(m_originalState);
- emit changesReverted();
-}
-
-void QAptActions::runSourcesEditor()
-{
- KProcess *proc = new KProcess(this);
- QStringList arguments;
- int winID = 0;
- foreach(QWindow* w, QGuiApplication::allWindows()) {
- if (w->objectName() == QLatin1String("DiscoverMainWindow")) {
- winID = w->winId();
- }
- }
-
- const QString kdesu = QFile::decodeName(CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/kdesu");
- const QString editor = QStandardPaths::findExecutable(QStringLiteral("software-properties-kde"));
-
- arguments << kdesu << QStringLiteral("--") << editor << QStringLiteral("--attach") << QString::number(winID);
- if (m_reloadWhenEditorFinished) {
- arguments << QStringLiteral("--dont-update");
- }
-
- proc->setProgram(arguments);
- proc->start();
- connect(proc, static_cast<void (KProcess::*)(int, QProcess::ExitStatus)>(&KProcess::finished), this, &QAptActions::sourcesEditorFinished);
-}
-
-void QAptActions::sourcesEditorFinished(int exitStatus)
-{
- bool reload = (exitStatus != 0);
- if (m_reloadWhenEditorFinished && reload) {
- actionCollection()->action(QStringLiteral("update"))->trigger();
- }
-
- emit sourcesEditorClosed(reload);
-}
-
-KActionCollection* QAptActions::actionCollection()
-{
- return m_actionCollection;
-}
-
-void QAptActions::setOriginalState(QApt::CacheState state)
-{
- m_originalState = state;
-}
-
-void QAptActions::setReloadWhenEditorFinished(bool reload)
-{
- m_reloadWhenEditorFinished = reload;
-}
-
-void QAptActions::initError()
-{
- QString details = m_backend->initErrorMessage();
-
- MuonStrings *muonStrings = MuonStrings::global();
-
- QString title = muonStrings->errorTitle(QApt::InitError);
- QString text = muonStrings->errorText(QApt::InitError, nullptr);
-
- KMessageBox::detailedError(mainWindow(), text, details, title);
- exit(-1);
-}
-
-void QAptActions::displayTransactionError(QApt::ErrorCode error, QApt::Transaction* trans)
-{
- if (error == QApt::Success)
- return;
-
- MuonStrings *muonStrings = MuonStrings::global();
-
- QString title = muonStrings->errorTitle(error);
- QString text = muonStrings->errorText(error, trans);
-
- switch (error) {
- case QApt::InitError:
- case QApt::FetchError:
- case QApt::CommitError:
- KMessageBox::detailedError(QAptActions::self()->mainWindow(), text, trans->errorDetails(), title);
- break;
- default:
- KMessageBox::error(QAptActions::self()->mainWindow(), text, title);
- break;
- }
-}
-
-void QAptActions::showHistoryDialog()
-{
- if (!m_historyDialog) {
- m_historyDialog = new QDialog(mainWindow());
- QVBoxLayout* layout = new QVBoxLayout(m_historyDialog);
- m_historyDialog->setLayout(layout);
- m_historyDialog->setWindowTitle(i18nc("@title:window", "Package History"));
- m_historyDialog->setWindowIcon(QIcon::fromTheme(QStringLiteral("view-history")));
-
- KConfigGroup dialogConfig(KSharedConfig::openConfig(QStringLiteral("muonrc")), QStringLiteral("HistoryDialog"));
- KWindowConfig::restoreWindowSize(m_historyDialog->windowHandle(), dialogConfig);
-
- HistoryView *historyView = new HistoryView(m_historyDialog);
- layout->addWidget(historyView);
-
- QDialogButtonBox* box = new QDialogButtonBox(m_historyDialog);
- box->setStandardButtons(QDialogButtonBox::Close);
- connect(box, &QDialogButtonBox::accepted, m_historyDialog.data(), &QDialog::accept);
- connect(box, &QDialogButtonBox::rejected, m_historyDialog.data(), &QDialog::reject);
- connect(m_historyDialog, &QDialog::finished, this, &QAptActions::closeHistoryDialog);
- layout->addWidget(box);
-
- m_historyDialog->show();
- } else {
- m_historyDialog->raise();
- }
-}
-
-void QAptActions::closeHistoryDialog()
-{
- KConfigGroup dialogConfig(KSharedConfig::openConfig(QStringLiteral("muonrc")), "HistoryDialog");
- KWindowConfig::restoreWindowSize(m_historyDialog->windowHandle(), dialogConfig);
- m_historyDialog->deleteLater();
- m_historyDialog = nullptr;
-}
-
-void QAptActions::launchDistUpgrade()
-{
- const QString kdesu = QFile::decodeName(CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/kdesu");
- QProcess::startDetached(kdesu, {QStringLiteral("--"), QStringLiteral("do-release-upgrade"), QStringLiteral("-m"), QStringLiteral("desktop"), QStringLiteral("-f"), QStringLiteral("DistUpgradeViewKDE")});
-}
-
-void QAptActions::checkDistUpgrade()
-{
- if(!QFile::exists(QStringLiteral("/usr/lib/python3/dist-packages/DistUpgrade/DistUpgradeFetcherKDE.py"))) {
- qWarning() << "Couldn't find the /usr/lib/python3/dist-packages/DistUpgrade/DistUpgradeFetcherKDE.py file";
- return;
- }
- QString checkerFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("libdiscover/applicationsbackend/releasechecker"));
- if(checkerFile.isEmpty()) {
- qWarning() << "Couldn't find the releasechecker script" << QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation);
- return;
- }
-
- KProcess* checkerProcess = new KProcess(this);
- checkerProcess->setProgram({ QStringLiteral("/usr/bin/python3"), checkerFile });
- connect(checkerProcess, static_cast<void (KProcess::*)(int)>(&KProcess::finished), this, &QAptActions::checkerFinished);
- connect(checkerProcess, static_cast<void (KProcess::*)(int)>(&KProcess::finished), checkerProcess, &KProcess::deleteLater);
- checkerProcess->start();
-}
-
-void QAptActions::checkerFinished(int res)
-{
- m_distUpgradeAvailable = (res == 0);
- if (!actionCollection())
- return;
- actionCollection()->action(QStringLiteral("dist-upgrade"))->setEnabled(m_distUpgradeAvailable);
-}
diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.h b/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.h
deleted file mode 100644
index b71b290..0000000
--- a/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.h
+++ /dev/null
@@ -1,110 +0,0 @@
-/***************************************************************************
- * Copyright © 2012 Jonathan Thomas <echidnaman@kubuntu.org> *
- * *
- * 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 QAPTACTIONS_H
-#define QAPTACTIONS_H
-
-#include <QtCore/QObject>
-#include <QPointer>
-#include <QWindow>
-
-#include <QApt/Globals>
-
-class KXmlGuiWindow;
-class KDialog;
-class KXmlGuiWindow;
-class KActionCollection;
-class QAction;
-class QDialog;
-class QNetworkConfigurationManager;
-
-namespace QApt {
- class Backend;
- class Transaction;
-}
-
-class QAptActions : public QObject
-{
- Q_OBJECT
-public:
- static QAptActions* self();
- void setActionCollection(KActionCollection* actions);
- Q_DECL_DEPRECATED QWidget* mainWindow() const;
-
- bool reloadWhenSourcesEditorFinished() const;
- bool isConnected() const;
- void setOriginalState(QApt::CacheState state);
- void setReloadWhenEditorFinished(bool reload);
- void initError();
- void displayTransactionError(QApt::ErrorCode error, QApt::Transaction* trans);
- KActionCollection* actionCollection();
-
- void setCanExit(bool e) { m_canExit = e; }
- bool canExit() const { return m_canExit; }
-
-Q_SIGNALS:
- void shouldConnect(bool isConnected);
- void changesReverted();
- void sourcesEditorClosed(bool reload);
- void downloadArchives(QApt::Transaction *trans);
-
-public Q_SLOTS:
- void setBackend(QApt::Backend *backend);
- void setupActions();
-
- // KAction slots
- bool saveSelections();
- bool saveInstalledPackagesList();
- void loadSelections();
- bool createDownloadList();
- void downloadPackagesFromList();
- void loadArchives();
- void undo();
- void redo();
- void revertChanges();
- void runSourcesEditor();
- void sourcesEditorFinished(int exitStatus);
- void showHistoryDialog();
- void setActionsEnabled(bool enabled = true);
-
-private Q_SLOTS:
- void closeHistoryDialog();
- void checkDistUpgrade();
- void launchDistUpgrade();
- void checkerFinished(int res);
-
-private:
- QAptActions();
-
- QApt::Backend *m_backend;
- QApt::CacheState m_originalState;
- bool m_actionsDisabled;
- KActionCollection* m_actionCollection;
- bool m_reloadWhenEditorFinished;
-
- QPointer<QDialog> m_historyDialog;
- QList<QAction *> m_actions;
- bool m_distUpgradeAvailable;
- QNetworkConfigurationManager* m_config;
- bool m_canExit;
-
-};
-
-#endif // QAPTACTIONS_H
diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/policies/org.kde.muon.repo.action b/libdiscover/backends/ApplicationBackend/libmuonapt/policies/org.kde.muon.repo.action
deleted file mode 100644
index dd6ad20..0000000
--- a/libdiscover/backends/ApplicationBackend/libmuonapt/policies/org.kde.muon.repo.action
+++ /dev/null
@@ -1,5 +0,0 @@
-[org.kde.muon.repo.modify]
-Name=Add Repo
-Description=The system is attempting to modify the sources
-Policy=auth_admin
-Persistence=session \ No newline at end of file
diff --git a/libdiscover/backends/ApplicationBackend/muonapplicationnotifier.notifyrc b/libdiscover/backends/ApplicationBackend/muonapplicationnotifier.notifyrc
deleted file mode 100644
index 8b7400b..0000000
--- a/libdiscover/backends/ApplicationBackend/muonapplicationnotifier.notifyrc
+++ /dev/null
@@ -1,109 +0,0 @@
-[Global]
-IconName=muondiscover
-Comment=Muon Application Backend Notifier
-Comment[ar]=مُخطر سند تطبيقات ميون
-Comment[ca]=Notificador del dorsal d'aplicacions del Muon
-Comment[ca@valencia]=Notificador del dorsal d'aplicacions del Muon
-Comment[cs]=Podpůrná vrstva upozorňování pro Muon
-Comment[da]=Muon-program-backend-bekendtgørelser
-Comment[de]=Muon-Dienstprogramm für Anwendungs-Benachrichtigungen
-Comment[el]=Πρόγραμμα ειδοποιήσεων εφαρμογών υποστήριξης Muon
-Comment[en_GB]=Muon Application Backend Notifier
-Comment[es]=Notificador del motor de la aplicación Muon
-Comment[et]=Muoni rakenduse taustaprogrammi märguanded
-Comment[fi]=Muonin sovellustaustajärjestelmän ilmoitukset
-Comment[fr]=Notifieur du moteur de l'application Muon
-Comment[gl]=Motor de notificacións de aplicacións de Muon
-Comment[id]=Pemberitahu Backend Aplikasi Muon
-Comment[it]=Notifiche motore applicazioni di Muon
-Comment[ko]=Muon 프로그램 백엔드 알림이
-Comment[nb]=Muon varsler for program-bakgrunnsmotor
-Comment[nl]=Muon backend van melder van toepassingen
-Comment[nn]=Muon-varslar for program-bakgrunnsmotor
-Comment[pl]=Silnik powiadamiania o programach Muon
-Comment[pt]=Notificação da Infra-Estrutura de Aplicações do Muon
-Comment[pt_BR]=Notificador da Infraestrutura de Aplicativos do Muon
-Comment[ru]=Модуль уведомлений Muon
-Comment[sk]=Backendový oznamovač aplikácií Muon
-Comment[sl]=Zaledja obvestilnika za programe Muon
-Comment[sr]=Муонова позадина за извештавање о програмима
-Comment[sr@ijekavian]=Муонова позадина за извештавање о програмима
-Comment[sr@ijekavianlatin]=Muonova pozadina za izveštavanje o programima
-Comment[sr@latin]=Muonova pozadina za izveštavanje o programima
-Comment[sv]=Muon programgränssnittsunderrättelser
-Comment[uk]=Сповіщувач модуля програми Muon
-Comment[x-test]=xxMuon Application Backend Notifierxx
-Comment[zh_CN]=Muon 应用程序后端提示器
-
-[Event/DistUpgrade]
-Name=Upgrade Available
-Name[ar]=التّرقيّة متوفّرة
-Name[ca]=Hi ha una actualització disponible
-Name[ca@valencia]=Hi ha una actualització disponible
-Name[cs]=Dostupná aktualizace distribuce
-Name[da]=Opgradering tilgængelig
-Name[de]=Paketaktualisierung verfügbar
-Name[el]=Διαθέσιμη αναβάθμιση
-Name[en_GB]=Upgrade Available
-Name[es]=Actualización disponible
-Name[et]=Saadaval on uuendus
-Name[fi]=Versiopäivitys saatavilla
-Name[fr]=Mise à niveau disponible
-Name[gl]=Dispoñíbel unha actualización
-Name[he]=יש שדרוג זמים
-Name[id]=Pembaruan Tersedia
-Name[it]=Aggiornamento disponibile
-Name[ko]=업그레이드 사용 가능
-Name[nb]=Oppgradering tilgjengelig
-Name[nl]=Opwaardering beschikbaar
-Name[nn]=Oppgradering tilgjengeleg
-Name[pl]=Dostępne uaktualnienie
-Name[pt]=Actualização Disponível
-Name[pt_BR]=Atualização disponível
-Name[ru]=Доступно обновление дистрибутива
-Name[sk]=Dostupné vylepšenia systému
-Name[sl]=Na voljo je nadgradnja
-Name[sr]=Доступна надоградња
-Name[sr@ijekavian]=Доступна надоградња
-Name[sr@ijekavianlatin]=Dostupna nadogradnja
-Name[sr@latin]=Dostupna nadogradnja
-Name[sv]=Uppgradering tillgänglig
-Name[uk]=Доступне оновлення дистрибутива
-Name[x-test]=xxUpgrade Availablexx
-Name[zh_CN]=更新可用
-Comment=A new version of Kubuntu is available
-Comment[ar]=إصدارة جديدة من كوبونتو متوفّرة
-Comment[ca]=Hi ha disponible una nova versió del Kubuntu
-Comment[ca@valencia]=Hi ha disponible una nova versió del Kubuntu
-Comment[cs]=Je dostupná nová verze Kubuntu
-Comment[da]=En ny version af Kubuntu er tilgængelig
-Comment[de]=Eine neue Version von Kubuntu ist verfügbar
-Comment[el]=Μια νέα έκδοση του Kubuntu είναι διαθέσιμη
-Comment[en_GB]=A new version of Kubuntu is available
-Comment[es]=Está disponible una nueva versión de Kubuntu
-Comment[et]=Saadaval on Kubuntu uus versioon
-Comment[fi]=Uusi Kubuntun versio on saatavilla
-Comment[fr]=Une nouvelle version de Kubuntu est disponible
-Comment[gl]=Hai dispoñíbel unha nova versión de Kubuntu.
-Comment[he]=גרסה חדשה של Kubuntu זמינה
-Comment[id]=Sebuah versi baru Kubuntu telah tersedia
-Comment[it]=È disponibile una nuova versione di Kubuntu
-Comment[ko]=Kubuntu 새 버전 사용 가능
-Comment[nb]=En ny versjon av Kubuntu er tilgjengelig
-Comment[nl]=Er is een nieuwe versie van Kubuntu beschikbaar
-Comment[nn]=Ein ny versjon av Kubuntu er tilgjengeleg
-Comment[pl]=Dostępna jest nowa wersja Kubuntu
-Comment[pt]=Está disponível uma nova versão do Kubuntu
-Comment[pt_BR]=Está disponível uma nova versão do Kubuntu
-Comment[ru]=Доступна новая версия Kubuntu
-Comment[sk]=Nová verzia Kubuntu je dostupná
-Comment[sl]=Na voljo je nova različica Kubuntu
-Comment[sr]=Доступно је ново издање Кубунтуа
-Comment[sr@ijekavian]=Доступно је ново издање Кубунтуа
-Comment[sr@ijekavianlatin]=Dostupno je novo izdanje Kubuntua
-Comment[sr@latin]=Dostupno je novo izdanje Kubuntua
-Comment[sv]=En ny version av Kubuntu är tillgänglig
-Comment[uk]=Випущено нову версію Kubuntu
-Comment[x-test]=xxA new version of Kubuntu is availablexx
-Comment[zh_CN]=有新版本的 Kubuntu 可用
-Action=Popup
diff --git a/libdiscover/backends/ApplicationBackend/qapt-backend-categories.xml b/libdiscover/backends/ApplicationBackend/qapt-backend-categories.xml
deleted file mode 100644
index 80f310a..0000000
--- a/libdiscover/backends/ApplicationBackend/qapt-backend-categories.xml
+++ /dev/null
@@ -1,559 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<Menu>
-
- <Menu>
- <Name>Accessories</Name>
- <Icon>applications-utilities</Icon>
- <Include>
- <And>
- <Category>Utility</Category>
- <Not><Category>Accessibility</Category></Not>
- </And>
- </Include>
- </Menu>
-
- <Menu>
- <Name>Accessibility</Name>
- <Icon>preferences-desktop-accessibility</Icon>
- <Include>
- <And>
- <Category>Accessibility</Category>
- <Not><Category>Settings</Category></Not>
- </And>
- </Include>
- </Menu>
-
- <Menu>
- <Name>Developer Tools</Name>
- <Icon>applications-development</Icon>
- <Include>
- <Or>
- <Category>Development</Category>
- <PkgSection>devel</PkgSection>
- <PkgSection>restricted/devel</PkgSection>
- <PkgSection>universe/devel</PkgSection>
- <PkgSection>multiverse/devel</PkgSection>
- </Or>
- <Filename>emacs.desktop</Filename>
- </Include>
-
-
- <Menu>
- <Name>Debugging</Name>
- <Icon>tools-report-bug</Icon>
- <Include>
- <And>
- <Category>Debugger</Category>
- </And>
- </Include>
- </Menu>
-
- <Menu>
- <Name>Graphic Interface Design</Name>
- <Include>
- <And>
- <Category>GUIDesigner</Category>
- </And>
- </Include>
- </Menu>
-
- <Menu>
- <Name>Haskell</Name>
- <Icon>text-x-haskell</Icon>
- <Include>
- <Or>
- <PkgSection>haskell</PkgSection>
- <PkgSection>restricted/haskell</PkgSection>
- <PkgSection>universe/haskell</PkgSection>
- <PkgSection>multiverse/haskell</PkgSection>
- </Or>
- </Include>
- </Menu>
-
- <Menu>
- <Name>IDEs</Name>
- <Include>
- <And>
- <Category>IDE</Category>
- </And>
- </Include>
- </Menu>
-
- <Menu>
- <Name>Java</Name>
- <Icon>application-x-java</Icon>
- <Include>
- <Or>
- <PkgSection>java</PkgSection>
- <PkgSection>restricted/java</PkgSection>
- <PkgSection>universe/java</PkgSection>
- <PkgSection>multiverse/java</PkgSection>
- </Or>
- </Include>
- </Menu>
-
- <Menu>
- <Name>Localization</Name>
- <Icon>preferences-desktop-locale</Icon>
- <Include>
- <And>
- <Category>Translation</Category>
- </And>
- </Include>
- </Menu>
-
- <Menu>
- <Name>Perl</Name>
- <Include>
- <Or>
- <PkgSection>perl</PkgSection>
- <PkgSection>restricted/perl</PkgSection>
- <PkgSection>universe/perl</PkgSection>
- <PkgSection>multiverse/perl</PkgSection>
- </Or>
- </Include>
- </Menu>
-
- <Menu>
- <Name>Profiling</Name>
- <Include>
- <Or>
- <Category>Profiling</Category>
- </Or>
- </Include>
- </Menu>
-
- <Menu>
- <Name>Python</Name>
- <Icon>text-x-python</Icon>
- <Include>
- <Or>
- <PkgSection>python</PkgSection>
- <PkgSection>restricted/python</PkgSection>
- <PkgSection>universe/python</PkgSection>
- <PkgSection>multiverse/python</PkgSection>
- </Or>
- </Include>
- </Menu>
-
- <Menu>
- <Name>Version Control</Name>
- <Icon>text-x-patch</Icon>
- <Include>
- <Or>
- <PkgSection>vcs</PkgSection>
- <PkgSection>restricted/vcs</PkgSection>
- <PkgSection>universe/vcs</PkgSection>
- <PkgSection>multiverse/vcs</PkgSection>
- <Category>RevisionControl</Category>
- </Or>
- </Include>
- </Menu>
-
- <Menu>
- <Name>Web Development</Name>
- <Include>
- <And>
- <Category>WebDevelopment</Category>
- </And>
- </Include>
- <Icon>applications-internet</Icon>
- </Menu>
-
- </Menu>
-
-
- <Menu>
- <Name>Education</Name>
- <Icon>applications-education</Icon>
- <Include>
- <And>
- <Category>Education</Category>
- <Not>
- <Category>Science</Category>
- </Not>
- </And>
- </Include>
- </Menu>
-
-
- <Menu>
- <Name>Science &amp; Engineering</Name>
- <Icon>applications-science</Icon>
- <Include>
- <Or>
- <Category>Science</Category>
- <Category>Engineering</Category>
- </Or>
- </Include>
- <Menu>
- <Name>Astronomy</Name>
- <Include>
- <And>
- <Category>Astronomy</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Biology</Name>
- <Include>
- <And>
- <Category>Biology</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Chemistry</Name>
- <Icon>applications-science</Icon>
- <Include>
- <And>
- <Category>Chemistry</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Computer Science &amp; Robotics</Name>
- <Icon>computer</Icon>
- <Include>
- <Or>
- <Category>ArtificialIntelligence</Category>
- <Category>ComputerScience</Category>
- <Category>Robotics</Category>
- </Or>
- </Include>
- </Menu>
- <Menu>
- <Name>Electronics</Name>
- <Icon>audio-card</Icon>
- <Include>
- <And>
- <Category>Electronics</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Engineering</Name>
- <Icon>applications-engineering</Icon>
- <Include>
- <And>
- <Category>Engineering</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Geography</Name>
- <Include>
- <And>
- <Category>Geography</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Geology</Name>
- <Include>
- <Or>
- <Category>Geology</Category>
- <Category>Geoscience</Category>
- </Or>
- </Include>
- </Menu>
- <Menu>
- <Name>Mathematics</Name>
- <Icon>applications-education-mathematics</Icon>
- <Include>
- <Or>
- <Category>DataVisualization</Category>
- <Category>Math</Category>
- <Category>NumericalAnalysis</Category>
- <PkgSection>math</PkgSection>
- <PkgSection>restricted/math</PkgSection>
- <PkgSection>universe/math</PkgSection>
- <PkgSection>multiverse/math</PkgSection>
- <PkgSection>gnu-r</PkgSection>
- <PkgSection>restricted/gnu-r</PkgSection>
- <PkgSection>universe/gnu-r</PkgSection>
- <PkgSection>multiverse/gnu-r</PkgSection>
- </Or>
- </Include>
- </Menu>
- <Menu>
- <Name>Physics</Name>
- <Icon>step</Icon>
- <Include>
- <And>
- <Category>Physics</Category>
- </And>
- </Include>
- </Menu>
- </Menu>
-
- <Menu>
- <Name>Fonts</Name>
- <Icon>preferences-desktop-font</Icon>
- <ShowTechnical>true</ShowTechnical>
- <Include>
- <Or>
- <PkgWildcard>ttf-*</PkgWildcard>
- <PkgWildcard>otf-*</PkgWildcard>
- <PkgSection>fonts</PkgSection>
- <PkgSection>restricted/fonts</PkgSection>
- <PkgSection>universe/fonts</PkgSection>
- <PkgSection>multiverse/fonts</PkgSection>
- </Or>
- </Include>
- </Menu>
-
- <Menu>
- <Name>Games</Name>
- <Icon>applications-games</Icon>
- <Include>
- <And>
- <Category>Game</Category>
- </And>
- </Include>
-
- <Menu>
- <Name>Arcade</Name>
- <Icon>applications-games-arcade</Icon>
- <Include>
- <And>
- <Category>ArcadeGame</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Board Games</Name>
- <Icon>applications-games-board</Icon>
- <Include>
- <And>
- <Category>BoardGame</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Card Games</Name>
- <Icon>applications-games-card</Icon>
- <Include>
- <And>
- <Category>CardGame</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Puzzles</Name>
- <Icon>applications-games</Icon>
- <Include>
- <And>
- <Category>LogicGame</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Role Playing</Name>
- <Icon>applications-games</Icon>
- <Include>
- <And>
- <Category>RolePlaying</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Simulation</Name>
- <Icon>applications-games-strategy</Icon>
- <Include>
- <And>
- <Category>Simulation</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Sports</Name>
- <Icon>applications-games</Icon>
- <Include>
- <And>
- <Category>SportsGame</Category>
- </And>
- </Include>
- </Menu>
-
- </Menu>
-
-
- <Menu>
- <Name>Graphics</Name>
- <Icon>applications-graphics</Icon>
- <Include>
- <And>
- <Category>Graphics</Category>
- </And>
- </Include>
- <Menu>
- <Name>3D</Name>
- <Include>
- <And>
- <Category>3DGraphics</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Drawing</Name>
- <Icon>draw-freehand</Icon>
- <Include>
- <And>
- <Category>VectorGraphics</Category>
- <Not>
- <Category>Viewer</Category>
- </Not>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Painting &amp; Editing</Name>
- <Icon>draw-brush</Icon>
- <Include>
- <And>
- <Category>RasterGraphics</Category>
- <Not>
- <Category>Viewer</Category>
- <Category>Scanning</Category>
- </Not>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Photography</Name>
- <Icon>image-x-generic</Icon>
- <Include>
- <And>
- <Category>Photography</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Publishing</Name>
- <Icon>document-export</Icon>
- <Include>
- <And>
- <Category>Publishing</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Scanning &amp; OCR</Name>
- <Icon>scanner</Icon>
- <Include>
- <Or>
- <Category>Scanning</Category>
- <Category>OCR</Category>
- </Or>
- </Include>
- </Menu>
- <Menu>
- <Name>Viewers</Name>
- <Icon>graphics-viewer-document</Icon>
- <Include>
- <And>
- <Category>Viewer</Category>
- </And>
- </Include>
- </Menu>
- </Menu>
-
-
- <Menu>
- <Name>Internet</Name>
- <Icon>applications-internet</Icon>
- <Include>
- <And>
- <Category>Network</Category>
- </And>
- </Include>
- <Menu>
- <Name>Chat</Name>
- <Icon>kopete</Icon>
- <Include>
- <Or>
- <Category>InstantMessaging</Category>
- <Category>IRCClient</Category>
- </Or>
- </Include>
- </Menu>
- <Menu>
- <Name>File Sharing</Name>
- <Icon>ktorrent</Icon>
- <Include>
- <And>
- <Category>FileTransfer</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Mail</Name>
- <Icon>internet-mail</Icon>
- <Include>
- <And>
- <Category>Email</Category>
- </And>
- </Include>
- </Menu>
- <Menu>
- <Name>Web Browsers</Name>
- <Icon>internet-web-browser</Icon>
- <Include>
- <And>
- <Category>WebBrowser</Category>
- </And>
- </Include>
- </Menu>
- </Menu>
-
-
- <Menu>
- <Name>Multimedia</Name>
- <Icon>applications-multimedia</Icon>
- <Include>
- <And>
- <Category>AudioVideo</Category>
- </And>
- </Include>
- </Menu>
-
-
- <Menu>
- <Name>Office</Name>
- <Icon>applications-office</Icon>
- <Include>
- <And>
- <Category>Office</Category>
- </And>
- </Include>
- </Menu>
-
- <Menu>
- <Name>System &amp; Settings</Name>
- <Icon>preferences-system</Icon>
- <Include>
- <Or>
- <Category>Settings</Category>
- <Category>System</Category>
- </Or>
- </Include>
- </Menu>
-
- <Menu>
- <Name>Plasma Addons</Name>
- <Icon>plasma</Icon>
-
- <Menu>
- <Name>Plasma Desktop Widgets</Name>
- <Icon>plasma</Icon>
- <ShowTechnical>true</ShowTechnical> <!-- needs to be like this as plasmoids don't get a appinstall file for some reason. -->
- <Include>
- <Or>
- <PkgWildcard>plasma-widget-*</PkgWildcard>
- </Or>
- </Include>
- </Menu>
- </Menu>
-
-</Menu>
diff --git a/libdiscover/backends/ApplicationBackend/qapt-backend.desktop b/libdiscover/backends/ApplicationBackend/qapt-backend.desktop
deleted file mode 100644
index 265f69f..0000000
--- a/libdiscover/backends/ApplicationBackend/qapt-backend.desktop
+++ /dev/null
@@ -1,111 +0,0 @@
-[Desktop Entry]
-Type=Service
-Exec=blubb
-Icon=applications-other
-Comment=Install and browse applications in APT
-Comment[ar]=ثبّت التّطبيقات في APT وتصفّحها
-Comment[ca]=Instal·la i mostra aplicacions en l'APT
-Comment[ca@valencia]=Instal·la i mostra aplicacions en l'APT
-Comment[cs]=Instalujte a prohlížejte aplikace v APT
-Comment[da]=Installér og gennemse programmer i APT
-Comment[de]=Anwendungen in APT installieren und durchsuchen
-Comment[el]=Εγκαταστήστε και περιηγηθείτε σε εφαρμογές με το APT
-Comment[en_GB]=Install and browse applications in APT
-Comment[es]=Instalar y explorar aplicaciones en APT
-Comment[et]=Rakenduste paigaldamine ja sirvimine APT-is
-Comment[fi]=Asenna ja selaa APT:n välityksellä tarjolla olevia sovelluksia
-Comment[fr]=Installer et parcourir des applications dans « APT »
-Comment[gl]=Instalar e buscar aplicacións en APT
-Comment[he]=התקן ודפדפף ביישומים ב־APT
-Comment[id]=Pasang dan jelajahi aplikasi di APT
-Comment[it]=Installa e sfoglia le applicazioni in APT
-Comment[ko]=APT에서 프로그램을 찾고 설치하기
-Comment[nb]=Installer og bla i programmer i APT
-Comment[nl]=Installeer en blader door toepassingen in APT
-Comment[nn]=Installer og bla gjennom program i APT
-Comment[pl]=Wgrywaj i przeglądaj programy w APT
-Comment[pt]=Instalar e navegar nas aplicações do APT
-Comment[pt_BR]=Instala e navega pelos aplicativos no APT
-Comment[ru]=Установка и обзор приложений в APT
-Comment[sk]=Inštalácia a prehliadanie aplikácií v APT
-Comment[sl]=Namestite in brskajte po programih v APT
-Comment[sr]=Инсталирајте и прегледајте програме из АПТ‑а
-Comment[sr@ijekavian]=Инсталирајте и прегледајте програме из АПТ‑а
-Comment[sr@ijekavianlatin]=Instalirajte i pregledajte programe iz APT‑a
-Comment[sr@latin]=Instalirajte i pregledajte programe iz APT‑a
-Comment[sv]=Installera och bläddra bland program med APT
-Comment[uk]=Встановіть і перегляньте встановлені програми у APT
-Comment[x-test]=xxInstall and browse applications in APTxx
-Comment[zh_CN]=安装浏览 APT 中的程序
-Name=Applications Backend
-Name[ar]=سند التّطبيقات
-Name[ca]=Dorsal d'aplicacions
-Name[ca@valencia]=Dorsal d'aplicacions
-Name[cs]=Podpůrná vrstva aplikace
-Name[da]=Program-backend
-Name[de]=Dienstprogramm für Anwendungen
-Name[el]=Σύστημα υποστήριξης εφαρμογών
-Name[en_GB]=Applications Backend
-Name[es]=Motor de aplicaciones
-Name[et]=Rakenduse taustaprogramm
-Name[fi]=Sovellukset-taustajärjestelmä
-Name[fr]=Moteur des applications
-Name[gl]=Infraestrutura de programas
-Name[id]=Backend Aplikasi
-Name[it]=Motore applicazioni
-Name[ko]=프로그램 백엔드
-Name[nb]=Program-bakgrunnsmotor
-Name[nl]=Backend van toepassing
-Name[nn]=Program-bakgrunnsmotor
-Name[pl]=Silnik programów
-Name[pt]=Infra-Estrutura de Aplicações
-Name[pt_BR]=Infraestrutura de aplicativos
-Name[ru]=Модуль приложений
-Name[sk]=Backend aplikácií
-Name[sl]=Zaledje programov
-Name[sr]=Позадина за програме
-Name[sr@ijekavian]=Позадина за програме
-Name[sr@ijekavianlatin]=Pozadina za programe
-Name[sr@latin]=Pozadina za programe
-Name[sv]=Programgränssnitt
-Name[uk]=Модуль програм
-Name[x-test]=xxApplications Backendxx
-Name[zh_CN]=应用程序后端
-GenericName=APT Support
-GenericName[ar]=دعم APT
-GenericName[ca]=Implementació de l'APT
-GenericName[ca@valencia]=Implementació de l'APT
-GenericName[cs]=Podpora APT
-GenericName[da]=APT-understøttelse
-GenericName[de]=Unterstützung für APT
-GenericName[el]=Υποστήριξη APT
-GenericName[en_GB]=APT Support
-GenericName[es]=Uso de APT
-GenericName[et]=APT toetus
-GenericName[fi]=APT-tuki
-GenericName[fr]=Prise en charge de « APT »
-GenericName[gl]=Soporte para APT
-GenericName[he]=APT תומך
-GenericName[id]=APT Support
-GenericName[it]=Supporto APT
-GenericName[ko]=APT 지원
-GenericName[nb]=APT-støtte
-GenericName[nl]=Ondersteuning van APT
-GenericName[nn]=APT-støtte
-GenericName[pl]=Obsługa APT
-GenericName[pt]=Suporte para o APT
-GenericName[pt_BR]=Suporte ao APT
-GenericName[ru]=Поддержка APT
-GenericName[sk]=Podpora APT
-GenericName[sl]=Podpora APT
-GenericName[sr]=Подршка за АПТ
-GenericName[sr@ijekavian]=Подршка за АПТ
-GenericName[sr@ijekavianlatin]=Podrška za APT
-GenericName[sr@latin]=Podrška za APT
-GenericName[sv]=Stöd för APT
-GenericName[uk]=Підтримка APT
-GenericName[x-test]=xxAPT Supportxx
-GenericName[zh_CN]=APT 支持
-X-KDE-Library=qapt-backend
-X-KDE-PluginInfo-Name=qapt-backend
-X-KDE-PluginInfo-License=GPL
diff --git a/libdiscover/backends/ApplicationBackend/qoauth/CMakeLists.txt b/libdiscover/backends/ApplicationBackend/qoauth/CMakeLists.txt
deleted file mode 100644
index 06c858a..0000000
--- a/libdiscover/backends/ApplicationBackend/qoauth/CMakeLists.txt
+++ /dev/null
@@ -1,5 +0,0 @@
-find_package(Qca-qt5 REQUIRED)
-
-add_library(MuonQOAuth STATIC src/interface.cpp)
-target_link_libraries(MuonQOAuth PUBLIC Qt5::Network qca-qt5)
-add_library(Muon::QOAuth ALIAS MuonQOAuth)
diff --git a/libdiscover/backends/ApplicationBackend/qoauth/src/interface.cpp b/libdiscover/backends/ApplicationBackend/qoauth/src/interface.cpp
deleted file mode 100644
index 179f729..0000000
--- a/libdiscover/backends/ApplicationBackend/qoauth/src/interface.cpp
+++ /dev/null
@@ -1,1084 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2009 by Dominik Kapusta <d@ayoy.net> *
- * *
- * This library is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU Lesser General Public License as *
- * published by the Free Software Foundation; either version 2.1 of *
- * the License, or (at your option) any later version. *
- * *
- * This library 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 *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with this library; if not, write to *
- * the Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
-
-
-#include "interface.h"
-#include "interface_p.h"
-
-#include <QtCrypto>
-
-#include <QNetworkAccessManager>
-#include <QNetworkRequest>
-#include <QNetworkReply>
-#include <QUrl>
-#include <QDateTime>
-#include <QtDebug>
-#include <QEventLoop>
-#include <QTimer>
-#include <QFileInfo>
-
-/*!
- \mainpage
-
- \section sec_what What is the purpose of QOAuth?
-
- The main motivation to create this library was to provide an interface to OAuth
- protocol for (Qt-based) C++ applications in an easy way. This is very early version
- of the library, and it lacks some functionality, but in the same time it is capable
- of sending OAuth authorization requests as well as preparing requests for accessing
- User's Protected Resources.
-
- \section sec_lic License and Authors
-
- The project is licensed under <a href=http://www.gnu.org/licenses/lgpl-2.1.html>GNU LGPL
- license</a> version 2.1 or later. The work is done by Dominik Kapusta (d at ayoy dot net).
-
- \section sec_inst How to install?
-
- \subsection ssec_deps Dependencies
-
- There are a few things necessary to get OAuth library working:
-
- <ol>
- <li>Qt libraries, version 4.4 or higher,</li>
- <li>QCA (Qt Cryptographic Architecture), available from
- <a href=http://delta.affinix.com/qca>Delta XMPP Project</a>, version 2.0.0
- or higher,</li>
- <li>OpenSSL plugin to QCA (qca-ossl), available from QCA page, and requiring OpenSSL.</li>
- </ol>
-
- \b Note: KDE4 users meet all the requirements out of the box.
-
- \subsection ssec_inst Installation
-
- The source code repository is hosted on <a href=http://github.com/ayoy/qoauth>GitHub</a>
- and the code can be checked out from there easily using git:
- \verbatim
- $ git clone git://github.com/ayoy/qoauth.git \endverbatim
-
- To compile the code, follow the simple procedure:
-
- \verbatim
- $ qmake
- $ make
- $ sudo make install \endverbatim
-
- \subsection ssec_use Usage
-
- Configuring your project to work with QOAuth library is extremely simple. Firstly,
- append a line to your project file:
- \verbatim
- CONFIG += oauth \endverbatim
-
- Then include the following header in your code:
- \verbatim
- #include <QtOAuth> \endverbatim
-
- \b Note: This follows the Qt scheme, i.e. <tt>QT += xml ==> #include <QtXml></tt>, etc.
-
- \section sec_bugs Bugs and issues
-
- Please file all the bug reports to the QOAuth bug tracking system at
- <a href="http://ayoy.lighthouseapp.com/projects/32547-qoauth/tickets?q=all">
- lighthouseapp.com</a>. If you wish to contribute, you're extremely welcome
- to fork a <a href=http://github.com/ayoy/qoauth>GitHub</a> repository and
- add your input there.
-
-*/
-
-/*!
- \class QOAuth::Interface interface.h <QtOAuth>
- \brief This class provides means for interaction with network services supporting
- OAuth authorization scheme.
-
- The QOAuth::Interface class is meant to enable OAuth support in applications in as simple way
- as possible. It provides 4 basic methods, two of which serve for authorization purposes:
- \li \ref requestToken(),
- \li \ref accessToken(),
-
- and the other two help with creation of requests for accessing Protected Resources:
- \li \ref createParametersString(),
- \li \ref inlineParameters().
-
- \section sec_auth_scheme OAuth authorization scheme
-
- According to <a href=http://oauth.net/core/1.0/#consumer_req_param>
- OAuth 1.0 Core specification</a>, <em>the OAuth protocol enables websites or applications
- (Consumers) to access Protected Resources from a web service (Service Provider) via an
- API, without requiring Users to disclose their Service Provider credentials to the
- Consumers</em>. Simply, OAuth is a way of connecting an application to the Service
- Provider's API without needing to provide User's login or password. The authorization
- is based on an exchange of a Token (user-specific) together with a Consumer Key
- (application-specific), encrypted with a combination of so called Token Secret and
- Customer Secret. Getting access to Protected Resources consists in three basic steps:
- <ol>
- <li>obtaining an unauthorized Request Token from the Service Provider,</li>
- <li>asking the User to authorize the Request Token,</li>
- <li>exchanging the Request Token for the Access Token.</li>
- </ol>
- Details are covered in <a href=http://oauth.net/core/1.0/#anchor9>Section 6</a> of the
- OAuth 1.0 Core Specification. As the authorization procedure is quite complex, the QOAuth
- library helps to simplify it by doing all the dirty work behind the scenes.
-
- \section sec_req_token OAuth authorization with QOAuth
-
- First step of OAuth authorization can be done in one line using QOAuth library.
- Consult the example:
-
- \include requestToken.cpp
-
- Once the unauthorized Request Token is received, User has to authorize it using
- Service Provider-defined method. This is beyond the scope of this library. Once User
- authorizes the Request Token, it can be exchanged for an Access Token that authorizes the
- application to access User's Protected Resources. This can be done with another one line:
-
- \include accessToken.cpp
-
- Once the Access Token is received, the application is authorized.
-
- \section sec_acc_res Requesting Protected Resources with QOAuth
-
- In order to access Protected Resources, the application has to send a request containing
- arguments including Customer Key and Access Token, and encrypt them with Customer Secret
- and Token Secret. The process of constructing such a request can be reduced to another
- one-line call with QOAuth::Interface. The example code for inlining all request parameters
- (both User-specific and OAuth-related):
-
- \include getResources.cpp
-
- If Service Provider requires the OAuth authorization to be done in the <tt>Authorization</tt>
- header field, then only User-specific parameters should be inlined with the URL:
-
- \include getResources2.cpp
-
- \section sec_capabilities Capabilities
-
- QOAuth library works with all 3 signature methods supported by the OAuth protocol, namely
- HMAC-SHA1, RSA-SHA1 and PLAINTEXT. Hovewer, RSA-SHA1 and (especially) PLAINTEXT
- methods may still need additional testing for various input conditions.
-*/
-
-
-QByteArray QOAuth::supportedOAuthVersion()
-{
- return InterfacePrivate::OAuthVersion;
-}
-
-QByteArray QOAuth::tokenParameterName()
-{
- return InterfacePrivate::ParamToken;
-}
-
-QByteArray QOAuth::tokenSecretParameterName()
-{
- return InterfacePrivate::ParamTokenSecret;
-}
-
-
-//! \brief The supported OAuth scheme version.
-const QByteArray QOAuth::InterfacePrivate::OAuthVersion = "1.0";
-
-//! \brief The <em>token</em> request parameter string
-const QByteArray QOAuth::InterfacePrivate::ParamToken = "oauth_token";
-//! \brief The <em>token secret</em> request parameter string
-const QByteArray QOAuth::InterfacePrivate::ParamTokenSecret = "oauth_token_secret";
-
-//! \brief The <em>consumer key</em> request parameter string
-const QByteArray QOAuth::InterfacePrivate::ParamConsumerKey = "oauth_consumer_key";
-//! \brief The <em>nonce</em> request parameter string
-const QByteArray QOAuth::InterfacePrivate::ParamNonce = "oauth_nonce";
-//! \brief The <em>signature</em> request parameter string
-const QByteArray QOAuth::InterfacePrivate::ParamSignature = "oauth_signature";
-//! \brief The <em>signature method</em> request parameter string
-const QByteArray QOAuth::InterfacePrivate::ParamSignatureMethod = "oauth_signature_method";
-//! \brief The <em>timestamp</em> request parameter string
-const QByteArray QOAuth::InterfacePrivate::ParamTimestamp = "oauth_timestamp";
-//! \brief The <em>version</em> request parameter string
-const QByteArray QOAuth::InterfacePrivate::ParamVersion = "oauth_version";
-
-QOAuth::InterfacePrivate::InterfacePrivate() :
- privateKeySet( false ),
- consumerKey( QByteArray() ),
- consumerSecret( QByteArray() ),
- manager(0),
- loop(0),
- requestTimeout(0),
- error( NoError )
-{
-}
-
-void QOAuth::InterfacePrivate::init()
-{
- Q_Q(QOAuth::Interface);
-
- ignoreSslErrors = false;
- loop = new QEventLoop(q);
- setupNetworkAccessManager();
-
- q->connect( &eventHandler, SIGNAL(eventReady(int,QCA::Event)), SLOT(_q_setPassphrase(int,QCA::Event)) );
- eventHandler.start();
-}
-
-void QOAuth::InterfacePrivate::setupNetworkAccessManager()
-{
- Q_Q(QOAuth::Interface);
-
- if (manager == 0)
- manager = new QNetworkAccessManager;
-
- manager->setParent(q);
- q->connect(manager, &QNetworkAccessManager::finished, loop, &QEventLoop::quit);
- q->connect(manager, SIGNAL(finished(QNetworkReply*)), SLOT(_q_parseReply(QNetworkReply*)));
- q->connect(manager, SIGNAL(sslErrors(QNetworkReply*, QList<QSslError>)), SLOT(_q_handleSslErrors(QNetworkReply*, QList<QSslError>)));
-}
-
-QByteArray QOAuth::InterfacePrivate::httpMethodToString( HttpMethod method )
-{
- switch ( method ) {
- case GET:
- return "GET";
- case POST:
- return "POST";
- case HEAD:
- return "HEAD";
- case PUT:
- return "PUT";
-#ifndef Q_WS_WIN
- case DELETE:
- return "DELETE";
-#endif
- default:
- qWarning() << __FUNCTION__ << "- Unrecognized method";
- return QByteArray();
- }
-}
-
-QByteArray QOAuth::InterfacePrivate::signatureMethodToString( SignatureMethod method )
-{
- switch ( method ) {
- case HMAC_SHA1:
- return "HMAC-SHA1";
- case RSA_SHA1:
- return "RSA-SHA1";
- case PLAINTEXT:
- return "PLAINTEXT";
- default:
- qWarning() << __FUNCTION__ << "- Unrecognized method";
- return QByteArray();
- }
-}
-
-QOAuth::ParamMap QOAuth::InterfacePrivate::replyToMap( const QByteArray &data )
-{
- // split reply to name=value strings
- QList<QByteArray> replyParams = data.split( '&' );
- // we'll store them in a map
- ParamMap parameters;
-
- QByteArray replyParam;
- QByteArray key;
- int separatorIndex;
-
- // iterate through name=value pairs
- Q_FOREACH ( replyParam, replyParams ) {
- // find occurrence of '='
- separatorIndex = replyParam.indexOf( '=' );
- // key is on the left
- key = replyParam.left( separatorIndex );
- // value is on the right
- parameters.insert( key , replyParam.right( replyParam.length() - separatorIndex - 1 ) );
- }
-
- return parameters;
-}
-
-void QOAuth::InterfacePrivate::_q_parseReply( QNetworkReply *reply )
-{
- int returnCode = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt();
-
- switch ( returnCode ) {
- case NoError:
- replyParams = replyToMap( reply->readAll() );
- if ( !replyParams.contains( InterfacePrivate::ParamToken ) ) {
- qWarning() << __FUNCTION__ << "- oauth_token not present in reply!";
- }
- if ( !replyParams.contains( InterfacePrivate::ParamTokenSecret ) ) {
- qWarning() << __FUNCTION__ << "- oauth_token_secret not present in reply!";
- }
-
- case BadRequest:
- case Unauthorized:
- case Forbidden:
- error = returnCode;
- break;
- default:
- error = OtherError;
- }
-
- reply->close();
-}
-
-void QOAuth::InterfacePrivate::_q_handleSslErrors(QNetworkReply *reply, const QList<QSslError> &errors)
-{
- Q_UNUSED(errors);
-
- if (ignoreSslErrors)
- reply->ignoreSslErrors();
-}
-
-QByteArray QOAuth::InterfacePrivate::paramsToString( const ParamMap &parameters, ParsingMode mode )
-{
- QByteArray middleString;
- QByteArray endString;
- QByteArray prependString;
-
- switch ( mode ) {
- case ParseForInlineQuery:
- prependString = "?";
- case ParseForRequestContent:
- case ParseForSignatureBaseString:
- middleString = "=";
- endString = "&";
- break;
- case ParseForHeaderArguments:
- prependString = "OAuth ";
- middleString = "=\"";
- endString = "\",";
- break;
- default:
- qWarning() << __FUNCTION__ << "- Unrecognized mode";
- return QByteArray();
- }
-
- QByteArray parameter;
- QByteArray parametersString;
-
- Q_FOREACH( parameter, parameters.uniqueKeys() ) {
- QList<QByteArray> values = parameters.values( parameter );
- if ( values.size() > 1 ) {
- qSort( values.begin(), values.end() );
- }
- QByteArray value;
- Q_FOREACH ( value, values ) {
- parametersString.append( parameter );
- parametersString.append( middleString );
- parametersString.append( value );
- parametersString.append( endString );
- }
- }
-
- // remove the trailing end character (comma or ampersand)
- parametersString.chop(1);
-
- // prepend with the suitable string (or none)
- parametersString.prepend( prependString );
-
- return parametersString;
-}
-
-
-/*!
- \brief Creates a new QOAuth::Interface class instance with the given \a parent
-*/
-
-QOAuth::Interface::Interface( QObject *parent ) :
- QObject( parent ),
- d_ptr( new InterfacePrivate )
-{
- Q_D(Interface);
-
- d->q_ptr = this;
- d->init();
-}
-
-/*!
- \brief Creates a new QOAuth::Interface class instance with the given \a parent,
- using \a manager for network connections.
-
- Use this constructor if you want to use your custom network access manager to
- handle network connections needed by the interface.
-
- /sa setNetworkAccessManager()
-*/
-
-QOAuth::Interface::Interface(QNetworkAccessManager *manager, QObject *parent) :
- QObject( parent ),
- d_ptr( new InterfacePrivate )
-{
- Q_D(Interface);
-
- d->q_ptr = this;
- d->manager = manager;
- d->init();
-}
-
-/*!
- \brief Destroys the QOAuth::Interface object
-*/
-
-QOAuth::Interface::~Interface()
-{
- delete d_ptr;
-}
-
-/*!
- \brief Returns the network access manager used by the interface.
-*/
-QNetworkAccessManager* QOAuth::Interface::networkAccessManager() const
-{
- Q_D(const Interface);
-
- return d->manager;
-}
-
-/*!
- \brief Sets \a manager to be the network access manager used by the interface.
-
- The interface class takes ownership of the manager. If there already is a manager,
- it's being deleted.
-
- /sa networkAccessManager()
-*/
-void QOAuth::Interface::setNetworkAccessManager(QNetworkAccessManager* manager)
-{
- Q_D(Interface);
-
- if (d->manager)
- delete d->manager;
-
- d->manager = manager;
- d->setupNetworkAccessManager();
-}
-
-/*!
- \property QOAuth::Interface::ignoreSslErrors
- \brief This property is used to control SSL errors handling.
-
- The default value is false, meaning that the interface will fail upon an SSL error.
- Set it to true if you want to disregard any SSL errors encountered
- during the authorization process.
-
- Access functions:
- \li <b>bool ignoreSslErrors() const</b>
- \li <b>void setIgnoreSslErrors( bool enabled )</b>
-*/
-
-bool QOAuth::Interface::ignoreSslErrors() const
-{
- Q_D(const QOAuth::Interface);
-
- return d->ignoreSslErrors;
-}
-
-void QOAuth::Interface::setIgnoreSslErrors(bool enabled)
-{
- Q_D(QOAuth::Interface);
-
- d->ignoreSslErrors = enabled;
-}
-
-
-/*!
- \property QOAuth::Interface::consumerKey
- \brief This property holds the consumer key
-
- The consumer key is used by the application to identify itself to the Service Provider.
-
- Access functions:
- \li <b>QByteArray consumerKey() const</b>
- \li <b>void setConsumerKey( const QByteArray &consumerKey )</b>
-*/
-
-QByteArray QOAuth::Interface::consumerKey() const
-{
- Q_D(const Interface);
-
- return d->consumerKey;
-}
-
-void QOAuth::Interface::setConsumerKey( const QByteArray &consumerKey )
-{
- Q_D(Interface);
-
- d->consumerKey = consumerKey;
-}
-
-/*!
- \property QOAuth::Interface::consumerSecret
- \brief This property holds the consumer secret
-
- The consumerSecret is used by the application for signing outgoing requests.
-
- Access functions:
- \li <b>QByteArray consumerSecret() const</b>
- \li <b>void setConsumerSecret( const QByteArray &consumerSecret )</b>
-*/
-
-QByteArray QOAuth::Interface::consumerSecret() const
-{
- Q_D(const Interface);
-
- return d->consumerSecret;
-}
-
-void QOAuth::Interface::setConsumerSecret( const QByteArray &consumerSecret )
-{
- Q_D(Interface);
-
- d->consumerSecret = consumerSecret;
-}
-
-/*!
- \property QOAuth::Interface::requestTimeout
- \brief This property holds the timeout value in milliseconds for issued network requests.
-
- The QOAuth::Interface class can send network requests when asked to do so by calling either
- requestToken() or accessToken() method. By defining the \a requestTimeout, requests
- can have the time constraint applied, after which they fail, setting \ref error to
- \ref Timeout. The \a requestTimeout value is initially set to \c 0, which in this
- case means that no timeout is applied to outgoing requests.
-
- Access functions:
- \li <b>uint requestTimeout() const</b>
- \li <b>void setRequestTimeout( uint requestTimeout )</b>
-*/
-
-uint QOAuth::Interface::requestTimeout() const
-{
- Q_D(const Interface);
-
- return d->requestTimeout;
-}
-
-void QOAuth::Interface::setRequestTimeout( uint msec )
-{
- Q_D(Interface);
-
- d->requestTimeout = msec;
-}
-
-
-/*!
- \property QOAuth::Interface::error
- \brief This property holds the error code
-
- The error code is initially set to \ref NoError, and its value is updated with every
- method that can cause errors.
-
- Access functions:
- \li <b>int error() const</b>
-
- \sa ErrorCode
-*/
-
-int QOAuth::Interface::error() const
-{
- Q_D(const Interface);
-
- return d->error;
-}
-
-
-/*!
- This method is useful when using OAuth with RSA-SHA1 signing algorithm. It reads the RSA
- private key from the string given as \a key, and stores it internally. If the key is
- secured by a passphrase, it should be passed as the second argument.
-
- The provided string is decoded into a private RSA key, optionally using the \a passphrase.
- If \a key contains a valid RSA private key, this method returns true. If any problems were
- encountered during decoding (either the key or the passphrase are invalid), false is
- returned and the error code is set to QOAuth::RSADecodingError.
-
- \sa setRSAPrivateKeyFromFile()
-*/
-
-// bool QOAuth::Interface::setRSAPrivateKey( const QString &key, const QCA::SecureArray &passphrase )
-// {
-// Q_D(Interface);
-//
-// d->setPrivateKey( key, passphrase, InterfacePrivate::KeyFromString );
-//
-// return ( d->error == NoError );
-// }
-
-/*!
- This method is useful when using OAuth with RSA-SHA1 signing algorithm. It reads the RSA
- private key from the given \a file, and stores it internally. If the key is secured by
- a passphrase, it should be passed as the second argument.
-
- The provided file is read and decoded into a private RSA key, optionally using the \a passphrase.
- If it contains a valid RSA private key, this method returns true. If any problems were
- encountered during decoding, false is returned and the appropriate error code is set:
- \li <tt>QOAuth::RSAKeyFileError</tt> - when the key file doesn't exist or is unreadable
- \li <tt>QOAuth::RSADecodingError</tt> - if problems occurred during encoding (either the key
- and/or password are invalid).
-
- \sa setRSAPrivateKey()
-*/
-
-// bool QOAuth::Interface::setRSAPrivateKeyFromFile( const QString &filename, const QCA::SecureArray &passphrase )
-// {
-// Q_D(Interface);
-//
-// if ( ! QFileInfo( filename ).exists() ) {
-// d->error = RSAKeyFileError;
-// qWarning() << __FUNCTION__ << "- the given file does not exist...";
-// } else {
-// d->setPrivateKey( filename, passphrase, InterfacePrivate::KeyFromFile );
-// }
-//
-// return ( d->error == NoError );
-// }
-
-void QOAuth::InterfacePrivate::setPrivateKey( const QString &source,
- const QCA::SecureArray &passphrase, KeySource from )
-{
-
- if( !QCA::isSupported( "pkey" ) ||
- !QCA::PKey::supportedIOTypes().contains( QCA::PKey::RSA ) ) {
- qFatal( "RSA is not supported!" );
- }
-
- privateKeySet = false;
- this->passphrase = passphrase;
-
- QCA::KeyLoader keyLoader;
- QEventLoop localLoop;
- QObject::connect(&keyLoader, &QCA::KeyLoader::finished, &localLoop, &QEventLoop::quit);
-
- switch (from) {
- case KeyFromString:
- keyLoader.loadPrivateKeyFromPEM( source );
- break;
- case KeyFromFile:
- keyLoader.loadPrivateKeyFromPEMFile( source );
- break;
- }
-
- QTimer::singleShot( 3000, &localLoop, SLOT(quit()) );
- localLoop.exec();
-
- readKeyFromLoader( &keyLoader );
-}
-
-void QOAuth::InterfacePrivate::readKeyFromLoader( QCA::KeyLoader *keyLoader )
-{
- QCA::ConvertResult result = keyLoader->convertResult();
- if ( result == QCA::ConvertGood ) {
- error = NoError;
- privateKey = keyLoader->privateKey();
- privateKeySet = true;
- } else if ( result == QCA::ErrorDecode ) {
- error = RSADecodingError;
- // this one seems to never be set ....
- // } else if ( result == QCA::ErrorPassphrase ) {
- // error = RSAPassphraseError;
- } else if ( result == QCA::ErrorFile ) {
- error = RSAKeyFileError;
- }
-}
-
-void QOAuth::InterfacePrivate::_q_setPassphrase( int id, const QCA::Event &event )
-{
- if ( event.isNull() ) {
- return;
- }
-
- // we're looking only for the passphrase for the RSA key
- if ( event.type() == QCA::Event::Password &&
- event.passwordStyle() == QCA::Event::StylePassphrase ) {
- // set the passphrase to the one provided with QOAuth::Interface::setRSAPrivateKey{,FromFile}()
- eventHandler.submitPassword( id, passphrase );
- } else {
- eventHandler.reject( id );
- }
-}
-
-/*!
- This method constructs and sends a request for obtaining an unauthorized Request Token
- from the Service Provider. This is the first step of the OAuth authentication flow,
- according to <a href=http://oauth.net/core/1.0/#anchor9>OAuth 1.0 Core specification</a>.
- The PLAINTEXT signature method uses Customer Secret and (if provided) Token Secret to
- sign a request. For the HMAC-SHA1 and RSA-SHA1 signature methods the
- <a href=http://oauth.net/core/1.0/#anchor14>Signature Base String</a> is created
- using the given \a requestUrl and \a httpMethod. The optional request parameters
- specified by the Service Provider can be passed in the \a params ParamMap.
-
- The Signature Base String contains the \ref consumerKey and uses \ref consumerSecret
- for encrypting the message, so it's necessary to provide them both before issuing this
- request. The method will check if both \ref consumerKey and \ref consumerSecret are
- provided, and fail if any of them is missing.
-
- When the signature is created, the appropriate request is sent to the Service Provider
- (namely, the \a requestUrl). Depending on the type of the request, the parameters are
- passed according to the <a href=http://oauth.net/core/1.0/#consumer_req_param>
- Consumer Request Parametes</a> section of the OAuth specification, i.e.:
- \li for GET requests, in the HTTP Authorization header, as defined in
- <a href=http://oauth.net/core/1.0/#auth_header>OAuth HTTP Authorization Scheme</a>,
- \li for POST requests, as a request body with \c content-type set to
- \c application/x-www-form-urlencoded.
-
- Once the request is sent, a local event loop is executed and set up to wait for the request
- to complete. If the \ref requestTimeout property is set to a non-zero value, its vaue
- is applied as a request timeout, after which the request is aborted.
-
- \returns If request succeded, the method returns all the data passed in the Service
- Provider response (including a Request Token and Token Secret), formed in a ParamMap.
- If request fails, the \ref error property is set to an appropriate value, and an empty
- ParamMap is returned.
-
- \sa accessToken(), error
-*/
-
-QOAuth::ParamMap QOAuth::Interface::requestToken( const QString &requestUrl, HttpMethod httpMethod,
- SignatureMethod signatureMethod, const ParamMap &params )
-{
- Q_D(Interface);
-
- return d->sendRequest( requestUrl, httpMethod, signatureMethod,
- QByteArray(), QByteArray(), params );
-}
-
-/*!
- This method constructs and sends a request for exchanging a Request Token (obtained
- previously with a call to \ref requestToken()) for an Access Token, that authorizes the
- application to access Protected Resources. This is the third step of the OAuth
- authentication flow, according to <a href=http://oauth.net/core/1.0/#anchor9>OAuth 1.0
- Core specification</a>. The PLAINTEXT signature method uses Customer Secret and (if
- provided) Token Secret to sign a request. For the HMAC-SHA1 and RSA-SHA1
- signature methods the <a href=http://oauth.net/core/1.0/#anchor14>Signature Base String</a>
- is created using the given \a requestUrl, \a httpMethod, \a token and \a tokenSecret.
- The optional request parameters specified by the Service Provider can be passed in the
- \a params ParamMap.
-
- The Signature Base String contains the \ref consumerKey and uses \ref consumerSecret
- for encrypting the message, so it's necessary to provide them both before issuing
- this request. The method will check if both \ref consumerKey and \ref consumerSecret
- are provided, and fail if any of them is missing.
-
- When the signature is created, the appropriate request is sent to the Service Provider
- (namely, the \a requestUrl). Depending on the type of the request, the parameters are
- passed according to the <a href=http://oauth.net/core/1.0/#consumer_req_param>
- Consumer Request Parametes</a> section of the OAuth specification, i.e.:
- \li for GET requests, in the HTTP Authorization header, as defined in
- <a href=http://oauth.net/core/1.0/#auth_header>OAuth HTTP Authorization Scheme</a>,
- \li for POST requests, as a request body with \c content-type set to
- \c application/x-www-form-urlencoded.
-
- Once the request is sent, a local event loop is executed and set up to wait for the request
- to complete. If the \ref requestTimeout property is set to a non-zero value, its vaue
- is applied as a request timeout, after which the request is aborted.
-
- \returns If request succeded, the method returns all the data passed in the Service
- Provider response (including an authorized Access Token and Token Secret), formed in
- a ParamMap. This request ends the authorization process, and the obtained Access Token
- and Token Secret should be kept by the application and provided with every future request
- authorized by OAuth, e.g. using \ref createParametersString(). If request fails, the
- \ref error property is set to an appropriate value, and an empty ParamMap is returned.
-
- \sa requestToken(), createParametersString(), error
-*/
-
-QOAuth::ParamMap QOAuth::Interface::accessToken( const QString &requestUrl, HttpMethod httpMethod, const QByteArray &token,
- const QByteArray &tokenSecret, SignatureMethod signatureMethod,
- const ParamMap &params )
-{
- Q_D(Interface);
-
- return d->sendRequest( requestUrl, httpMethod, signatureMethod,
- token, tokenSecret, params );
-
-}
-
-/*!
- This method generates a parameters string required to access Protected Resources using
- OAuth authorization. According to <a href=http://oauth.net/core/1.0/#anchor13>OAuth 1.0
- Core specification</a>, every outgoing request for accessing Protected Resources must
- contain information like the Consumer Key and Access Token, and has to be signed using one
- of the supported signature methods.
-
- The PLAINTEXT signature method uses Customer Secret and (if provided) Token Secret to
- sign a request. For the HMAC-SHA1 and RSA-SHA1 signature methods the
- <a href=http://oauth.net/core/1.0/#anchor14>Signature Base String</a> is created using
- the given \a requestUrl, \a httpMethod, \a token and \a tokenSecret. The optional
- request parameters specified by the Service Provider can be passed in the \a params
- \ref ParamMap.
-
- The Signature Base String contains the \ref consumerKey and uses \ref consumerSecret
- for encrypting the message, so it's necessary to provide them both before issuing
- this request. The method will check if both \ref consumerKey and \ref consumerSecret
- are provided, and fail if any of them is missing.
-
- The \a mode parameter specifies the format of the parameter string.
-
- \returns The parsed parameters string, that depending on \a mode and \a httpMethod is:
-
- <table>
- <tr><td>\b \a mode </td> <td>\b outcome </td></tr>
- <tr><td><tt>QOAuth::ParseForRequestContent</tt></td> <td>ready to be posted as a request body</td></tr>
- <tr><td><tt>QOAuth::ParseForInlineQuery</tt></td> <td>prepended with a <em>'?'</em> and ready to be appended to the \a requestUrl</td></tr>
- <tr><td><tt>QOAuth::ParseForHeaderArguments</tt></td> <td>ready to be set as an argument for the \c Authorization HTTP header</td></tr>
- <tr><td><tt>QOAuth::ParseForSignatureBaseString</tt></td> <td><em>meant for internal use</em></td></tr>
- </table>
-
- \sa inlineParameters()
-*/
-
-QByteArray QOAuth::Interface::createParametersString( const QString &requestUrl, HttpMethod httpMethod, const QByteArray &token,
- const QByteArray &tokenSecret, SignatureMethod signatureMethod,
- const ParamMap &params, ParsingMode mode )
-{
- Q_D(Interface);
-
- d->error = NoError;
-
- // copy parameters to a writeable object
- ParamMap parameters = params;
- // calculate the signature
- QByteArray signature = d->createSignature( requestUrl, httpMethod, signatureMethod,
- token, tokenSecret, &parameters );
-
- // return an empty bytearray when signature wasn't created
- if ( d->error != NoError ) {
- return QByteArray();
- }
-
- // append it to parameters
- parameters.insert( InterfacePrivate::ParamSignature, signature );
- // convert the map to bytearray, according to requested mode
- QByteArray parametersString = d->paramsToString( parameters, mode );
-
- return parametersString;
-}
-
-/*!
- This method is provided for convenience. It generates an inline query string out of
- given parameter map. The resulting string can be either sent in an HTTP POST request
- as a request content, or appended directly to an HTTP GET request's URL as a query string.
- When using this method for preparing an HTTP GET query string you can set the \a mode
- to ParseForInlineQuery to have the string prepended with a question mark (separating
- the URL path from the query string). Modes other than QOAuth::ParseForRequestContent and
- QOAuth::ParseForInlineQuery produce an empty byte array.
-
- Use this method together with createParametersString(), when you request a header
- parameters string (QOAuth::ParseForHeaderArguments) together with HTTP GET method.
- In such case, apart from header arguments, you must provide a query string containing
- custom request parameters (i.e. not OAuth-related). Pass the custom parameters map
- to this method to receive a query string to be appended to the URL.
-
- \sa createParametersString()
-*/
-
-QByteArray QOAuth::Interface::inlineParameters( const ParamMap &params, ParsingMode mode )
-{
- Q_D(Interface);
-
- QByteArray query;
-
- switch (mode) {
- case ParseForInlineQuery:
- case ParseForRequestContent:
- query = d->paramsToString( params, mode );
- break;
- case ParseForHeaderArguments:
- case ParseForSignatureBaseString:
- break;
- }
-
- return query;
-}
-
-QOAuth::ParamMap QOAuth::InterfacePrivate::sendRequest( const QString &requestUrl, HttpMethod httpMethod,
- SignatureMethod signatureMethod, const QByteArray &token,
- const QByteArray &tokenSecret, const ParamMap &params )
-{
- if ( httpMethod != GET && httpMethod != POST ) {
- qWarning() << __FUNCTION__ << "- requestToken() and accessToken() accept only GET and POST methods";
- error = UnsupportedHttpMethod;
- return ParamMap();
- }
-
- error = NoError;
-
- ParamMap parameters = params;
-
- // create signature
- QByteArray signature = createSignature( requestUrl, httpMethod, signatureMethod,
- token, tokenSecret, &parameters );
-
- // if signature wasn't created, return an empty map
- if ( error != NoError ) {
- return ParamMap();
- }
-
- // add signature to parameters
- parameters.insert( InterfacePrivate::ParamSignature, signature );
-
- QByteArray authorizationHeader;
- QNetworkRequest request;
-
- if ( httpMethod == GET ) {
- authorizationHeader = paramsToString( parameters, ParseForHeaderArguments );
- // create the authorization header
- request.setRawHeader( "Authorization", authorizationHeader );
- } else if ( httpMethod == POST ) {
- authorizationHeader = paramsToString( parameters, ParseForRequestContent );
- // create a network request
- request.setHeader( QNetworkRequest::ContentTypeHeader, QStringLiteral("application/x-www-form-urlencoded") );
- }
-
- request.setUrl( QUrl( requestUrl ) );
-
- // fire up a single shot timer if timeout was specified
- if ( requestTimeout > 0 ) {
- QTimer::singleShot( requestTimeout, loop, SLOT(quit()) );
- // if the request finishes on time, the error value is overriden
- // if not, it remains equal to QOAuth::Interface::Timeout
- error = Timeout;
- }
-
- // clear the reply container and send the request
- replyParams.clear();
- QNetworkReply *reply;
- if ( httpMethod == GET ) {
- reply = manager->get( request );
- } else if ( httpMethod == POST ) {
- reply = manager->post( request, authorizationHeader );
- }
-
- // start the event loop and wait for the response
- loop->exec();
-
- // if request completed successfully, error is different than QOAuth::Interface::Timeout
- // if it failed, we have to abort the request
- if ( error == Timeout ) {
- reply->abort();
- }
-
- return replyParams;
-}
-
-QByteArray QOAuth::InterfacePrivate::createSignature( const QString &requestUrl, HttpMethod httpMethod,
- SignatureMethod signatureMethod, const QByteArray &token,
- const QByteArray &tokenSecret, ParamMap *params )
-{
- if ( ( signatureMethod == HMAC_SHA1 ||
- signatureMethod == RSA_SHA1 ) &&
- consumerKey.isEmpty() ) {
- qWarning() << __FUNCTION__ << "- consumer key is empty, make sure that you set it"
- "with QOAuth::Interface::setConsumerKey()";
- error = ConsumerKeyEmpty;
- return QByteArray();
- }
- if ( consumerSecret.isEmpty() ) {
- qWarning() << __FUNCTION__ << "- consumer secret is empty, make sure that you set it"
- "with QOAuth::Interface::setConsumerSecret()";
- error = ConsumerSecretEmpty;
- return QByteArray();
- }
-
- if ( signatureMethod == RSA_SHA1 &&
- privateKey.isNull() ) {
- qWarning() << __FUNCTION__ << "- RSA private key is empty, make sure that you provide it"
- "with QOAuth::Interface::setRSAPrivateKey{,FromFile}()";
- error = RSAPrivateKeyEmpty;
- return QByteArray();
- }
-
- // create nonce
- QCA::InitializationVector iv( 16 );
- QByteArray nonce = iv.toByteArray().toHex();
-
- // create timestamp
- uint time = QDateTime::currentDateTime().toTime_t();
- QByteArray timestamp = QByteArray::number( time );
-
- // create signature base string
- // 1. create the method string
- QByteArray httpMethodString = httpMethodToString( httpMethod );
- // 2. prepare percent-encoded request URL
- QByteArray percentRequestUrl = requestUrl.toLatin1().toPercentEncoding();
- // 3. prepare percent-encoded parameters string
- params->insert( InterfacePrivate::ParamConsumerKey, consumerKey );
- params->insert( InterfacePrivate::ParamNonce, nonce );
- params->insert( InterfacePrivate::ParamSignatureMethod,
- signatureMethodToString( signatureMethod ) );
- params->insert( InterfacePrivate::ParamTimestamp, timestamp );
- params->insert( InterfacePrivate::ParamVersion, InterfacePrivate::OAuthVersion );
- // append token only if it is defined (requestToken() doesn't use a token at all)
- if ( !token.isEmpty() ) {
- params->insert( InterfacePrivate::ParamToken, token );
- }
-
- QByteArray parametersString = paramsToString( *params, ParseForSignatureBaseString );
- QByteArray percentParametersString = parametersString.toPercentEncoding();
-
- QByteArray digest;
-
- // PLAINTEXT doesn't use the Signature Base String
- if ( signatureMethod == PLAINTEXT ) {
- digest = createPlaintextSignature( tokenSecret );
- } else {
- // 4. create signature base string
- QByteArray signatureBaseString;
- signatureBaseString.append( httpMethodString + '&' );
- signatureBaseString.append( percentRequestUrl + '&' );
- signatureBaseString.append( percentParametersString );
-
-
- if ( signatureMethod == HMAC_SHA1 ) {
- if( !QCA::isSupported( "hmac(sha1)" ) ) {
- qFatal( "HMAC(SHA1) is not supported!" );
- }
- // create key for HMAC-SHA1 hashing
- QByteArray key( consumerSecret.toPercentEncoding() + '&' + tokenSecret.toPercentEncoding() );
-
- // create HMAC-SHA1 digest in Base64
- QCA::MessageAuthenticationCode hmac( QStringLiteral("hmac(sha1)"), QCA::SymmetricKey( key ) );
- QCA::SecureArray array( signatureBaseString );
- hmac.update( array );
- QCA::SecureArray resultArray = hmac.final();
- digest = resultArray.toByteArray().toBase64();
-
- } else if ( signatureMethod == RSA_SHA1 ) {
- // sign the Signature Base String with the RSA key
- digest = privateKey.signMessage( QCA::MemoryRegion( signatureBaseString ),
- QCA::EMSA3_SHA1 ).toBase64();
- }
- }
-
- // percent-encode the digest
- QByteArray signature = digest.toPercentEncoding();
- return signature;
-}
-
-QByteArray QOAuth::InterfacePrivate::createPlaintextSignature( const QByteArray &tokenSecret )
-{
- if ( consumerSecret.isEmpty() ) {
- qWarning() << __FUNCTION__ << "- consumer secret is empty, make sure that you set it"
- "with QOAuth::Interface::setConsumerSecret()";
- error = ConsumerSecretEmpty;
- return QByteArray();
- }
-
- // get percent encoded consumer secret and token secret, join and return
- return consumerSecret.toPercentEncoding() + '&' + tokenSecret.toPercentEncoding();
-}
-
-#include "moc_interface.cpp"
diff --git a/libdiscover/backends/ApplicationBackend/qoauth/src/interface.h b/libdiscover/backends/ApplicationBackend/qoauth/src/interface.h
deleted file mode 100644
index bddc53d..0000000
--- a/libdiscover/backends/ApplicationBackend/qoauth/src/interface.h
+++ /dev/null
@@ -1,119 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2009 by Dominik Kapusta <d@ayoy.net> *
- * *
- * This library is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU Lesser General Public License as *
- * published by the Free Software Foundation; either version 2.1 of *
- * the License, or (at your option) any later version. *
- * *
- * This library 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 *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with this library; if not, write to *
- * the Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
-
-
-/*!
- \file interface.h
-
- This file is a part of libqoauth. You should not include it directly in your
- application. Instead please use <tt>\#include &lt;QtOAuth&gt;</tt>.
-*/
-
-#ifndef INTERFACE_H
-#define INTERFACE_H
-
-#include <QObject>
-
-#define slots Q_SLOTS
-#define signals Q_SIGNALS
-
-#include <QtCrypto>
-
-#include "qoauth_global.h"
-#include "qoauth_namespace.h"
-
-class QNetworkAccessManager;
-class QNetworkReply;
-
-namespace QOAuth {
-
-class InterfacePrivate;
-
-class QOAUTH_EXPORT Interface : public QObject
-{
- Q_OBJECT
-
- Q_PROPERTY( QByteArray consumerKey READ consumerKey WRITE setConsumerKey )
- Q_PROPERTY( QByteArray consumerSecret READ consumerSecret WRITE setConsumerSecret )
- Q_PROPERTY( uint requestTimeout READ requestTimeout WRITE setRequestTimeout )
- Q_PROPERTY( bool ignoreSslErrors READ ignoreSslErrors WRITE setIgnoreSslErrors )
- Q_PROPERTY( int error READ error )
-
-public:
- Interface( QObject *parent = 0 );
- Interface( QNetworkAccessManager *manager, QObject *parent = 0 );
- virtual ~Interface();
-
- QNetworkAccessManager* networkAccessManager() const;
- void setNetworkAccessManager(QNetworkAccessManager *manager);
-
- bool ignoreSslErrors() const;
- void setIgnoreSslErrors(bool enabled);
-
- QByteArray consumerKey() const;
- void setConsumerKey( const QByteArray &consumerKey );
-
- QByteArray consumerSecret() const;
- void setConsumerSecret( const QByteArray &consumerSecret );
-
- uint requestTimeout() const;
- void setRequestTimeout( uint msec );
-
- int error() const;
-
-// bool setRSAPrivateKey( const QString &key,
-// const QCA::SecureArray &passphrase = QCA::SecureArray() );
-// bool setRSAPrivateKeyFromFile( const QString &filename,
-// const QCA::SecureArray &passphrase = QCA::SecureArray() );
-
-
- ParamMap requestToken( const QString &requestUrl, HttpMethod httpMethod,
- SignatureMethod signatureMethod = HMAC_SHA1, const ParamMap &params = ParamMap() );
-
- ParamMap accessToken( const QString &requestUrl, HttpMethod httpMethod, const QByteArray &token,
- const QByteArray &tokenSecret, SignatureMethod signatureMethod = HMAC_SHA1,
- const ParamMap &params = ParamMap() );
-
- QByteArray createParametersString( const QString &requestUrl, HttpMethod httpMethod,
- const QByteArray &token, const QByteArray &tokenSecret,
- SignatureMethod signatureMethod, const ParamMap &params, ParsingMode mode );
-
- QByteArray inlineParameters( const ParamMap &params, ParsingMode mode = ParseForRequestContent );
-
-
-protected:
- InterfacePrivate * const d_ptr;
-
-private:
- Q_DISABLE_COPY(Interface)
- Q_DECLARE_PRIVATE(Interface)
- Q_PRIVATE_SLOT(d_func(), void _q_parseReply(QNetworkReply *reply))
- Q_PRIVATE_SLOT(d_func(), void _q_setPassphrase(int id, const QCA::Event &event))
- Q_PRIVATE_SLOT(d_func(), void _q_handleSslErrors( QNetworkReply *reply,
- const QList<QSslError> &errors ))
-
-#ifdef UNIT_TEST
- friend class Ut_Interface;
- friend class Ft_Interface;
-#endif
-};
-
-} // namespace QOAuth
-
-#endif // INTERFACE_H
diff --git a/libdiscover/backends/ApplicationBackend/qoauth/src/interface_p.h b/libdiscover/backends/ApplicationBackend/qoauth/src/interface_p.h
deleted file mode 100644
index 97f3a6e..0000000
--- a/libdiscover/backends/ApplicationBackend/qoauth/src/interface_p.h
+++ /dev/null
@@ -1,127 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2009 by Dominik Kapusta <d@ayoy.net> *
- * *
- * This library is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU Lesser General Public License as *
- * published by the Free Software Foundation; either version 2.1 of *
- * the License, or (at your option) any later version. *
- * *
- * This library 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 *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with this library; if not, write to *
- * the Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
-
-
-/*!
- \file interface_p.h
-
- This file is a part of libqoauth and is considered strictly internal. You should not
- include it in your application. Instead please use <tt>\#include &lt;QtOAuth&gt;</tt>.
-*/
-
-#ifndef QOAUTH_P_H
-#define QOAUTH_P_H
-
-#include "interface.h"
-#include <QPointer>
-#include <QNetworkAccessManager>
-// #include <QtCrypto>
-
-class QNetworkReply;
-class QEventLoop;
-
-namespace QOAuth {
-
-class Interface;
-
-
-class QOAUTH_EXPORT InterfacePrivate
-{
- Q_DECLARE_PUBLIC(Interface)
-
-public:
- enum Operation {
- RequestToken,
- Authorize,
- Authenticate,
- AccessToken
- };
-
- enum KeySource {
- KeyFromString,
- KeyFromFile
- };
-
- static const QByteArray OAuthVersion;
- static const QByteArray ParamToken;
- static const QByteArray ParamTokenSecret;
-
- static const QByteArray ParamConsumerKey;
- static const QByteArray ParamNonce;
- static const QByteArray ParamSignature;
- static const QByteArray ParamSignatureMethod;
- static const QByteArray ParamTimestamp;
- static const QByteArray ParamVersion;
-
-
- InterfacePrivate();
- void init();
- void setupNetworkAccessManager();
-
- QByteArray httpMethodToString( HttpMethod method );
- QByteArray signatureMethodToString( SignatureMethod method );
- ParamMap replyToMap( const QByteArray &data );
- QByteArray paramsToString( const ParamMap &parameters, ParsingMode mode );
-
- QByteArray createSignature( const QString &requestUrl, HttpMethod httpMethod,
- SignatureMethod signatureMethod, const QByteArray &token,
- const QByteArray &tokenSecret, ParamMap *params );
-
- // for PLAINTEXT only
- QByteArray createPlaintextSignature( const QByteArray &tokenSecret );
-
- ParamMap sendRequest( const QString &requestUrl, HttpMethod httpMethod, SignatureMethod signatureMethod,
- const QByteArray &token, const QByteArray &tokenSecret, const ParamMap &params );
-
- // RSA-SHA1 stuff
- void setPrivateKey( const QString &source, const QCA::SecureArray &passphrase, KeySource from );
- void readKeyFromLoader( QCA::KeyLoader *keyLoader );
-
- bool privateKeySet;
-
- QCA::Initializer initializer;
- QCA::PrivateKey privateKey;
- QCA::SecureArray passphrase;
- QCA::EventHandler eventHandler;
- // end of RSA-SHA1 stuff
-
- bool ignoreSslErrors;
- QByteArray consumerKey;
- QByteArray consumerSecret;
-
- ParamMap replyParams;
-
- QPointer<QNetworkAccessManager> manager;
- QEventLoop *loop;
-
- uint requestTimeout;
- int error;
-
-protected:
- Interface *q_ptr;
-
-public:
- void _q_parseReply( QNetworkReply *reply );
- void _q_setPassphrase( int id, const QCA::Event &event );
- void _q_handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors );
-};
-
-} // namespace QOAuth
-
-#endif // INTERFACE_P_H
diff --git a/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_global.h b/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_global.h
deleted file mode 100644
index 66c0d5b..0000000
--- a/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_global.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2009 by Dominik Kapusta <d@ayoy.net> *
- * *
- * This library is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU Lesser General Public License as *
- * published by the Free Software Foundation; either version 2.1 of *
- * the License, or (at your option) any later version. *
- * *
- * This library 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 *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with this library; if not, write to *
- * the Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
-
-
-/*!
- \file qoauth_global.h
-
- This file is a part of libqoauth and is considered strictly internal. You should not
- include it in your application. Instead please use <tt>\#include &lt;QtOAuth&gt;</tt>.
-*/
-
-#ifndef QOAUTH_GLOBAL_H
-#define QOAUTH_GLOBAL_H
-
-#include <QtCore/qglobal.h>
-
-#if defined(QOAUTH)
-# define QOAUTH_EXPORT Q_DECL_EXPORT
-#else
-# define QOAUTH_EXPORT Q_DECL_IMPORT
-#endif
-
-#endif // QOAUTH_GLOBAL_H
diff --git a/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_namespace.h b/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_namespace.h
deleted file mode 100644
index fb2270b..0000000
--- a/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_namespace.h
+++ /dev/null
@@ -1,180 +0,0 @@
-/***************************************************************************
- * Copyright (C) 2009 by Dominik Kapusta <d@ayoy.net> *
- * *
- * This library is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU Lesser General Public License as *
- * published by the Free Software Foundation; either version 2.1 of *
- * the License, or (at your option) any later version. *
- * *
- * This library 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 *
- * Lesser General Public License for more details. *
- * *
- * You should have received a copy of the GNU Lesser General Public *
- * License along with this library; if not, write to *
- * the Free Software Foundation, Inc., *
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
- ***************************************************************************/
-
-
-/*!
- \file qoauth_namespace.h
-
- This file is a part of libqoauth. You should not include it directly in your
- application. Instead please use <tt>\#include &lt;QtOAuth&gt;</tt>.
-*/
-
-#ifndef QOAUTH_NAMESPACE_H
-#define QOAUTH_NAMESPACE_H
-
-#include <QMultiMap>
-#include <QByteArray>
-
-#include "qoauth_global.h"
-
-/*!
- \namespace QOAuth
- \brief This namespace encapsulates all classes and definitions provided by libqoauth.
-*/
-namespace QOAuth {
-
- /*!
- \typedef ParamMap
- \brief A typedef for the data structure for storing request parameters
- */
- typedef QMultiMap<QByteArray,QByteArray> ParamMap;
-
- /*!
- \enum SignatureMethod
- \brief This enum type describes the signature method used by the request.
-
- There are 3 different signature methods defined by the
- <a href=http://oauth.net/core/1.0/#signing_process>OAuth protocol</a>. This enum
- is used to specify the method used by a specific request. Hence, one of its values
- must be passed as a parameter in any of the \ref QOAuth::Interface::requestToken(),
- \ref QOAuth::Interface::accessToken() or \ref QOAuth::Interface::createParametersString()
- method.
- */
- enum SignatureMethod {
- HMAC_SHA1, //!< Sets the signature method to HMAC-SHA1
- RSA_SHA1, //!< Sets the signature method to RSA-SHA1 (not implemented yet)
- PLAINTEXT //!< Sets the signature method to PLAINTEXT (not implemented yet)
- };
-
- /*!
- \enum HttpMethod
- \brief This enum type specifies the HTTP method used for creating
- a <a href=http://oauth.net/core/1.0/#anchor14>Signature Base String</a>
- and/or sending a request.
-
- The HTTP method has to be specified in QOAuth class for two reasons:
- \li to know what type of request should be prepared and sent
- (\ref QOAuth::Interface::requestToken() and \ref QOAuth::Interface::accessToken()),
- \li to prepare a correct signature, as the Signature Base String contains a parameter
- specifying the HTTP method used for request (\ref QOAuth::Interface::createParametersString()).
-
- \note For \ref QOAuth::Interface::requestToken() and \ref QOAuth::Interface::accessToken() methods
- only \ref GET and \ref POST methods are allowed.
- */
- enum HttpMethod {
- GET, //!< Sets the HTTP method to GET
- POST, //!< Sets the HTTP method to POST
- HEAD, //!< Sets the HTTP method to HEAD
- PUT //!< Sets the HTTP method to PUT
-#ifndef Q_WS_WIN
- , DELETE //!< Sets the HTTP method to DELETE
-#endif
- };
-
- /*!
- \enum ParsingMode
- \brief This enum type specifies the method of parsing parameters into
- a parameter string.
-
- When creating a parameters string for a custom request using
- \ref QOAuth::Interface::createParametersString() the parsing mode must be defined in order
- to prepare the string correctly.
-
- According to what is stated in <a href=http://oauth.net/core/1.0/#consumer_req_param>
- OAuth 1.0 Core specification</a>, parameters can be passed in a request to
- the Service Provider in 3 different ways. When using \ref QOAuth::Interface::createParametersString(),
- choose the one that suits you by setting \a ParsingMode appropriatelly.
-
- \sa QOAuth::Interface::createParametersString()
- */
- enum ParsingMode {
- ParseForRequestContent, //!< Inline query format (<tt>foo=bar&bar=baz&baz=foo ...</tt>), suitable for POST requests
- ParseForInlineQuery, /*!< Same as ParseForRequestContent, but prepends the string with a question mark -
- suitable for GET requests (appending parameters to the request URL) */
- ParseForHeaderArguments, //!< HTTP request header format (parameters to be put inside a request header)
- ParseForSignatureBaseString //!< <a href=http://oauth.net/core/1.0/#anchor14>Signature Base String</a> format, meant for internal use.
- };
-
- /*!
- \enum ErrorCode
- \brief This enum type defines error types that are assigned to the
- \ref QOAuth::Interface::error property
-
- This error codes collection contains both network-related errors and those that
- can occur when incorrect arguments are provided to any of the class's methods.
-
- \sa QOAuth::Interface::error
- */
- enum ErrorCode {
- NoError = 200, //!< No error occured (so far :-) )
- BadRequest = 400, //!< Represents HTTP status code \c 400 (Bad Request)
- Unauthorized = 401, //!< Represents HTTP status code \c 401 (Unauthorized)
- Forbidden = 403, //!< Represents HTTP status code \c 403 (Forbidden)
- Timeout = 1001, //!< Represents a request timeout error
- ConsumerKeyEmpty, //!< Consumer key has not been provided
- ConsumerSecretEmpty, //!< Consumer secret has not been provided
- UnsupportedHttpMethod, /*!< The HTTP method is not supported by the request.
- \note \ref QOAuth::Interface::requestToken() and
- \ref QOAuth::Interface::accessToken()
- accept only HTTP GET and POST requests. */
-
- RSAPrivateKeyEmpty = 1101, //!< RSA private key has not been provided
- // RSAPassphraseError, //!< RSA passphrase is incorrect (or has not been provided)
- RSADecodingError, /*!< There was a problem decoding the RSA private key
- (the key is invalid or the provided passphrase is incorrect)*/
- RSAKeyFileError, //!< The provided key file either doesn't exist or is unreadable.
- OtherError //!< A network-related error not specified above
- };
-
-
- /*!
- \brief Returns the supported OAuth protocol version
- */
- QOAUTH_EXPORT QByteArray supportedOAuthVersion();
-
- /*!
- \brief Returns the name of the Access Token argument parameter (<tt>oauth_token</tt> in
- current implementation)
-
- Useful when reading Service Provider's reply for \ref QOAuth::Interface::accessToken() request, e.g:
- \code
- QOAuth::Interface qoauth;
- QByteArray requestToken = "token";
- QByteArray requestTokenSecret = "secret";
- QOAuth::ParamMap reply = qoauth.accessToken( "http://example.com/access_token", QOAuth::POST,
- token, tokenSecret, QOAuth::HMAC_SHA1 );
-
- if ( qoauth.error() == QOAuth::NoError ) {
- token = reply.value( QOAuth::tokenParameterName() );
- tokenSecret = reply.value( QOAuth::tokenSecretParameterName() );
- }
- \endcode
- */
- QOAUTH_EXPORT QByteArray tokenParameterName();
-
- /*!
- \brief Returns the name of the Token Secret argument parameter (<tt>oauth_token_secret</tt> in
- current implementation)
- \sa QOAuth::tokenParameterName()
- */
- QOAUTH_EXPORT QByteArray tokenSecretParameterName();
-
-} // namespace QOAuth
-
-#endif // QOAUTH_NAMESPACE_H
diff --git a/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.cpp b/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.cpp
deleted file mode 100644
index b17c15e..0000000
--- a/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.cpp
+++ /dev/null
@@ -1,154 +0,0 @@
-/***************************************************************************
- * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.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 "ApplicationBackendTest.h"
-#include <QStringList>
-#include <QAction>
-#include <QFile>
-#include <KProtocolManager>
-#include <KActionCollection>
-#include <qtest.h>
-
-#include <tests/modeltest.h>
-#include <ApplicationBackend.h>
-#include <resources/ResourcesModel.h>
-#include <resources/ResourcesProxyModel.h>
-#include <resources/AbstractBackendUpdater.h>
-#include <Category/Category.h>
-#include <Category/CategoryModel.h>
-#include <DiscoverBackendsFactory.h>
-#include <KXmlGuiWindow>
-#include <QAptActions.h>
-
-QTEST_MAIN( ApplicationBackendTest )
-
-QString getCodename(const QString& value)
-{
- QString ret;
- QFile f(QStringLiteral("/etc/os-release"));
- if(f.open(QIODevice::ReadOnly|QIODevice::Text)){
- QRegExp rx(QStringLiteral("%1=(.+)\n").arg(value));
- while(!f.atEnd()) {
- QString line = QString::fromUtf8(f.readLine());
- if(rx.exactMatch(line)) {
- ret = rx.cap(1);
- break;
- }
- }
- }
- return ret;
-}
-
-AbstractResourcesBackend* backendByName(ResourcesModel* m, const QString& name)
-{
- QVector<AbstractResourcesBackend*> backends = m->backends();
- foreach(AbstractResourcesBackend* backend, backends) {
- if(QString::fromLatin1(backend->metaObject()->className())==name) {
- return backend;
- }
- }
- return nullptr;
-}
-
-ApplicationBackendTest::ApplicationBackendTest()
-{
- QString ratingsDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+QStringLiteral("/libdiscover/ratings.txt");
- QFile testRatings(QStringLiteral("~/.kde-unit-test/share/apps/libdiscover/ratings.txt"));
- QFile ratings(ratingsDir);
- QString codeName = getCodename(QStringLiteral("ID"));
- if(!testRatings.exists()) {
- if(ratings.exists()) {
- ratings.copy(testRatings.fileName());
- } else {
- ratings.close();
- if(codeName.toLower() == QLatin1String("ubuntu")) {
- ratingsDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+QStringLiteral("/libdiscover/rnrtestratings.txt");
- } else {
- ratingsDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+QStringLiteral("/libdiscover/popcontestratings.txt");
- }
- ratings.setFileName(ratingsDir);
- if(ratings.exists()) {
- ratings.copy(testRatings.fileName());
- }
- }
- testRatings.close();
- ratings.close();
- }
- ResourcesModel* m = new ResourcesModel(QStringLiteral("qapt-backend"), this);
- m_window = new KActionCollection(this, QStringLiteral("ApplicationBackendTest"));
- m->integrateActions(m_window);
- new ModelTest(m,m);
- m_appBackend = backendByName(m, QStringLiteral("ApplicationBackend"));
- QVERIFY(m_appBackend); //TODO: test all backends
- QSignalSpy s(m, SIGNAL(allInitialized()));
- QVERIFY(s.wait());
-}
-
-ApplicationBackendTest::~ApplicationBackendTest()
-{
- delete m_window;
-}
-
-void ApplicationBackendTest::testReload()
-{
- ResourcesModel* model = ResourcesModel::global();
- QVector<AbstractResource*> apps = m_appBackend->allResources();
- QCOMPARE(apps.count(), model->rowCount());
-
- QVector<QVariant> appNames(apps.size());
- for(int i=0; i<model->rowCount(); ++i) {
- AbstractResource* app = apps[i];
- appNames[i]=app->property("packageName");
- }
-
- bool b = QMetaObject::invokeMethod(m_appBackend, "reload");
- QVERIFY(b);
- m_appBackend->updatesCount();
- QCOMPARE(apps, m_appBackend->allResources() );
-
- QVERIFY(!apps.isEmpty());
- QCOMPARE(apps.count(), model->rowCount());
-
- for(int i=0; i<model->rowCount(); ++i) {
- AbstractResource* app = apps[i];
- QCOMPARE(appNames[i], app->property("packageName"));
-// QCOMPARE(m_model->data(m_model->index(i), ResourcesModel::NameRole).toString(), app->name());
- }
-}
-
-void ApplicationBackendTest::testCategories()
-{
- ResourcesProxyModel* proxy = new ResourcesProxyModel(this);
- const auto cats = CategoryModel::rootCategories();
- for(auto cat: cats) {
- proxy->setFiltersFromCategory(cat);
- }
-}
-
-void ApplicationBackendTest::testRefreshUpdates()
-{
- ResourcesModel* m = ResourcesModel::global();
-
- QSignalSpy spy(m, SIGNAL(fetchingChanged()));
- m_window->action(QStringLiteral("update"))->trigger();
-// QTest::kWaitForSignal(m, SLOT(fetchingChanged()));
- QVERIFY(!m->isFetching());
- qDebug() << spy.count();
-}
diff --git a/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.h b/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.h
deleted file mode 100644
index 420a395..0000000
--- a/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.h
+++ /dev/null
@@ -1,45 +0,0 @@
-/***************************************************************************
- * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.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 RESOURCESMODELTEST_H
-#define RESOURCESMODELTEST_H
-
-#include <QtTest/QtTest>
-
-class KActionCollection;
-class AbstractResourcesBackend;
-class ApplicationBackendTest : public QObject
-{
- Q_OBJECT
- public:
- ApplicationBackendTest();
- ~ApplicationBackendTest() override;
-
- private Q_SLOTS:
- void testReload();
- void testCategories();
- void testRefreshUpdates();
-
- private:
- AbstractResourcesBackend* m_appBackend;
- KActionCollection* m_window;
-};
-
-#endif
diff --git a/libdiscover/backends/ApplicationBackend/tests/CMakeLists.txt b/libdiscover/backends/ApplicationBackend/tests/CMakeLists.txt
deleted file mode 100644
index c60f87f..0000000
--- a/libdiscover/backends/ApplicationBackend/tests/CMakeLists.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-include_directories(..)
-
-set(EXTRA_LIBS QApt::Main MuonApt)
-
-install(FILES rnrtestratings.txt DESTINATION ${DATA_INSTALL_DIR}/libdiscover)
-install(FILES popcontestratings.txt DESTINATION ${DATA_INSTALL_DIR}/libdiscover)
-
-add_unit_test(applicationbackendtest ApplicationBackendTest.cpp)
-add_unit_test(reviewstest ReviewsTest.cpp)
-add_unit_test(sourcestest SourcesTest.cpp)
-
-list(APPEND EXTRA_LIBS DiscoverNotifiers MuonApplicationNotifierTestLib)
-add_unit_test(notifiertest NotifierTest.cpp)
diff --git a/libdiscover/backends/ApplicationBackend/tests/NotifierTest.cpp b/libdiscover/backends/ApplicationBackend/tests/NotifierTest.cpp
deleted file mode 100644
index e9bd02d..0000000
--- a/libdiscover/backends/ApplicationBackend/tests/NotifierTest.cpp
+++ /dev/null
@@ -1,41 +0,0 @@
-/***************************************************************************
- * Copyright © 2015 Harald Sitter <sitter@kde.org> *
- * *
- * 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 "NotifierTest.h"
-
-#include <QTest>
-
-#include <ApplicationNotifier.h>
-
-QTEST_MAIN( NotifierTest )
-
-NotifierTest::NotifierTest()
-{
-}
-
-NotifierTest::~NotifierTest() = default;
-
-void NotifierTest::testInit()
-{
- // Ensure init order is correct and we don't run into nullptr exceptions on
- // initialization.
- ApplicationNotifier app(this);
- app.metaObject()->invokeMethod(&app, "recheckSystemUpdateNeeded");
-}
diff --git a/libdiscover/backends/ApplicationBackend/tests/NotifierTest.h b/libdiscover/backends/ApplicationBackend/tests/NotifierTest.h
deleted file mode 100644
index e225a03..0000000
--- a/libdiscover/backends/ApplicationBackend/tests/NotifierTest.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/***************************************************************************
- * Copyright © 2015 Harald Sitter <sitter@kde.org> *
- * *
- * 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 NOTIFIERTEST_H
-#define NOTIFIERTEST_H
-
-#include <QtTest/QtTest>
-
-class NotifierTest : public QObject
-{
- Q_OBJECT
- public:
- NotifierTest();
- ~NotifierTest() override;
-
- private Q_SLOTS:
- void testInit();
-};
-
-#endif
diff --git a/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.cpp b/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.cpp
deleted file mode 100644
index 4d6c2cb..0000000
--- a/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.cpp
+++ /dev/null
@@ -1,90 +0,0 @@
-/***************************************************************************
- * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.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 "ReviewsTest.h"
-#include <tests/modeltest.h>
-#include <ReviewsBackend/ReviewsModel.h>
-#include <qapt/backend.h>
-#include <KProtocolManager>
-#include <qtest.h>
-#include <ReviewsBackend/AbstractReviewsBackend.h>
-#include <DiscoverBackendsFactory.h>
-#include <resources/AbstractResourcesBackend.h>
-#include <resources/ResourcesModel.h>
-#include <QSignalSpy>
-#include <KActionCollection>
-
-QTEST_MAIN( ReviewsTest )
-
-AbstractResourcesBackend* backendByName(ResourcesModel* m, const QString& name)
-{
- QVector<AbstractResourcesBackend*> backends = m->backends();
- foreach(AbstractResourcesBackend* backend, backends) {
- if(QString::fromLatin1(backend->metaObject()->className())==name) {
- return backend;
- }
- }
- return nullptr;
-}
-
-ReviewsTest::ReviewsTest(QObject* parent): QObject(parent)
-{
- ResourcesModel* m = new ResourcesModel(QStringLiteral("qapt-backend"), this);
- m_window = new KActionCollection(this, QStringLiteral("ReviewsTest"));
- m->integrateActions(m_window);
- m_appBackend = backendByName(m, QStringLiteral("ApplicationBackend"));
- QVERIFY(QSignalSpy(m, SIGNAL(allInitialized())).wait());
- m_revBackend = m_appBackend->reviewsBackend();
-}
-
-void ReviewsTest::testReviewsFetch()
-{
- if(m_revBackend->isFetching())
- QSignalSpy(m_revBackend, SIGNAL(ratingsReady())).wait();
- QVERIFY(!m_revBackend->isFetching());
-}
-
-void ReviewsTest::testReviewsModel_data()
-{
- QTest::addColumn<QString>( "application" );
- QTest::newRow( "python" ) << QStringLiteral("python");
- QTest::newRow( "gedit" ) << QStringLiteral("gedit");
-}
-
-void ReviewsTest::testReviewsModel()
-{
- QFETCH(QString, application);
- ReviewsModel* model = new ReviewsModel(this);
- new ModelTest(model, model);
-
- AbstractResource* app = m_appBackend->resourceByPackageName(application);
- QVERIFY(app);
- model->setResource(app);
- QSignalSpy(model, SIGNAL(rowsInserted(QModelIndex,int,int))).wait(2000);
-
- QModelIndex root;
- while(model->canFetchMore(root)) {
- model->fetchMore(root);
- bool arrived = QSignalSpy(model, SIGNAL(rowsInserted(QModelIndex,int,int))).wait(2000);
- QCOMPARE(arrived, model->canFetchMore(root));
- }
-
- delete model;
-}
diff --git a/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.h b/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.h
deleted file mode 100644
index 7c638e5..0000000
--- a/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/***************************************************************************
- * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.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 REVIEWSTEST_H
-#define REVIEWSTEST_H
-
-#include <QtCore/QObject>
-
-class KActionCollection;
-class AbstractResourcesBackend;
-class AbstractReviewsBackend;
-namespace QApt {
-class Backend;
-}
-
-class ReviewsTest : public QObject
-{
- Q_OBJECT
- public:
- explicit ReviewsTest(QObject* parent = nullptr);
-
- private Q_SLOTS:
- void testReviewsFetch();
-
- void testReviewsModel_data();
- void testReviewsModel();
-
- private:
- AbstractReviewsBackend* m_revBackend;
- AbstractResourcesBackend* m_appBackend;
- KActionCollection* m_window;
-
-};
-
-#endif // REVIEWSTEST_H
diff --git a/libdiscover/backends/ApplicationBackend/tests/SourcesTest.cpp b/libdiscover/backends/ApplicationBackend/tests/SourcesTest.cpp
deleted file mode 100644
index f55d049..0000000
--- a/libdiscover/backends/ApplicationBackend/tests/SourcesTest.cpp
+++ /dev/null
@@ -1,101 +0,0 @@
-/***************************************************************************
- * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.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 "SourcesTest.h"
-#include <tests/modeltest.h>
-#include <ReviewsBackend/ReviewsModel.h>
-#include <qapt/backend.h>
-#include <KProtocolManager>
-#include <KActionCollection>
-#include <qtest.h>
-#include <ReviewsBackend/AbstractReviewsBackend.h>
-#include <DiscoverBackendsFactory.h>
-#include <resources/AbstractResourcesBackend.h>
-#include <resources/ResourcesModel.h>
-#include <resources/SourcesModel.h>
-#include <resources/AbstractSourcesBackend.h>
-#include <QSignalSpy>
-
-QTEST_MAIN( SourcesTest )
-
-AbstractResourcesBackend* backendByName(ResourcesModel* m, const QString& name)
-{
- QVector<AbstractResourcesBackend*> backends = m->backends();
- foreach(AbstractResourcesBackend* backend, backends) {
- if(QString::fromLatin1(backend->metaObject()->className()) == name) {
- return backend;
- }
- }
- return nullptr;
-}
-
-SourcesTest::SourcesTest(QObject* parent): QObject(parent)
-{
- ResourcesModel* m = new ResourcesModel(QStringLiteral("qapt-backend"), this);
- m_window = new KActionCollection(this, QStringLiteral("SourcesTest"));
- m->integrateActions(m_window);
- m_appBackend = backendByName(m, QStringLiteral("ApplicationBackend"));
- QVERIFY(QSignalSpy(m, SIGNAL(allInitialized())).wait());
-
- SourcesModel* sources = SourcesModel::global();
- QVERIFY(sources->rowCount() == 1);
- QVERIFY(!backend()->name().isEmpty());
-}
-
-AbstractSourcesBackend* SourcesTest::backend() const
-{
- SourcesModel* sources = SourcesModel::global();
- QObject* l = sources->data(sources->index(0), SourcesModel::SourceBackend).value<QObject*>();
- return qobject_cast<AbstractSourcesBackend*>(l);
-}
-
-
-void SourcesTest::testSourcesFetch()
-{
- QAbstractItemModel* aptSources = backend()->sources();
-
- for(int i = 0, c=aptSources->rowCount(); i<c; ++i) {
- QVERIFY(aptSources);
- QModelIndex idx = aptSources->index(i, 0);
- QVERIFY(idx.data(Qt::DisplayRole).toString() != QString());
- }
-}
-
-void SourcesTest::testResourcesMatchSources()
-{
- QAbstractItemModel* aptSources = backend()->sources();
- QSet<QString> allSources;
- for (int i=0, c=aptSources->rowCount(); i<c; ++i) {
- QModelIndex idx = aptSources->index(i, 0);
- allSources += idx.data(Qt::DisplayRole).toString();
- }
-
- ResourcesModel* rmodel = ResourcesModel::global();
- for (int i=0, c=rmodel->rowCount(); i<c; ++i) {
- QModelIndex idx = rmodel->index(i, 0);
- QString origin = idx.data(ResourcesModel::OriginRole).toString();
- bool found = allSources.contains(origin);
- if (!found) {
- qDebug() << "couldn't find" << origin << "for" << idx.data(ResourcesModel::NameRole).toString() << "@" << i << "/" << c << "in" << allSources;
- QEXPECT_FAIL("", "I need to ask the Kubuntu guys, I don't understand", Continue);
- }
- QVERIFY(found);
- }
-}
diff --git a/libdiscover/backends/ApplicationBackend/tests/SourcesTest.h b/libdiscover/backends/ApplicationBackend/tests/SourcesTest.h
deleted file mode 100644
index 10217a0..0000000
--- a/libdiscover/backends/ApplicationBackend/tests/SourcesTest.h
+++ /dev/null
@@ -1,48 +0,0 @@
-/***************************************************************************
- * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.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 SOURCESTEST_H
-#define SOURCESTEST_H
-
-#include <QtCore/QObject>
-
-class KActionCollection;
-class AbstractSourcesBackend;
-class AbstractResourcesBackend;
-
-class SourcesTest : public QObject
-{
- Q_OBJECT
- public:
- explicit SourcesTest(QObject* parent = nullptr);
-
- private Q_SLOTS:
- void testSourcesFetch();
- void testResourcesMatchSources();
-
- private:
- AbstractSourcesBackend* backend() const;
-
- AbstractResourcesBackend* m_appBackend;
- KActionCollection* m_window;
-
-};
-
-#endif // REVIEWSTEST_H
diff --git a/libdiscover/backends/ApplicationBackend/tests/popcontestratings.txt b/libdiscover/backends/ApplicationBackend/tests/popcontestratings.txt
deleted file mode 100644
index 4266691..0000000
--- a/libdiscover/backends/ApplicationBackend/tests/popcontestratings.txt
+++ /dev/null
Binary files differ
diff --git a/libdiscover/backends/ApplicationBackend/tests/rnrtestratings.txt b/libdiscover/backends/ApplicationBackend/tests/rnrtestratings.txt
deleted file mode 100644
index edddb7a..0000000
--- a/libdiscover/backends/ApplicationBackend/tests/rnrtestratings.txt
+++ /dev/null
@@ -1,6253 +0,0 @@
-[
- {
- "ratings_total": 13,
- "ratings_average": "3.77",
- "app_name": "",
- "package_name": "gnome-hearts",
- "histogram": "[1, 1, 1, 7, 3]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "openssh-server",
- "histogram": "[0, 0, 0, 0, 6]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "2.33",
- "app_name": "",
- "package_name": "hdd-ranger",
- "histogram": "[1, 1, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "gnome-sushi-common",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "gtalk",
- "histogram": "[0, 0, 1, 0, 1]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "chemtool",
- "histogram": "[0, 2, 0, 2, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "g++-multilib",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 0,
- "ratings_average": "0.00",
- "app_name": "",
- "package_name": "comentariosweb",
- "histogram": "[0, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "2.43",
- "app_name": "",
- "package_name": "driftnet",
- "histogram": "[3, 1, 1, 1, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "myminesweeper",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "lunar",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "vagrant",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "xpenguins",
- "histogram": "[2, 0, 2, 0, 5]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "triplane",
- "histogram": "[1, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 89,
- "ratings_average": "4.81",
- "app_name": "",
- "package_name": "bastion",
- "histogram": "[2, 0, 2, 5, 80]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "gdpc",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "wordnet",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "calligra-data",
- "histogram": "[0, 0, 0, 2, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "nodejs-dev",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 10,
- "ratings_average": "3.70",
- "app_name": "",
- "package_name": "ltris",
- "histogram": "[0, 3, 1, 2, 4]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "2.40",
- "app_name": "",
- "package_name": "anonmail",
- "histogram": "[3, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "xabacus",
- "histogram": "[1, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "iasl",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "gnome-dictionary",
- "histogram": "[1, 1, 0, 1, 1]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "cont4-contl",
- "histogram": "[1, 0, 0, 2, 3]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "2.33",
- "app_name": "",
- "package_name": "flumotion",
- "histogram": "[4, 2, 0, 2, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "ipod",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "eiskaltdcpp-qt",
- "histogram": "[1, 0, 0, 1, 3]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.33",
- "app_name": "",
- "package_name": "fdupes",
- "histogram": "[0, 0, 0, 2, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "avahi-discover",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 12,
- "ratings_average": "3.25",
- "app_name": "",
- "package_name": "maps",
- "histogram": "[1, 2, 4, 3, 2]"
- },
- {
- "ratings_total": 19,
- "ratings_average": "1.16",
- "app_name": "",
- "package_name": "egoboo",
- "histogram": "[17, 1, 1, 0, 0]"
- },
- {
- "ratings_total": 16,
- "ratings_average": "2.12",
- "app_name": "",
- "package_name": "balazarbrothers",
- "histogram": "[5, 7, 2, 1, 1]"
- },
- {
- "ratings_total": 17,
- "ratings_average": "4.59",
- "app_name": "",
- "package_name": "ttf-aenigma",
- "histogram": "[0, 0, 0, 7, 10]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "page-crunch",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "3.71",
- "app_name": "",
- "package_name": "bubbros",
- "histogram": "[2, 0, 0, 1, 4]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "4.86",
- "app_name": "",
- "package_name": "latexdraw",
- "histogram": "[0, 0, 0, 1, 6]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "gutenprint-doc",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.33",
- "app_name": "",
- "package_name": "gimp-plugin-registry",
- "histogram": "[0, 0, 1, 0, 2]"
- },
- {
- "ratings_total": 32,
- "ratings_average": "3.56",
- "app_name": "",
- "package_name": "stormcloud",
- "histogram": "[4, 6, 2, 8, 12]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "nethogs",
- "histogram": "[0, 0, 0, 0, 6]"
- },
- {
- "ratings_total": 45,
- "ratings_average": "4.04",
- "app_name": "",
- "package_name": "kmymoney",
- "histogram": "[4, 4, 2, 11, 24]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "3.71",
- "app_name": "",
- "package_name": "kodos",
- "histogram": "[0, 1, 1, 4, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "qmidiroute",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 11,
- "ratings_average": "3.27",
- "app_name": "",
- "package_name": "dvd95",
- "histogram": "[2, 2, 1, 3, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "nspluginwrapper",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 65,
- "ratings_average": "4.66",
- "app_name": "",
- "package_name": "musescore",
- "histogram": "[0, 1, 2, 15, 47]"
- },
- {
- "ratings_total": 25,
- "ratings_average": "4.96",
- "app_name": "",
- "package_name": "git",
- "histogram": "[0, 0, 0, 1, 24]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "contrapuntnum1",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 13,
- "ratings_average": "4.31",
- "app_name": "",
- "package_name": "clusterssh",
- "histogram": "[0, 2, 0, 3, 8]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "2.50",
- "app_name": "",
- "package_name": "avahi-ui-utils",
- "histogram": "[1, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.33",
- "app_name": "",
- "package_name": "nvclock",
- "histogram": "[0, 1, 1, 0, 1]"
- },
- {
- "ratings_total": 21,
- "ratings_average": "4.19",
- "app_name": "",
- "package_name": "usb-imagewriter",
- "histogram": "[2, 1, 0, 6, 12]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "midisport-firmware",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "tribute",
- "histogram": "[1, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.33",
- "app_name": "",
- "package_name": "devilspie",
- "histogram": "[0, 0, 1, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "partclone",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 13,
- "ratings_average": "3.31",
- "app_name": "",
- "package_name": "prepaid-manager-applet",
- "histogram": "[4, 0, 2, 2, 5]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "4.86",
- "app_name": "",
- "package_name": "chromium-codecs-ffmpeg-extra",
- "histogram": "[0, 0, 0, 1, 6]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "4.33",
- "app_name": "",
- "package_name": "ubuntu-edu-preschool",
- "histogram": "[1, 0, 0, 0, 5]"
- },
- {
- "ratings_total": 106,
- "ratings_average": "3.35",
- "app_name": "",
- "package_name": "epiphany-browser",
- "histogram": "[18, 14, 17, 27, 30]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "gpe-contacts",
- "histogram": "[0, 1, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "nfs-kernel-server",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "debian-installer-launcher",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "joe",
- "histogram": "[0, 0, 0, 0, 4]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "2.75",
- "app_name": "",
- "package_name": "fldiff",
- "histogram": "[2, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 48,
- "ratings_average": "4.10",
- "app_name": "",
- "package_name": "gnome-commander",
- "histogram": "[4, 2, 4, 13, 25]"
- },
- {
- "ratings_total": 13,
- "ratings_average": "2.77",
- "app_name": "",
- "package_name": "gnome-font-viewer",
- "histogram": "[6, 0, 1, 3, 3]"
- },
- {
- "ratings_total": 63,
- "ratings_average": "4.54",
- "app_name": "",
- "package_name": "steelstorm-episode2",
- "histogram": "[0, 1, 4, 18, 40]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "gogglesmm",
- "histogram": "[0, 1, 0, 1, 2]"
- },
- {
- "ratings_total": 61,
- "ratings_average": "3.84",
- "app_name": "",
- "package_name": "dvdstyler",
- "histogram": "[10, 5, 2, 12, 32]"
- },
- {
- "ratings_total": 12,
- "ratings_average": "2.33",
- "app_name": "",
- "package_name": "simdock",
- "histogram": "[6, 2, 1, 0, 3]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "kde-runtime",
- "histogram": "[0, 1, 0, 1, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "jockey-common",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "qv4l2",
- "histogram": "[1, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "ecryptfs-utils",
- "histogram": "[1, 0, 1, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "ktikz",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.33",
- "app_name": "",
- "package_name": "pybik",
- "histogram": "[1, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.75",
- "app_name": "",
- "package_name": "btresourcesearch",
- "histogram": "[0, 0, 0, 1, 3]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "3.33",
- "app_name": "",
- "package_name": "freedroid",
- "histogram": "[1, 0, 2, 2, 1]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "1.11",
- "app_name": "",
- "package_name": "zhone",
- "histogram": "[8, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "pongaronga",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "jaxe",
- "histogram": "[3, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.33",
- "app_name": "",
- "package_name": "libreoffice-presentation-minimizer",
- "histogram": "[1, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "nautilus-sendto",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "pathogen",
- "histogram": "[0, 1, 0, 1, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "gvb",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "bluewho",
- "histogram": "[2, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "learnmysqlintamil-ebook",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "cowsay",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "korganizer-mobile",
- "histogram": "[0, 2, 0, 0, 2]"
- },
- {
- "ratings_total": 18,
- "ratings_average": "4.06",
- "app_name": "",
- "package_name": "sylpheed",
- "histogram": "[2, 0, 1, 7, 8]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "1.33",
- "app_name": "",
- "package_name": "wavesurfer",
- "histogram": "[2, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "fnfxd",
- "histogram": "[0, 0, 1, 0, 3]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "goattracker",
- "histogram": "[0, 1, 0, 1, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "xvattr",
- "histogram": "[3, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "madwimax",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 21,
- "ratings_average": "2.52",
- "app_name": "",
- "package_name": "gtklick",
- "histogram": "[11, 1, 1, 3, 5]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "2.60",
- "app_name": "",
- "package_name": "lyricue",
- "histogram": "[1, 2, 1, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "ndiswrapper-dkms",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "libsfml-dev",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "xmms2-plugin-flv",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "linux-shell-01",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "2.67",
- "app_name": "",
- "package_name": "cbrpager",
- "histogram": "[1, 0, 1, 1, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.75",
- "app_name": "",
- "package_name": "kde-standard",
- "histogram": "[0, 0, 0, 1, 3]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "bloboats",
- "histogram": "[2, 0, 0, 4, 3]"
- },
- {
- "ratings_total": 18,
- "ratings_average": "4.28",
- "app_name": "",
- "package_name": "ghex",
- "histogram": "[1, 0, 1, 7, 9]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "1.86",
- "app_name": "",
- "package_name": "gnomecatalog",
- "histogram": "[4, 0, 3, 0, 0]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "3.14",
- "app_name": "",
- "package_name": "glom",
- "histogram": "[1, 3, 0, 0, 3]"
- },
- {
- "ratings_total": 22,
- "ratings_average": "3.86",
- "app_name": "",
- "package_name": "fritzing",
- "histogram": "[3, 2, 2, 3, 12]"
- },
- {
- "ratings_total": 10,
- "ratings_average": "2.80",
- "app_name": "",
- "package_name": "libnb-platform12-java",
- "histogram": "[5, 0, 1, 0, 4]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "dash",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "3.83",
- "app_name": "",
- "package_name": "kphotoalbum",
- "histogram": "[1, 1, 0, 0, 4]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "recover",
- "histogram": "[3, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "pdfstudio7",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 19,
- "ratings_average": "3.84",
- "app_name": "",
- "package_name": "searchmonkey",
- "histogram": "[2, 1, 4, 3, 9]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "telepathy-butterfly",
- "histogram": "[1, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "wesnoth",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 51,
- "ratings_average": "3.35",
- "app_name": "",
- "package_name": "alarm-clock",
- "histogram": "[8, 10, 6, 10, 17]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "quark",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "2.83",
- "app_name": "",
- "package_name": "gpxviewer",
- "histogram": "[1, 2, 1, 1, 1]"
- },
- {
- "ratings_total": 11,
- "ratings_average": "3.36",
- "app_name": "",
- "package_name": "lxinput",
- "histogram": "[2, 2, 1, 2, 4]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "tuxpaint-config",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "4.57",
- "app_name": "",
- "package_name": "menulibre",
- "histogram": "[0, 1, 0, 0, 6]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "2.50",
- "app_name": "",
- "package_name": "zram-config",
- "histogram": "[1, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 73,
- "ratings_average": "4.27",
- "app_name": "",
- "package_name": "flare",
- "histogram": "[2, 5, 7, 16, 43]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "kthesaurus",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "1.50",
- "app_name": "",
- "package_name": "telegnome",
- "histogram": "[1, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "smtm",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "beast",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 29,
- "ratings_average": "2.10",
- "app_name": "",
- "package_name": "gnome-phone-manager",
- "histogram": "[16, 3, 4, 3, 3]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "miniponga",
- "histogram": "[3, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "python3-all",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 117,
- "ratings_average": "4.55",
- "app_name": "",
- "package_name": "gnome-mplayer",
- "histogram": "[4, 4, 5, 15, 89]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "xmille",
- "histogram": "[0, 1, 2, 1, 0]"
- },
- {
- "ratings_total": 10,
- "ratings_average": "4.70",
- "app_name": "",
- "package_name": "shotwell-common",
- "histogram": "[0, 0, 0, 3, 7]"
- },
- {
- "ratings_total": 69,
- "ratings_average": "3.83",
- "app_name": "",
- "package_name": "clipit",
- "histogram": "[8, 4, 7, 23, 27]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "glassfish-appserv",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 21,
- "ratings_average": "4.24",
- "app_name": "",
- "package_name": "git-cola",
- "histogram": "[0, 2, 0, 10, 9]"
- },
- {
- "ratings_total": 127,
- "ratings_average": "3.85",
- "app_name": "",
- "package_name": "ubuntuone-control-panel-gtk",
- "histogram": "[12, 14, 14, 28, 59]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "libtiff-tools",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "4.14",
- "app_name": "",
- "package_name": "parley",
- "histogram": "[0, 1, 1, 1, 4]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "cron",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 18,
- "ratings_average": "3.17",
- "app_name": "",
- "package_name": "gisomount",
- "histogram": "[7, 0, 1, 3, 7]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "tinyca",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "pandora",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "charmap.app",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "ktimer",
- "histogram": "[1, 0, 1, 0, 2]"
- },
- {
- "ratings_total": 15,
- "ratings_average": "4.93",
- "app_name": "",
- "package_name": "octave",
- "histogram": "[0, 0, 0, 1, 14]"
- },
- {
- "ratings_total": 45,
- "ratings_average": "3.40",
- "app_name": "",
- "package_name": "pq",
- "histogram": "[11, 5, 4, 5, 20]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "2.60",
- "app_name": "",
- "package_name": "tictactoe-ng",
- "histogram": "[2, 1, 0, 1, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "xjump",
- "histogram": "[0, 1, 1, 1, 0]"
- },
- {
- "ratings_total": 22,
- "ratings_average": "4.05",
- "app_name": "",
- "package_name": "clamav",
- "histogram": "[1, 1, 4, 6, 10]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "readpst",
- "histogram": "[1, 0, 1, 0, 2]"
- },
- {
- "ratings_total": 102,
- "ratings_average": "3.60",
- "app_name": "",
- "package_name": "sound-juicer",
- "histogram": "[15, 16, 11, 13, 47]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "3.71",
- "app_name": "",
- "package_name": "yahtzeesharp",
- "histogram": "[0, 1, 2, 2, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "defisheye",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "fullcircle-it-issue-vm",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 12,
- "ratings_average": "4.67",
- "app_name": "",
- "package_name": "hex-a-hop",
- "histogram": "[0, 0, 0, 4, 8]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "2.17",
- "app_name": "",
- "package_name": "helena-the-3rd",
- "histogram": "[3, 1, 1, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "gpe-othello",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "2.25",
- "app_name": "",
- "package_name": "pyracerz",
- "histogram": "[1, 2, 0, 1, 0]"
- },
- {
- "ratings_total": 35,
- "ratings_average": "3.83",
- "app_name": "",
- "package_name": "pdfchain",
- "histogram": "[3, 3, 3, 14, 12]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "lacheck",
- "histogram": "[2, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "1.22",
- "app_name": "",
- "package_name": "notification-daemon",
- "histogram": "[7, 2, 0, 0, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.67",
- "app_name": "",
- "package_name": "new-orbit",
- "histogram": "[0, 0, 0, 1, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "lirc",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "splatform",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "keepnote",
- "histogram": "[4, 0, 0, 2, 3]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "packeth",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "xcowsay",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 13,
- "ratings_average": "4.31",
- "app_name": "",
- "package_name": "nicotine",
- "histogram": "[1, 0, 0, 5, 7]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "2.71",
- "app_name": "",
- "package_name": "nagstamon",
- "histogram": "[3, 1, 0, 1, 2]"
- },
- {
- "ratings_total": 0,
- "ratings_average": "0.00",
- "app_name": "",
- "package_name": "color-by-numbers-flowers",
- "histogram": "[0, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "xipmsg",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "pod2pdf",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "barrydesktop",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "gngb",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "grabc",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "3.40",
- "app_name": "",
- "package_name": "im-switch",
- "histogram": "[0, 1, 2, 1, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "1.33",
- "app_name": "",
- "package_name": "topfeed",
- "histogram": "[2, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "xfce4-panel",
- "histogram": "[1, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "adobe-flash-properties-kde",
- "histogram": "[0, 0, 1, 0, 1]"
- },
- {
- "ratings_total": 20,
- "ratings_average": "3.25",
- "app_name": "",
- "package_name": "autokey-gtk",
- "histogram": "[4, 4, 2, 3, 7]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "alpine",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "libgtest-dev",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "1.83",
- "app_name": "",
- "package_name": "wsjt",
- "histogram": "[4, 0, 1, 1, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "asterisk",
- "histogram": "[1, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "fullcircle-issue-70",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "myspell-ru",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "2.50",
- "app_name": "",
- "package_name": "wiimap",
- "histogram": "[1, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "mp3splt",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "bash-completion",
- "histogram": "[1, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "2.75",
- "app_name": "",
- "package_name": "pdfcrack",
- "histogram": "[2, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "volumecontrol.app",
- "histogram": "[7, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "qrencode",
- "histogram": "[1, 0, 0, 2, 3]"
- },
- {
- "ratings_total": 8,
- "ratings_average": "3.75",
- "app_name": "",
- "package_name": "muine",
- "histogram": "[0, 1, 3, 1, 3]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "4.89",
- "app_name": "",
- "package_name": "kvirc",
- "histogram": "[0, 0, 0, 1, 8]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "gnome-themes-ubuntu",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 19,
- "ratings_average": "3.47",
- "app_name": "",
- "package_name": "yelp",
- "histogram": "[3, 2, 3, 5, 6]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "gargoyle-free",
- "histogram": "[2, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 12,
- "ratings_average": "4.83",
- "app_name": "",
- "package_name": "ipython",
- "histogram": "[0, 0, 0, 2, 10]"
- },
- {
- "ratings_total": 25,
- "ratings_average": "4.20",
- "app_name": "",
- "package_name": "gnome-schedule",
- "histogram": "[2, 1, 0, 9, 13]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "units",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 85,
- "ratings_average": "4.65",
- "app_name": "",
- "package_name": "xchat",
- "histogram": "[1, 0, 4, 18, 62]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "snmp",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 24,
- "ratings_average": "4.42",
- "app_name": "",
- "package_name": "electricsheep",
- "histogram": "[2, 1, 1, 1, 19]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "idle",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 102,
- "ratings_average": "2.94",
- "app_name": "",
- "package_name": "gnome-gmail",
- "histogram": "[34, 14, 10, 12, 32]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "xawtv",
- "histogram": "[0, 1, 0, 0, 1]"
- },
- {
- "ratings_total": 16,
- "ratings_average": "4.25",
- "app_name": "",
- "package_name": "konsole",
- "histogram": "[1, 0, 2, 4, 9]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "perroquet",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 20,
- "ratings_average": "3.65",
- "app_name": "",
- "package_name": "scratch",
- "histogram": "[4, 2, 0, 5, 9]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "unity-webapps-amazoncloudreader",
- "histogram": "[2, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 114,
- "ratings_average": "4.12",
- "app_name": "",
- "package_name": "pithos",
- "histogram": "[15, 6, 3, 16, 74]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "2.33",
- "app_name": "",
- "package_name": "alsa-tools-gui",
- "histogram": "[2, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "rsnapshot",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "4.86",
- "app_name": "",
- "package_name": "emacs24",
- "histogram": "[0, 0, 0, 1, 6]"
- },
- {
- "ratings_total": 19,
- "ratings_average": "2.63",
- "app_name": "",
- "package_name": "stopmotion",
- "histogram": "[7, 2, 4, 3, 3]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "2.33",
- "app_name": "",
- "package_name": "printer-driver-c2esp",
- "histogram": "[2, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 30,
- "ratings_average": "3.87",
- "app_name": "",
- "package_name": "vym",
- "histogram": "[2, 3, 3, 11, 11]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "lunar-applet",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 22,
- "ratings_average": "4.82",
- "app_name": "",
- "package_name": "verbiste-gnome",
- "histogram": "[0, 0, 1, 2, 19]"
- },
- {
- "ratings_total": 16,
- "ratings_average": "4.56",
- "app_name": "",
- "package_name": "gnome-specimen",
- "histogram": "[0, 1, 1, 2, 12]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "aft",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "nagios3",
- "histogram": "[1, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 15,
- "ratings_average": "3.20",
- "app_name": "",
- "package_name": "bzflag",
- "histogram": "[5, 2, 0, 1, 7]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "iesabel",
- "histogram": "[0, 1, 0, 1, 1]"
- },
- {
- "ratings_total": 30,
- "ratings_average": "1.33",
- "app_name": "",
- "package_name": "slimrat",
- "histogram": "[25, 2, 2, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "wine1.3-gecko",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "spacezero",
- "histogram": "[0, 1, 0, 1, 0]"
- },
- {
- "ratings_total": 14,
- "ratings_average": "4.64",
- "app_name": "",
- "package_name": "blockout2",
- "histogram": "[0, 0, 0, 5, 9]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "cmake-qt-gui",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "cherokee",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.80",
- "app_name": "",
- "package_name": "aptitude",
- "histogram": "[0, 0, 0, 1, 4]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "2.50",
- "app_name": "",
- "package_name": "freqtweak",
- "histogram": "[1, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.33",
- "app_name": "",
- "package_name": "wordpress",
- "histogram": "[0, 0, 0, 2, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "gcc-mingw32",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 17,
- "ratings_average": "4.41",
- "app_name": "",
- "package_name": "scantailor",
- "histogram": "[1, 1, 0, 3, 12]"
- },
- {
- "ratings_total": 52,
- "ratings_average": "4.21",
- "app_name": "",
- "package_name": "ogmrip",
- "histogram": "[4, 3, 4, 8, 33]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "3.20",
- "app_name": "",
- "package_name": "thinkfan",
- "histogram": "[2, 0, 0, 1, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "libavformat-extra-52",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "mapivi",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 8,
- "ratings_average": "2.38",
- "app_name": "",
- "package_name": "gnome-documents",
- "histogram": "[1, 3, 4, 0, 0]"
- },
- {
- "ratings_total": 122,
- "ratings_average": "4.37",
- "app_name": "",
- "package_name": "libreoffice",
- "histogram": "[5, 3, 8, 32, 74]"
- },
- {
- "ratings_total": 44,
- "ratings_average": "4.43",
- "app_name": "",
- "package_name": "preload",
- "histogram": "[2, 3, 1, 6, 32]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "qjackrcd",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 12,
- "ratings_average": "2.58",
- "app_name": "",
- "package_name": "nautilus-clamscan",
- "histogram": "[6, 1, 0, 2, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "ubuntu-practical-guide",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "gkdebconf",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 587,
- "ratings_average": "3.64",
- "app_name": "",
- "package_name": "rhythmbox",
- "histogram": "[95, 54, 76, 105, 257]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "apocalypze",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "toshset",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 8,
- "ratings_average": "4.88",
- "app_name": "",
- "package_name": "puzzle-moppet",
- "histogram": "[0, 0, 0, 1, 7]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "xfce4-notes-plugin",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "kmail-mobile",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 31,
- "ratings_average": "4.13",
- "app_name": "",
- "package_name": "swordandsworcery",
- "histogram": "[1, 2, 5, 7, 16]"
- },
- {
- "ratings_total": 32,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "pacman",
- "histogram": "[14, 9, 5, 3, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "openrocket",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "honeyd",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "3.83",
- "app_name": "",
- "package_name": "harpia",
- "histogram": "[1, 0, 0, 3, 2]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "3.40",
- "app_name": "",
- "package_name": "nautilus-script-collection-svn",
- "histogram": "[1, 0, 1, 2, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "ragz",
- "histogram": "[3, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "ifuse",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 0,
- "ratings_average": "0.00",
- "app_name": "",
- "package_name": "alleyoop",
- "histogram": "[0, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "gimp-resynthesizer",
- "histogram": "[0, 0, 0, 0, 9]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "lxdm",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "net-tools",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "pavumeter",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 11,
- "ratings_average": "2.55",
- "app_name": "",
- "package_name": "gnome-control-center",
- "histogram": "[4, 3, 1, 0, 3]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "jalali-calendar",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "gedit-developer-plugins",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "md5deep",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "lcrt",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.33",
- "app_name": "",
- "package_name": "scndgen",
- "histogram": "[0, 1, 0, 2, 0]"
- },
- {
- "ratings_total": 18,
- "ratings_average": "2.89",
- "app_name": "",
- "package_name": "outreel",
- "histogram": "[8, 1, 1, 1, 7]"
- },
- {
- "ratings_total": 186,
- "ratings_average": "4.08",
- "app_name": "",
- "package_name": "pinta",
- "histogram": "[13, 12, 17, 49, 95]"
- },
- {
- "ratings_total": 35,
- "ratings_average": "2.37",
- "app_name": "",
- "package_name": "ristretto",
- "histogram": "[14, 9, 2, 5, 5]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.60",
- "app_name": "",
- "package_name": "libreoffice-presenter-console",
- "histogram": "[0, 0, 0, 2, 3]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "basex",
- "histogram": "[0, 0, 0, 0, 9]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "2.50",
- "app_name": "",
- "package_name": "fairmat-academic",
- "histogram": "[1, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "angrydd",
- "histogram": "[1, 1, 1, 0, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "primer-generator",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 105,
- "ratings_average": "4.25",
- "app_name": "",
- "package_name": "guvcview",
- "histogram": "[11, 3, 3, 20, 68]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "tkabber",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "cairo-dock-plug-ins-data",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "hercules",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "whois",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "lskat",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "viewvc",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "zynjacku",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "exifprobe",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 11,
- "ratings_average": "4.82",
- "app_name": "",
- "package_name": "osmos",
- "histogram": "[0, 0, 0, 2, 9]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "comgt",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "transmission-qt",
- "histogram": "[0, 0, 1, 2, 1]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "3.89",
- "app_name": "",
- "package_name": "hasciicam",
- "histogram": "[1, 0, 1, 4, 3]"
- },
- {
- "ratings_total": 38,
- "ratings_average": "4.45",
- "app_name": "",
- "package_name": "scite",
- "histogram": "[0, 3, 4, 4, 27]"
- },
- {
- "ratings_total": 0,
- "ratings_average": "0.00",
- "app_name": "",
- "package_name": "ubuntu-user-gy-issue-201101",
- "histogram": "[0, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 10,
- "ratings_average": "2.60",
- "app_name": "",
- "package_name": "gnome-breakout",
- "histogram": "[4, 0, 3, 2, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "xgraph",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "2.75",
- "app_name": "",
- "package_name": "entangle",
- "histogram": "[2, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.60",
- "app_name": "",
- "package_name": "glmark2",
- "histogram": "[0, 0, 0, 2, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "kde-l10n-fa",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 34,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "clamz",
- "histogram": "[4, 0, 0, 1, 29]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "unity-lens-photos",
- "histogram": "[1, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "cream",
- "histogram": "[1, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 37,
- "ratings_average": "3.41",
- "app_name": "",
- "package_name": "rapidsvn",
- "histogram": "[8, 5, 3, 6, 15]"
- },
- {
- "ratings_total": 12,
- "ratings_average": "4.75",
- "app_name": "",
- "package_name": "kmahjongg",
- "histogram": "[0, 0, 1, 1, 10]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "gerstensaft",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.67",
- "app_name": "",
- "package_name": "ngspice",
- "histogram": "[0, 0, 0, 1, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "transitionsdj",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "overgod",
- "histogram": "[1, 1, 0, 1, 3]"
- },
- {
- "ratings_total": 11,
- "ratings_average": "3.36",
- "app_name": "",
- "package_name": "pyneighborhood",
- "histogram": "[4, 0, 0, 2, 5]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "dmraid",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "3.11",
- "app_name": "",
- "package_name": "a7xpg",
- "histogram": "[3, 0, 2, 1, 3]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "forceline",
- "histogram": "[0, 1, 0, 0, 1]"
- },
- {
- "ratings_total": 130,
- "ratings_average": "4.54",
- "app_name": "",
- "package_name": "guayadeque",
- "histogram": "[5, 2, 7, 20, 96]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.75",
- "app_name": "",
- "package_name": "reinteract",
- "histogram": "[1, 0, 0, 1, 2]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "worker",
- "histogram": "[2, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "xsel",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "memtester",
- "histogram": "[0, 0, 1, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "gnome-panel-bonobo",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "3.33",
- "app_name": "",
- "package_name": "qgo",
- "histogram": "[1, 0, 3, 0, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "2.50",
- "app_name": "",
- "package_name": "openerp6.1-full",
- "histogram": "[1, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 11,
- "ratings_average": "2.45",
- "app_name": "",
- "package_name": "kexi",
- "histogram": "[5, 1, 2, 1, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "proftpd-basic",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "2.50",
- "app_name": "",
- "package_name": "timemachine",
- "histogram": "[1, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.25",
- "app_name": "",
- "package_name": "rkhunter",
- "histogram": "[0, 0, 1, 1, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "bittornado-gui",
- "histogram": "[1, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "4.67",
- "app_name": "",
- "package_name": "lunar-commander",
- "histogram": "[0, 0, 1, 0, 5]"
- },
- {
- "ratings_total": 32,
- "ratings_average": "1.69",
- "app_name": "",
- "package_name": "qlix",
- "histogram": "[25, 1, 0, 3, 3]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "knotes-mobile",
- "histogram": "[2, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.67",
- "app_name": "",
- "package_name": "wkhtmltopdf",
- "histogram": "[0, 0, 0, 1, 2]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "1.60",
- "app_name": "",
- "package_name": "indicator-file-explorer",
- "histogram": "[4, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "mcabber",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "mellowmeadowslite",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "2.75",
- "app_name": "",
- "package_name": "evolution-rss",
- "histogram": "[0, 2, 1, 1, 0]"
- },
- {
- "ratings_total": 13,
- "ratings_average": "4.23",
- "app_name": "",
- "package_name": "spirits",
- "histogram": "[0, 1, 1, 5, 6]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "mpdcon.app",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "ns2",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "drush",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "1.50",
- "app_name": "",
- "package_name": "gazpacho",
- "histogram": "[1, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "otf-yozvox-yozfont",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "handbrake-gtk",
- "histogram": "[1, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "aria2",
- "histogram": "[0, 0, 0, 0, 5]"
- },
- {
- "ratings_total": 13,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "ia32-libs",
- "histogram": "[0, 0, 0, 0, 13]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "system-config-audit",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "cobra",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "usb-modeswitch",
- "histogram": "[1, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "xcompmgr",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 15,
- "ratings_average": "1.80",
- "app_name": "",
- "package_name": "pornview",
- "histogram": "[8, 5, 0, 1, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "kanyremote",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "elisa",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "sysprof",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "mango-lassi",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "context",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "kcachegrind",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 8,
- "ratings_average": "3.12",
- "app_name": "",
- "package_name": "cowbell",
- "histogram": "[2, 1, 2, 0, 3]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "vmware-view-client",
- "histogram": "[0, 0, 0, 2, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "ninepinbowling",
- "histogram": "[1, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "buzztard",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "xconq",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "sword-language-pack-el",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 39,
- "ratings_average": "4.41",
- "app_name": "",
- "package_name": "gnome-subtitles",
- "histogram": "[1, 2, 2, 9, 25]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "freeaccount",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "kayali",
- "histogram": "[1, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "sugar-sliderpuzzle-activity",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "gtkdiskfree",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 21,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "kamerka",
- "histogram": "[3, 2, 2, 6, 8]"
- },
- {
- "ratings_total": 30,
- "ratings_average": "3.63",
- "app_name": "",
- "package_name": "f-spot",
- "histogram": "[4, 5, 2, 6, 13]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "4.33",
- "app_name": "",
- "package_name": "mutt",
- "histogram": "[1, 0, 0, 0, 5]"
- },
- {
- "ratings_total": 17,
- "ratings_average": "4.12",
- "app_name": "",
- "package_name": "bino",
- "histogram": "[2, 1, 1, 2, 11]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "source-highlight",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 0,
- "ratings_average": "0.00",
- "app_name": "",
- "package_name": "zqcert",
- "histogram": "[0, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "libfaac0",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 44,
- "ratings_average": "4.66",
- "app_name": "",
- "package_name": "kid3-qt",
- "histogram": "[2, 1, 1, 2, 38]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "gjacktransport",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "gtwitter",
- "histogram": "[4, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "treeviewx",
- "histogram": "[3, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "qw-the-game",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "3.17",
- "app_name": "",
- "package_name": "njam",
- "histogram": "[1, 2, 0, 1, 2]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "yabause-qt",
- "histogram": "[1, 1, 0, 1, 1]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.80",
- "app_name": "",
- "package_name": "lynx",
- "histogram": "[0, 0, 0, 1, 4]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.67",
- "app_name": "",
- "package_name": "flamerobin",
- "histogram": "[0, 0, 0, 1, 2]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "filecrypter",
- "histogram": "[3, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 0,
- "ratings_average": "0.00",
- "app_name": "",
- "package_name": "r-cran-foreign",
- "histogram": "[0, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "abrowser",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "openarena-data",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "php5-mysqlnd",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 34,
- "ratings_average": "4.94",
- "app_name": "",
- "package_name": "vim",
- "histogram": "[0, 0, 0, 2, 32]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "mtr",
- "histogram": "[0, 0, 1, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "tilp2",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 119,
- "ratings_average": "4.33",
- "app_name": "",
- "package_name": "assaultcube",
- "histogram": "[3, 3, 13, 33, 67]"
- },
- {
- "ratings_total": 38,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "marble",
- "histogram": "[1, 2, 1, 7, 27]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "crazyblox",
- "histogram": "[0, 1, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "zekr-quran-translations-en",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "man-db",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "maitreya",
- "histogram": "[0, 0, 0, 2, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "simplyhtml",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "fonts-liberation",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "caca-utils",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "bc",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "banshee-extension-alarm",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "bochs",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "plymouth-theme-edubuntu",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "clisp",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "libgmp3-dev",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "seamonkey",
- "histogram": "[1, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "vlc-data",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "netcat",
- "histogram": "[0, 0, 0, 2, 0]"
- },
- {
- "ratings_total": 8,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "seq24",
- "histogram": "[1, 0, 0, 0, 7]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "light-themes",
- "histogram": "[0, 0, 0, 2, 0]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "2.40",
- "app_name": "",
- "package_name": "alsamixergui",
- "histogram": "[2, 1, 0, 2, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "tfdocgen",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "viewmol",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "thegravedigger-demo",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "texlive-xetex",
- "histogram": "[1, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 21,
- "ratings_average": "4.62",
- "app_name": "",
- "package_name": "minitunes",
- "histogram": "[0, 0, 1, 6, 14]"
- },
- {
- "ratings_total": 16,
- "ratings_average": "2.06",
- "app_name": "",
- "package_name": "kshutdown",
- "histogram": "[10, 1, 1, 2, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "poppler-data",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "clamav-freshclam",
- "histogram": "[1, 0, 0, 2, 0]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "python-matplotlib",
- "histogram": "[0, 0, 2, 1, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "libsdl1.2-dev",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "dirdiff",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "sixpack",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "goplay",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "xfig",
- "histogram": "[0, 0, 0, 3, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "libsdl-gfx1.2-dev",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "pygmy",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "gobby-0.5",
- "histogram": "[1, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "gtablix",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 11,
- "ratings_average": "1.64",
- "app_name": "",
- "package_name": "asoundconf-gtk",
- "histogram": "[9, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.67",
- "app_name": "",
- "package_name": "kiki-the-nano-bot",
- "histogram": "[0, 0, 0, 1, 2]"
- },
- {
- "ratings_total": 12,
- "ratings_average": "4.58",
- "app_name": "",
- "package_name": "pioneers",
- "histogram": "[0, 0, 1, 3, 8]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "ksystemlog",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 13,
- "ratings_average": "4.08",
- "app_name": "",
- "package_name": "dosemu",
- "histogram": "[2, 0, 1, 2, 8]"
- },
- {
- "ratings_total": 11,
- "ratings_average": "3.27",
- "app_name": "",
- "package_name": "gworldclock",
- "histogram": "[1, 1, 4, 4, 1]"
- },
- {
- "ratings_total": 15,
- "ratings_average": "2.40",
- "app_name": "",
- "package_name": "sacred-gold",
- "histogram": "[7, 1, 2, 4, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "kmenuedit",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "kmousetool",
- "histogram": "[1, 0, 1, 0, 1]"
- },
- {
- "ratings_total": 18,
- "ratings_average": "3.78",
- "app_name": "",
- "package_name": "freedoom",
- "histogram": "[3, 2, 0, 4, 9]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "fonts-droid",
- "histogram": "[0, 0, 0, 0, 5]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "webcamd",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "incron",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "1.67",
- "app_name": "",
- "package_name": "musickeys",
- "histogram": "[2, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.67",
- "app_name": "",
- "package_name": "fonts-hosny-thabit",
- "histogram": "[0, 0, 0, 1, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "redis-server",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "language-pack-gnome-ug-base",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "cclive",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "rinse",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "ninvaders",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "arcad3d-c1",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "python3-pip",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "ibam",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 22,
- "ratings_average": "4.14",
- "app_name": "",
- "package_name": "arandr",
- "histogram": "[2, 2, 2, 1, 15]"
- },
- {
- "ratings_total": 8,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "openlp",
- "histogram": "[0, 0, 1, 2, 5]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "2.33",
- "app_name": "",
- "package_name": "terminatorx",
- "histogram": "[2, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "graphviz",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "2.71",
- "app_name": "",
- "package_name": "framingham",
- "histogram": "[4, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 47,
- "ratings_average": "3.26",
- "app_name": "",
- "package_name": "plexmediaserver",
- "histogram": "[12, 4, 8, 6, 17]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "3.44",
- "app_name": "",
- "package_name": "bkchem",
- "histogram": "[3, 0, 0, 2, 4]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "xdm",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "python-gdata",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "pcsc-tools",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 33,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "qutim",
- "histogram": "[5, 3, 5, 5, 15]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "openssl",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 12,
- "ratings_average": "4.33",
- "app_name": "",
- "package_name": "mangler",
- "histogram": "[1, 1, 0, 1, 9]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "uair",
- "histogram": "[0, 1, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "organ-trail",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "unity-scope-dribbble",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "3.33",
- "app_name": "",
- "package_name": "mm3",
- "histogram": "[1, 1, 0, 3, 1]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "3.40",
- "app_name": "",
- "package_name": "tasks",
- "histogram": "[1, 1, 0, 1, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "greed",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "e2fsprogs",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "dyndns",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "lubuntu-restricted-addons",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "banshee-extension-magnatune",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "gdevilspie",
- "histogram": "[1, 0, 0, 1, 3]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "pentobi",
- "histogram": "[0, 0, 0, 0, 4]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.25",
- "app_name": "",
- "package_name": "terminal.app",
- "histogram": "[0, 0, 0, 3, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "dx",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "ebumeter",
- "histogram": "[1, 0, 0, 2, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "gtkballs",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "sshuttle",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "breakout",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "python-unity-singlet",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "ltp",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "ttf-kacst",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "miro-data",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "rootstock-gtk",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 69,
- "ratings_average": "3.14",
- "app_name": "",
- "package_name": "flightgear",
- "histogram": "[19, 8, 9, 10, 23]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "gvfs-backends",
- "histogram": "[0, 1, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "language-pack-zh-hans-base",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "brother-cups-wrapper-mfc9420cn",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "autodock",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "gksu",
- "histogram": "[1, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "theorur",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "streamer",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "2.14",
- "app_name": "",
- "package_name": "screenie-qt",
- "histogram": "[5, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "karts-1000",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "gpsdrive",
- "histogram": "[2, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "3.20",
- "app_name": "",
- "package_name": "gwc",
- "histogram": "[2, 0, 0, 1, 2]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "3.29",
- "app_name": "",
- "package_name": "terminal-tng",
- "histogram": "[1, 1, 2, 1, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "p3nfs",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.20",
- "app_name": "",
- "package_name": "openbox",
- "histogram": "[1, 0, 0, 0, 4]"
- },
- {
- "ratings_total": 14,
- "ratings_average": "4.79",
- "app_name": "",
- "package_name": "tellico",
- "histogram": "[0, 0, 1, 1, 12]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "tomboy-latex",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "qrfcview",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "tcpdump",
- "histogram": "[1, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "linkchecker",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "linux-image-generic-pae",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "xfce4-goodies",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "daa2iso",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "fullcircle-issue-56",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "nuapplet",
- "histogram": "[2, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "vlc-plugin-pulse",
- "histogram": "[1, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.20",
- "app_name": "",
- "package_name": "fcitx-googlepinyin",
- "histogram": "[1, 0, 0, 0, 4]"
- },
- {
- "ratings_total": 24,
- "ratings_average": "1.71",
- "app_name": "",
- "package_name": "resapplet",
- "histogram": "[16, 2, 4, 1, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "shiki-colors",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "gpppon",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "libopenscenegraph-dev",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "xfonts-100dpi",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.20",
- "app_name": "",
- "package_name": "corebreach",
- "histogram": "[0, 0, 1, 2, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "pskmail",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 24,
- "ratings_average": "4.25",
- "app_name": "",
- "package_name": "dia",
- "histogram": "[1, 0, 2, 10, 11]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "ibus-pinyin",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 197,
- "ratings_average": "3.94",
- "app_name": "",
- "package_name": "simple-scan",
- "histogram": "[25, 11, 18, 39, 104]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "libapache2-modsecurity",
- "histogram": "[1, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 12,
- "ratings_average": "2.50",
- "app_name": "",
- "package_name": "rutilt",
- "histogram": "[5, 2, 1, 2, 2]"
- },
- {
- "ratings_total": 27,
- "ratings_average": "3.11",
- "app_name": "",
- "package_name": "wifi-radar",
- "histogram": "[9, 2, 3, 3, 10]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "sonic",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "revista-espirito-livre-1",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 35,
- "ratings_average": "4.06",
- "app_name": "",
- "package_name": "gtkorphan",
- "histogram": "[5, 0, 3, 7, 20]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "coccinelle",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "gsl-bin",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "numix-gtk3-dark-theme",
- "histogram": "[0, 0, 2, 3, 2]"
- },
- {
- "ratings_total": 8,
- "ratings_average": "2.88",
- "app_name": "",
- "package_name": "wallpaperchanger",
- "histogram": "[3, 0, 2, 1, 2]"
- },
- {
- "ratings_total": 55,
- "ratings_average": "4.82",
- "app_name": "",
- "package_name": "baobab",
- "histogram": "[0, 0, 1, 8, 46]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "1.83",
- "app_name": "",
- "package_name": "opencity",
- "histogram": "[3, 2, 0, 1, 0]"
- },
- {
- "ratings_total": 74,
- "ratings_average": "3.38",
- "app_name": "",
- "package_name": "screenlets",
- "histogram": "[11, 9, 14, 21, 19]"
- },
- {
- "ratings_total": 10,
- "ratings_average": "2.90",
- "app_name": "",
- "package_name": "stallion",
- "histogram": "[3, 2, 1, 1, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "trafshow",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "kicad-common",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "2.33",
- "app_name": "",
- "package_name": "xqf",
- "histogram": "[2, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 0,
- "ratings_average": "0.00",
- "app_name": "",
- "package_name": "evtest",
- "histogram": "[0, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "openbravo-3",
- "histogram": "[0, 0, 1, 1, 4]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "python-webkit",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 48,
- "ratings_average": "3.15",
- "app_name": "",
- "package_name": "gl-117",
- "histogram": "[12, 6, 5, 13, 12]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "totem-xine",
- "histogram": "[0, 0, 1, 1, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "rainy-day",
- "histogram": "[2, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "pngcrush",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "braindump",
- "histogram": "[1, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "gzrt",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "comixcursors-righthanded",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "2.33",
- "app_name": "",
- "package_name": "yatzy",
- "histogram": "[1, 0, 2, 0, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "python-visual",
- "histogram": "[0, 0, 1, 0, 1]"
- },
- {
- "ratings_total": 92,
- "ratings_average": "4.42",
- "app_name": "",
- "package_name": "blueman",
- "histogram": "[5, 3, 7, 10, 67]"
- },
- {
- "ratings_total": 318,
- "ratings_average": "3.85",
- "app_name": "",
- "package_name": "gtk-recordmydesktop",
- "histogram": "[33, 25, 40, 79, 141]"
- },
- {
- "ratings_total": 118,
- "ratings_average": "4.69",
- "app_name": "",
- "package_name": "openttd",
- "histogram": "[2, 0, 6, 16, 94]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "fullcircle-issue-57",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.33",
- "app_name": "",
- "package_name": "hfsplus",
- "histogram": "[0, 0, 0, 2, 1]"
- },
- {
- "ratings_total": 41,
- "ratings_average": "3.93",
- "app_name": "",
- "package_name": "xcfa",
- "histogram": "[7, 1, 4, 5, 24]"
- },
- {
- "ratings_total": 129,
- "ratings_average": "2.93",
- "app_name": "",
- "package_name": "usb-creator-gtk",
- "histogram": "[52, 8, 9, 17, 43]"
- },
- {
- "ratings_total": 15,
- "ratings_average": "2.67",
- "app_name": "",
- "package_name": "zeitgeist",
- "histogram": "[6, 2, 1, 3, 3]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "3.20",
- "app_name": "",
- "package_name": "musictube",
- "histogram": "[1, 1, 1, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "ia32-libs-multiarch",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 38,
- "ratings_average": "3.18",
- "app_name": "",
- "package_name": "nvidia-current",
- "histogram": "[11, 2, 7, 5, 13]"
- },
- {
- "ratings_total": 30,
- "ratings_average": "2.87",
- "app_name": "",
- "package_name": "hotot-gtk",
- "histogram": "[12, 3, 2, 3, 10]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "octave-optim",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 0,
- "ratings_average": "0.00",
- "app_name": "",
- "package_name": "2vcard",
- "histogram": "[0, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 29,
- "ratings_average": "3.21",
- "app_name": "",
- "package_name": "gresistor",
- "histogram": "[9, 1, 4, 5, 10]"
- },
- {
- "ratings_total": 789,
- "ratings_average": "4.69",
- "app_name": "",
- "package_name": "clementine",
- "histogram": "[17, 10, 29, 89, 644]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "gem",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 91,
- "ratings_average": "4.15",
- "app_name": "",
- "package_name": "wine1.4",
- "histogram": "[6, 5, 11, 16, 53]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "libdrm2",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "gzip",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 10,
- "ratings_average": "2.70",
- "app_name": "",
- "package_name": "ktoon",
- "histogram": "[3, 3, 0, 2, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "iverilog",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "gadmin-dhcpd",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "steghide",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 10,
- "ratings_average": "2.30",
- "app_name": "",
- "package_name": "xword",
- "histogram": "[6, 0, 1, 1, 2]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "sozi",
- "histogram": "[1, 0, 0, 1, 3]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.33",
- "app_name": "",
- "package_name": "yui-compressor",
- "histogram": "[0, 0, 1, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "python-glade2",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "browser-plugin-gnash",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "2.40",
- "app_name": "",
- "package_name": "spider",
- "histogram": "[2, 1, 1, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "ttf-goudybookletter",
- "histogram": "[0, 0, 1, 0, 1]"
- },
- {
- "ratings_total": 44,
- "ratings_average": "3.84",
- "app_name": "",
- "package_name": "planner",
- "histogram": "[4, 4, 5, 13, 18]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "qmk-groundstation",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 95,
- "ratings_average": "3.65",
- "app_name": "",
- "package_name": "network-manager-gnome",
- "histogram": "[9, 10, 20, 22, 34]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "ttf-adf-baskervald",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.75",
- "app_name": "",
- "package_name": "lonesurvivor",
- "histogram": "[0, 1, 0, 2, 1]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "2.17",
- "app_name": "",
- "package_name": "unace",
- "histogram": "[3, 1, 0, 2, 0]"
- },
- {
- "ratings_total": 30,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "korganizer",
- "histogram": "[4, 3, 4, 7, 12]"
- },
- {
- "ratings_total": 0,
- "ratings_average": "0.00",
- "app_name": "",
- "package_name": "wbritish",
- "histogram": "[0, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "irpas",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 26,
- "ratings_average": "4.23",
- "app_name": "",
- "package_name": "bum",
- "histogram": "[0, 1, 4, 9, 12]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "libjnr-x86asm-java",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "gosmore",
- "histogram": "[7, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "fancontrol",
- "histogram": "[2, 1, 0, 1, 0]"
- },
- {
- "ratings_total": 11,
- "ratings_average": "3.64",
- "app_name": "",
- "package_name": "implosion",
- "histogram": "[1, 1, 4, 0, 5]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "nbtscan",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "unity-scope-clementine",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "cone",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "freeglut3",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 21,
- "ratings_average": "4.43",
- "app_name": "",
- "package_name": "mkvtoolnix-gui",
- "histogram": "[2, 0, 0, 4, 15]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "libdvdread4",
- "histogram": "[0, 0, 1, 0, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "exif",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "wmdrawer",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "ubuntuone-control-panel",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "libckyapplet1",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "kx11grab",
- "histogram": "[2, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "ht",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "openoffice.org-pdfimport",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 19,
- "ratings_average": "4.26",
- "app_name": "",
- "package_name": "uqm",
- "histogram": "[1, 1, 3, 1, 13]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "btrfs-tools",
- "histogram": "[2, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "2.60",
- "app_name": "",
- "package_name": "gwenrename",
- "histogram": "[2, 0, 2, 0, 1]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "3.40",
- "app_name": "",
- "package_name": "gnome-boxes",
- "histogram": "[0, 2, 0, 2, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "pomidor",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "3.80",
- "app_name": "",
- "package_name": "thunderbird-locale-fr",
- "histogram": "[1, 0, 1, 0, 3]"
- },
- {
- "ratings_total": 17,
- "ratings_average": "4.76",
- "app_name": "",
- "package_name": "firmware-b43-installer",
- "histogram": "[0, 1, 0, 1, 15]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "sanduhr",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "pidgin-mra-dbg",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "jigdo-file",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.67",
- "app_name": "",
- "package_name": "type-fu",
- "histogram": "[0, 0, 0, 1, 2]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "manage-launcher",
- "histogram": "[1, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "gxmms2",
- "histogram": "[2, 1, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "harden-remoteaudit",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "pandoc",
- "histogram": "[0, 0, 2, 0, 2]"
- },
- {
- "ratings_total": 12,
- "ratings_average": "2.83",
- "app_name": "",
- "package_name": "gadmin-samba",
- "histogram": "[4, 2, 1, 2, 3]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "mrpt-apps",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "x-tile",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "xfce4-taskmanager",
- "histogram": "[1, 0, 0, 1, 3]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "wipe",
- "histogram": "[1, 0, 0, 3, 3]"
- },
- {
- "ratings_total": 18,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "tuxpuck",
- "histogram": "[1, 2, 3, 8, 4]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "dnsmasq",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "1.50",
- "app_name": "",
- "package_name": "simon",
- "histogram": "[1, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 34,
- "ratings_average": "3.59",
- "app_name": "",
- "package_name": "modem-manager-gui",
- "histogram": "[4, 6, 4, 6, 14]"
- },
- {
- "ratings_total": 8,
- "ratings_average": "3.75",
- "app_name": "",
- "package_name": "fontypython",
- "histogram": "[1, 1, 1, 1, 4]"
- },
- {
- "ratings_total": 13,
- "ratings_average": "3.77",
- "app_name": "",
- "package_name": "retext",
- "histogram": "[2, 2, 0, 2, 7]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "gnome-do-plugins",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "libavcodec-extra-53",
- "histogram": "[1, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.75",
- "app_name": "",
- "package_name": "mandelbulber",
- "histogram": "[0, 0, 0, 1, 3]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "2.80",
- "app_name": "",
- "package_name": "goldencube",
- "histogram": "[1, 2, 0, 1, 1]"
- },
- {
- "ratings_total": 124,
- "ratings_average": "4.30",
- "app_name": "",
- "package_name": "alarm-clock-applet",
- "histogram": "[8, 7, 3, 28, 78]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "1.83",
- "app_name": "",
- "package_name": "cortina",
- "histogram": "[3, 2, 0, 1, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "buggyrace",
- "histogram": "[1, 1, 0, 1, 1]"
- },
- {
- "ratings_total": 151,
- "ratings_average": "4.52",
- "app_name": "",
- "package_name": "nexuiz",
- "histogram": "[4, 5, 11, 20, 111]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "tanglet",
- "histogram": "[0, 0, 2, 2, 0]"
- },
- {
- "ratings_total": 51,
- "ratings_average": "4.08",
- "app_name": "",
- "package_name": "glchess",
- "histogram": "[3, 5, 5, 10, 28]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "ubuntistas-14",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "3.43",
- "app_name": "",
- "package_name": "ktron",
- "histogram": "[2, 0, 0, 3, 2]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "fonts-linuxlibertine",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 10,
- "ratings_average": "1.40",
- "app_name": "",
- "package_name": "xsddiagram",
- "histogram": "[8, 0, 2, 0, 0]"
- },
- {
- "ratings_total": 14,
- "ratings_average": "4.79",
- "app_name": "",
- "package_name": "mediainfo-gui",
- "histogram": "[0, 0, 1, 1, 12]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.25",
- "app_name": "",
- "package_name": "hostapd",
- "histogram": "[0, 2, 0, 1, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "gmrun",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 29,
- "ratings_average": "4.86",
- "app_name": "",
- "package_name": "bpython",
- "histogram": "[0, 0, 1, 2, 26]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "mydesktopcalendar",
- "histogram": "[4, 1, 0, 2, 0]"
- },
- {
- "ratings_total": 29,
- "ratings_average": "4.52",
- "app_name": "",
- "package_name": "lingot",
- "histogram": "[1, 1, 2, 3, 22]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "libdevel-ptkdb-perl",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "jython",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "libogre-dev",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "indicator-sound",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "1.60",
- "app_name": "",
- "package_name": "dclock-java",
- "histogram": "[4, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "libsdl1.2debian-all",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "gperiodic",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "revista-espirito-livre-2",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "hotwire",
- "histogram": "[1, 0, 1, 0, 2]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "intone",
- "histogram": "[0, 1, 0, 1, 1]"
- },
- {
- "ratings_total": 12,
- "ratings_average": "3.58",
- "app_name": "",
- "package_name": "mp3diags",
- "histogram": "[3, 0, 1, 3, 5]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "wallpaper",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "impressive",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "vala-terminal",
- "histogram": "[0, 0, 1, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "libgtkglextmm-x11-1.2-dev",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "libphp-jpgraph",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "sineshaper",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "thunderbird-locale-de",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "xca",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "php5-curl",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "libreoffice-java-common",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "ttf-tuffy",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "edubuntu-fonts",
- "histogram": "[0, 0, 0, 0, 4]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "bugs-everywhere",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.20",
- "app_name": "",
- "package_name": "gnome-utils",
- "histogram": "[1, 0, 0, 0, 4]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.75",
- "app_name": "",
- "package_name": "wicd",
- "histogram": "[0, 0, 0, 1, 3]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "katoob",
- "histogram": "[0, 1, 0, 1, 1]"
- },
- {
- "ratings_total": 8,
- "ratings_average": "3.88",
- "app_name": "",
- "package_name": "scim",
- "histogram": "[1, 0, 1, 3, 3]"
- },
- {
- "ratings_total": 11,
- "ratings_average": "2.64",
- "app_name": "",
- "package_name": "ace-of-penguins",
- "histogram": "[4, 2, 1, 2, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "2.50",
- "app_name": "",
- "package_name": "festlex-oald",
- "histogram": "[1, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "urth",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "hwdata",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "tovid",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "2.80",
- "app_name": "",
- "package_name": "fillmore",
- "histogram": "[2, 0, 1, 1, 1]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "3.33",
- "app_name": "",
- "package_name": "tecnoballz",
- "histogram": "[2, 0, 3, 1, 3]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "zescrow-client",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "foff",
- "histogram": "[1, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "gimp-flegita",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "haxe",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 60,
- "ratings_average": "3.97",
- "app_name": "",
- "package_name": "xmoto",
- "histogram": "[6, 3, 6, 17, 28]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "disksearch",
- "histogram": "[0, 0, 1, 1, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "pype",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.75",
- "app_name": "",
- "package_name": "pidgin-sipe",
- "histogram": "[0, 0, 2, 1, 1]"
- },
- {
- "ratings_total": 17,
- "ratings_average": "3.94",
- "app_name": "",
- "package_name": "gespeaker",
- "histogram": "[2, 0, 1, 8, 6]"
- },
- {
- "ratings_total": 91,
- "ratings_average": "4.21",
- "app_name": "",
- "package_name": "pcsxr",
- "histogram": "[6, 4, 7, 22, 52]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "1.33",
- "app_name": "",
- "package_name": "gadmin-openvpn-client",
- "histogram": "[2, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 25,
- "ratings_average": "3.68",
- "app_name": "",
- "package_name": "qjackctl",
- "histogram": "[4, 2, 2, 7, 10]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "xyscan",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "grep",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "2.50",
- "app_name": "",
- "package_name": "gigalomania",
- "histogram": "[2, 0, 1, 0, 1]"
- },
- {
- "ratings_total": 38,
- "ratings_average": "1.50",
- "app_name": "",
- "package_name": "aweather",
- "histogram": "[27, 6, 3, 1, 1]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "2.40",
- "app_name": "",
- "package_name": "djplay",
- "histogram": "[2, 1, 1, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "libsdl-mixer1.2-dev",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 27,
- "ratings_average": "2.59",
- "app_name": "",
- "package_name": "photoprint",
- "histogram": "[12, 2, 3, 5, 5]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "1.67",
- "app_name": "",
- "package_name": "gromit",
- "histogram": "[4, 0, 2, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "gnumail.app",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 96,
- "ratings_average": "4.05",
- "app_name": "",
- "package_name": "myunity",
- "histogram": "[10, 4, 5, 29, 48]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.33",
- "app_name": "",
- "package_name": "gcc-avr",
- "histogram": "[1, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "thunar-volman",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "kdrill",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "dialog",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "archmage",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "magictouch",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 29,
- "ratings_average": "4.62",
- "app_name": "",
- "package_name": "ufraw",
- "histogram": "[0, 1, 2, 4, 22]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "xvile",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 0,
- "ratings_average": "0.00",
- "app_name": "",
- "package_name": "puppet",
- "histogram": "[0, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 29,
- "ratings_average": "3.14",
- "app_name": "",
- "package_name": "dreamchess",
- "histogram": "[6, 5, 5, 5, 8]"
- },
- {
- "ratings_total": 45,
- "ratings_average": "4.11",
- "app_name": "",
- "package_name": "basket",
- "histogram": "[0, 6, 5, 12, 22]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "psi",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "libmondrian-java",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.33",
- "app_name": "",
- "package_name": "minirok",
- "histogram": "[1, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "fonts-unfonts-core",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "allegro-demo",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "grub-pc",
- "histogram": "[1, 1, 1, 1, 1]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "2.50",
- "app_name": "",
- "package_name": "kgoldrunner",
- "histogram": "[2, 0, 1, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "kiten",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "puredata-core",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 11,
- "ratings_average": "2.09",
- "app_name": "",
- "package_name": "nebula44",
- "histogram": "[7, 0, 1, 2, 1]"
- },
- {
- "ratings_total": 13,
- "ratings_average": "1.23",
- "app_name": "",
- "package_name": "nvclock-gtk",
- "histogram": "[12, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "kuiviewer",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "costume-quest-meta",
- "histogram": "[0, 0, 1, 1, 1]"
- },
- {
- "ratings_total": 8,
- "ratings_average": "4.38",
- "app_name": "",
- "package_name": "icedtea-7-plugin",
- "histogram": "[0, 1, 1, 0, 6]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "3.29",
- "app_name": "",
- "package_name": "gwibber-service-sina",
- "histogram": "[2, 0, 1, 2, 2]"
- },
- {
- "ratings_total": 20,
- "ratings_average": "3.95",
- "app_name": "",
- "package_name": "ardentryst",
- "histogram": "[1, 0, 5, 7, 7]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.67",
- "app_name": "",
- "package_name": "cpufrequtils",
- "histogram": "[0, 0, 0, 1, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "openuniverse-common",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "livemix",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "pyromaths",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 12,
- "ratings_average": "3.92",
- "app_name": "",
- "package_name": "war-in-a-box-paper-tanks",
- "histogram": "[2, 1, 0, 2, 7]"
- },
- {
- "ratings_total": 63,
- "ratings_average": "2.43",
- "app_name": "",
- "package_name": "nautilus",
- "histogram": "[24, 11, 12, 9, 7]"
- },
- {
- "ratings_total": 36,
- "ratings_average": "3.19",
- "app_name": "",
- "package_name": "tuxcmd",
- "histogram": "[12, 2, 2, 7, 13]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.20",
- "app_name": "",
- "package_name": "ancientrome2",
- "histogram": "[0, 0, 1, 2, 2]"
- },
- {
- "ratings_total": 17,
- "ratings_average": "2.71",
- "app_name": "",
- "package_name": "freeguide",
- "histogram": "[7, 3, 0, 2, 5]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "drfinance",
- "histogram": "[2, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "2.50",
- "app_name": "",
- "package_name": "kplato",
- "histogram": "[1, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "jigl",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "biblatex",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "dbview",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "account-plugin-sina",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "clive",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "woof",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "2.67",
- "app_name": "",
- "package_name": "cloudprint",
- "histogram": "[1, 0, 1, 1, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.75",
- "app_name": "",
- "package_name": "globs",
- "histogram": "[0, 1, 1, 0, 2]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "dynamitejack",
- "histogram": "[0, 0, 0, 2, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "printer-driver-pnm2ppa",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "libtinyxml-dev",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "fullcircle-issue-71",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "3.33",
- "app_name": "",
- "package_name": "ddd",
- "histogram": "[1, 1, 1, 1, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "jp2a",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "1.29",
- "app_name": "",
- "package_name": "nepomuk-core-data",
- "histogram": "[6, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "backuppc",
- "histogram": "[0, 0, 1, 0, 1]"
- },
- {
- "ratings_total": 8,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "owncloud",
- "histogram": "[0, 0, 1, 2, 5]"
- },
- {
- "ratings_total": 29,
- "ratings_average": "4.69",
- "app_name": "",
- "package_name": "gtkhash",
- "histogram": "[0, 0, 1, 7, 21]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "xresprobe",
- "histogram": "[0, 2, 0, 0, 0]"
- },
- {
- "ratings_total": 18,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "icedtea-netx-common",
- "histogram": "[4, 0, 5, 1, 8]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "kamera",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "pomodoro-applet",
- "histogram": "[1, 0, 1, 0, 1]"
- },
- {
- "ratings_total": 8,
- "ratings_average": "4.38",
- "app_name": "",
- "package_name": "nano",
- "histogram": "[1, 0, 0, 1, 6]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "xfonts-base",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 12,
- "ratings_average": "4.67",
- "app_name": "",
- "package_name": "qtqr",
- "histogram": "[0, 0, 0, 4, 8]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "4.75",
- "app_name": "",
- "package_name": "flex",
- "histogram": "[0, 0, 0, 1, 3]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "1.33",
- "app_name": "",
- "package_name": "xsol",
- "histogram": "[2, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 19,
- "ratings_average": "4.47",
- "app_name": "",
- "package_name": "qalculate-gtk",
- "histogram": "[1, 1, 0, 3, 14]"
- },
- {
- "ratings_total": 433,
- "ratings_average": "4.67",
- "app_name": "",
- "package_name": "audacious",
- "histogram": "[11, 4, 13, 60, 345]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "libqtgui4",
- "histogram": "[0, 0, 1, 1, 0]"
- },
- {
- "ratings_total": 75,
- "ratings_average": "4.36",
- "app_name": "",
- "package_name": "fogger",
- "histogram": "[0, 2, 7, 28, 38]"
- },
- {
- "ratings_total": 8,
- "ratings_average": "3.25",
- "app_name": "",
- "package_name": "aseprite",
- "histogram": "[2, 0, 2, 2, 2]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "3.89",
- "app_name": "",
- "package_name": "gambas3-ide",
- "histogram": "[2, 0, 1, 0, 6]"
- },
- {
- "ratings_total": 10,
- "ratings_average": "4.60",
- "app_name": "",
- "package_name": "fmit",
- "histogram": "[0, 0, 1, 2, 7]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "rig",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "2.50",
- "app_name": "",
- "package_name": "pgdesigner",
- "histogram": "[1, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 97,
- "ratings_average": "4.31",
- "app_name": "",
- "package_name": "openjdk-7-jre",
- "histogram": "[9, 2, 6, 13, 67]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "4.78",
- "app_name": "",
- "package_name": "likewise-open-gui",
- "histogram": "[0, 0, 0, 2, 7]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "fsarchiver",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "indicator-power",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "python3-examples",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "2.75",
- "app_name": "",
- "package_name": "banshee-extension-clutterflow",
- "histogram": "[1, 0, 2, 1, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.67",
- "app_name": "",
- "package_name": "fcrackzip",
- "histogram": "[0, 0, 1, 2, 0]"
- },
- {
- "ratings_total": 37,
- "ratings_average": "4.16",
- "app_name": "",
- "package_name": "ripperx",
- "histogram": "[2, 2, 3, 11, 19]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "libhdf5-serial-1.8.4",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 22,
- "ratings_average": "4.23",
- "app_name": "",
- "package_name": "ark",
- "histogram": "[1, 2, 2, 3, 14]"
- },
- {
- "ratings_total": 11,
- "ratings_average": "4.36",
- "app_name": "",
- "package_name": "biogenesis",
- "histogram": "[0, 1, 1, 2, 7]"
- },
- {
- "ratings_total": 40,
- "ratings_average": "1.98",
- "app_name": "",
- "package_name": "linthesia",
- "histogram": "[26, 3, 1, 6, 4]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "ttf-arabeyes",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "default-jre",
- "histogram": "[0, 1, 0, 0, 2]"
- },
- {
- "ratings_total": 62,
- "ratings_average": "3.27",
- "app_name": "",
- "package_name": "cairo-clock",
- "histogram": "[13, 8, 7, 17, 17]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "viridian",
- "histogram": "[0, 0, 0, 0, 4]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "jemboss",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "pyragua",
- "histogram": "[1, 0, 1, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "libmojolicious-perl",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "lxf161",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "3.57",
- "app_name": "",
- "package_name": "memory-owl",
- "histogram": "[1, 0, 2, 2, 2]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "sqlite",
- "histogram": "[0, 0, 0, 0, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "libreoffice-evolution",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "yersinia",
- "histogram": "[0, 0, 1, 0, 0]"
- },
- {
- "ratings_total": 29,
- "ratings_average": "4.41",
- "app_name": "",
- "package_name": "gambas2-ide",
- "histogram": "[3, 0, 0, 5, 21]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "mosh",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 10,
- "ratings_average": "2.70",
- "app_name": "",
- "package_name": "moserial",
- "histogram": "[2, 4, 1, 1, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "ttf-arphic-gbsn00lp",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "tuxinfo",
- "histogram": "[1, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "2.50",
- "app_name": "",
- "package_name": "rovclock",
- "histogram": "[1, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "2.78",
- "app_name": "",
- "package_name": "kdocker",
- "histogram": "[5, 0, 0, 0, 4]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "myspell-st",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 16,
- "ratings_average": "4.12",
- "app_name": "",
- "package_name": "solfege",
- "histogram": "[2, 0, 0, 6, 8]"
- },
- {
- "ratings_total": 14,
- "ratings_average": "2.79",
- "app_name": "",
- "package_name": "rapid-photo-downloader",
- "histogram": "[6, 2, 0, 1, 5]"
- },
- {
- "ratings_total": 14,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "glob2",
- "histogram": "[1, 0, 0, 3, 10]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "umlet",
- "histogram": "[0, 0, 0, 0, 4]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "2.80",
- "app_name": "",
- "package_name": "kabikaboo",
- "histogram": "[2, 0, 1, 1, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "krecipes",
- "histogram": "[0, 1, 0, 0, 2]"
- },
- {
- "ratings_total": 41,
- "ratings_average": "4.83",
- "app_name": "",
- "package_name": "classicmenu-indicator",
- "histogram": "[1, 0, 0, 3, 37]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "network-manager-openconnect",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 12,
- "ratings_average": "4.08",
- "app_name": "",
- "package_name": "mousepad",
- "histogram": "[0, 2, 0, 5, 5]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "jclic",
- "histogram": "[1, 0, 2, 0, 1]"
- },
- {
- "ratings_total": 26,
- "ratings_average": "4.23",
- "app_name": "",
- "package_name": "unison-gtk",
- "histogram": "[1, 2, 2, 6, 15]"
- },
- {
- "ratings_total": 22,
- "ratings_average": "4.23",
- "app_name": "",
- "package_name": "gpick",
- "histogram": "[0, 2, 3, 5, 12]"
- },
- {
- "ratings_total": 0,
- "ratings_average": "0.00",
- "app_name": "",
- "package_name": "virtualbox-ose",
- "histogram": "[0, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "ibus-table-cangjie-big",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "ibus-array",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "libnet-telnet-cisco-perl",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 77,
- "ratings_average": "4.34",
- "app_name": "",
- "package_name": "wine1.3",
- "histogram": "[2, 2, 10, 17, 46]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "2.33",
- "app_name": "",
- "package_name": "invaders-3d",
- "histogram": "[2, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "vnc4server",
- "histogram": "[0, 0, 0, 1, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.50",
- "app_name": "",
- "package_name": "bibledit",
- "histogram": "[0, 0, 1, 1, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "tpb",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 8,
- "ratings_average": "1.12",
- "app_name": "",
- "package_name": "twitux",
- "histogram": "[7, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "unity-place-files",
- "histogram": "[1, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 17,
- "ratings_average": "4.82",
- "app_name": "",
- "package_name": "kalzium",
- "histogram": "[0, 0, 0, 3, 14]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "python-django-doc",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "clang",
- "histogram": "[0, 0, 0, 0, 5]"
- },
- {
- "ratings_total": 48,
- "ratings_average": "1.33",
- "app_name": "",
- "package_name": "tencentqq",
- "histogram": "[42, 1, 2, 1, 2]"
- },
- {
- "ratings_total": 187,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "gedit",
- "histogram": "[8, 4, 11, 27, 137]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.20",
- "app_name": "",
- "package_name": "gpscorrelate-gui",
- "histogram": "[0, 1, 0, 1, 3]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.80",
- "app_name": "",
- "package_name": "ppa-purge",
- "histogram": "[0, 0, 0, 1, 4]"
- },
- {
- "ratings_total": 11,
- "ratings_average": "1.73",
- "app_name": "",
- "package_name": "conglomerate",
- "histogram": "[6, 2, 3, 0, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "2.67",
- "app_name": "",
- "package_name": "yojigsaw",
- "histogram": "[1, 1, 0, 0, 1]"
- },
- {
- "ratings_total": 6,
- "ratings_average": "4.33",
- "app_name": "",
- "package_name": "nvidia-glx-185",
- "histogram": "[0, 1, 0, 1, 4]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "sfst",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 4,
- "ratings_average": "1.25",
- "app_name": "",
- "package_name": "synce-trayicon",
- "histogram": "[3, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "4.80",
- "app_name": "",
- "package_name": "edge",
- "histogram": "[0, 0, 0, 1, 4]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "tagainijisho",
- "histogram": "[0, 0, 0, 0, 9]"
- },
- {
- "ratings_total": 99,
- "ratings_average": "4.26",
- "app_name": "",
- "package_name": "file-roller",
- "histogram": "[4, 4, 9, 27, 55]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "picmi",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "keytouch",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "3.00",
- "app_name": "",
- "package_name": "ttf-indic-fonts-core",
- "histogram": "[1, 0, 1, 0, 1]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "4.71",
- "app_name": "",
- "package_name": "idle3",
- "histogram": "[0, 0, 1, 0, 6]"
- },
- {
- "ratings_total": 5,
- "ratings_average": "3.20",
- "app_name": "",
- "package_name": "alsaplayer-common",
- "histogram": "[1, 0, 2, 1, 1]"
- },
- {
- "ratings_total": 9,
- "ratings_average": "4.56",
- "app_name": "",
- "package_name": "bibus",
- "histogram": "[0, 0, 1, 2, 6]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "vncsnapshot",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 24,
- "ratings_average": "3.46",
- "app_name": "",
- "package_name": "ripoff",
- "histogram": "[2, 6, 4, 3, 9]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "julius-voxforge",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "linux-firmware-nonfree",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 14,
- "ratings_average": "4.43",
- "app_name": "",
- "package_name": "kalgebra",
- "histogram": "[0, 0, 3, 2, 9]"
- },
- {
- "ratings_total": 71,
- "ratings_average": "3.73",
- "app_name": "",
- "package_name": "minetest",
- "histogram": "[6, 5, 17, 17, 26]"
- },
- {
- "ratings_total": 87,
- "ratings_average": "2.82",
- "app_name": "",
- "package_name": "xsensors",
- "histogram": "[24, 13, 20, 15, 15]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "3.71",
- "app_name": "",
- "package_name": "cdcat",
- "histogram": "[1, 0, 0, 5, 1]"
- },
- {
- "ratings_total": 22,
- "ratings_average": "4.09",
- "app_name": "",
- "package_name": "gnome-nettool",
- "histogram": "[1, 1, 3, 7, 10]"
- },
- {
- "ratings_total": 22,
- "ratings_average": "4.50",
- "app_name": "",
- "package_name": "jabref",
- "histogram": "[0, 0, 1, 9, 12]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "revista-espirito-livre-5",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "kic",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 7,
- "ratings_average": "3.57",
- "app_name": "",
- "package_name": "k3d",
- "histogram": "[2, 0, 0, 2, 3]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "1.00",
- "app_name": "",
- "package_name": "awstats",
- "histogram": "[1, 0, 0, 0, 0]"
- },
- {
- "ratings_total": 28,
- "ratings_average": "4.75",
- "app_name": "",
- "package_name": "sqliteman",
- "histogram": "[0, 0, 0, 7, 21]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "travel-trial",
- "histogram": "[0, 1, 0, 0, 0]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "pidgin-facebookchat",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 35,
- "ratings_average": "4.69",
- "app_name": "",
- "package_name": "wxmaxima",
- "histogram": "[1, 0, 1, 5, 28]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "fourorless",
- "histogram": "[0, 0, 0, 0, 1]"
- },
- {
- "ratings_total": 1,
- "ratings_average": "4.00",
- "app_name": "",
- "package_name": "adduser",
- "histogram": "[0, 0, 0, 1, 0]"
- },
- {
- "ratings_total": 3,
- "ratings_average": "2.67",
- "app_name": "",
- "package_name": "xpn",
- "histogram": "[1, 1, 0, 0, 1]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "5.00",
- "app_name": "",
- "package_name": "netgen",
- "histogram": "[0, 0, 0, 0, 2]"
- },
- {
- "ratings_total": 2,
- "ratings_average": "2.00",
- "app_name": "",
- "package_name": "holdingnuts",
- "histogram": "[0, 2, 0, 0, 0]"
- },
- {
- "ratings_total": 8,
- "ratings_average": "4.25",
- "app_name": "",
- "package_name": "parsec47",
- "histogram": "[0, 0, 1, 4, 3]"
- },
- {
- "ratings_total": 15,
- "ratings_average": "4.53",
- "app_name": "",
- "package_name": "blobwars",
- "histogram": "[1, 0, 0, 3, 11]"
- },
- {
- "ratings_total": 49,
- "ratings_average": "3.53",
- "app_name": "",
- "package_name": "visualboyadvance-gtk",
- "histogram": "[9, 5, 9, 3, 23]"
- }
-] \ No newline at end of file
diff --git a/libdiscover/backends/ApplicationBackend/ubuntu_sso_dbus_interface.xml b/libdiscover/backends/ApplicationBackend/ubuntu_sso_dbus_interface.xml
deleted file mode 100644
index cb8dd3c..0000000
--- a/libdiscover/backends/ApplicationBackend/ubuntu_sso_dbus_interface.xml
+++ /dev/null
@@ -1,73 +0,0 @@
-<!DOCTYPE node PUBLIC "-//freedesktop//DTD D-BUS Object Introspection 1.0//EN"
-"http://www.freedesktop.org/standards/dbus/1.0/introspect.dtd">
-<node name="/com/ubuntu/sso/credentials">
- <interface name="com.ubuntu.sso.CredentialsManagement">
- <signal name="CredentialsError">
- <arg type="s" name="app_name" />
- <arg type="a{ss}" name="error_dict" />
- <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="QMap&lt;QString,QString&gt;"/>
- </signal>
- <signal name="CredentialsStored">
- <arg type="s" name="app_name" />
- </signal>
- <signal name="CredentialsNotFound">
- <arg type="s" name="app_name" />
- </signal>
- <signal name="AuthorizationDenied">
- <arg type="s" name="app_name" />
- </signal>
-<!--
- NOTE: this is commented out because the method is called register and it's a c++ reserved keyword and it doesn't work
- <method name="register">
- <arg direction="in" type="s" name="app_name" />
- <arg direction="in" type="a{ss}" name="args" />
- <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="QMap&lt;QString,QString&gt;"/>
- </method>-->
- <method name="find_credentials_sync">
- <arg direction="in" type="s" name="app_name" />
- <arg direction="in" type="a{ss}" name="args" />
- <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="QMap&lt;QString,QString&gt;"/>
- <arg direction="out" type="a{ss}" />
- <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QMap&lt;QString,QString&gt;"/>
- </method>
- <method name="find_credentials">
- <arg direction="in" type="s" name="app_name" />
- <arg direction="in" type="a{ss}" name="args" />
- <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="QMap&lt;QString,QString&gt;"/>
- </method>
- <signal name="CredentialsCleared">
- <arg type="s" name="app_name" />
- </signal>
- <method name="clear_credentials">
- <arg direction="in" type="s" name="app_name" />
- <arg direction="in" type="a{ss}" name="args" />
- <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="QMap&lt;QString,QString&gt;"/>
- </method>
- <signal name="CredentialsFound">
- <arg type="s" name="app_name" />
- <arg type="a{ss}" name="credentials" />
- <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="QMap&lt;QString,QString&gt;"/>
- </signal>
- <method name="login">
- <arg direction="in" type="s" name="app_name" />
- <arg direction="in" type="a{ss}" name="args" />
- <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="QMap&lt;QString,QString&gt;"/>
- </method>
- <method name="login_email_password">
- <arg direction="in" type="s" name="app_name" />
- <arg direction="in" type="a{ss}" name="args" />
- <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="QMap&lt;QString,QString&gt;"/>
- </method>
- <method name="store_credentials">
- <arg direction="in" type="s" name="app_name" />
- <arg direction="in" type="a{ss}" name="args" />
- <annotation name="com.trolltech.QtDBus.QtTypeName.In1" value="QMap&lt;QString,QString&gt;"/>
- </method>
- </interface>
- <interface name="org.freedesktop.DBus.Introspectable">
- <method name="Introspect">
- <arg direction="out" type="s" />
- </method>
- </interface>
-</node>
-
diff --git a/libdiscover/backends/CMakeLists.txt b/libdiscover/backends/CMakeLists.txt
index bb38eb2..0e909a4 100644
--- a/libdiscover/backends/CMakeLists.txt
+++ b/libdiscover/backends/CMakeLists.txt
@@ -12,14 +12,6 @@ if(KF5Attica_FOUND AND KF5NewStuff_FOUND)
add_subdirectory(KNSBackend)
endif()
-if(QApt_FOUND)
- add_subdirectory(ApplicationBackend)
-endif()
-
-if(BODEGA_FOUND)
- add_subdirectory(BodegaBackend)
-endif()
-
if(packagekitqt5_FOUND AND AppstreamQt_FOUND)
add_subdirectory(PackageKitBackend)
endif()