summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleix Pol <[email protected]>2016-10-26 01:37:19 +0200
committerAleix Pol <[email protected]>2016-10-26 01:37:19 +0200
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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]>
-#
-# Author: Jonathan Thomas <[email protected]>
-#
-# 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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[[email protected]]=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[[email protected]]=Муонова позадина за извештавање о програмима
-Comment[[email protected]]=Muonova pozadina za izveštavanje o programima
-Comment[[email protected]]=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[[email protected]]=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[[email protected]]=Доступна надоградња
-Name[[email protected]]=Dostupna nadogradnja
-Name[[email protected]]=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[[email protected]]=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[[email protected]]=Доступно је ново издање Кубунтуа
-Comment[[email protected]]=Dostupno je novo izdanje Kubuntua
-Comment[[email protected]]=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[[email protected]]=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[[email protected]]=Инсталирајте и прегледајте програме из АПТ‑а
-Comment[[email protected]]=Instalirajte i pregledajte programe iz APT‑a
-Comment[[email protected]]=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[[email protected]]=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[[email protected]]=Позадина за програме
-Name[[email protected]]=Pozadina za programe
-Name[[email protected]]=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[[email protected]]=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[[email protected]]=Подршка за АПТ
-GenericName[[email protected]]=Podrška za APT
-GenericName[[email protected]]=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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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 <[email protected]> *
- * *
- * 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()