diff options
| author | Aleix Pol <aleixpol@kde.org> | 2016-10-25 23:37:19 (GMT) |
|---|---|---|
| committer | Aleix Pol <aleixpol@kde.org> | 2016-10-25 23:37:19 (GMT) |
| commit | e42560d53d8ebe3d5fa910129ee07ebc6483db64 (patch) | |
| tree | b1dafcd1ab5773afce874c194f38da4ac4cccd2f | |
| parent | 7fca278dae7696e1975cc61a03e4a99240fcd0a8 (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
53 files changed, 0 insertions, 14212 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index c367c76..af87809 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,13 +21,6 @@ find_package(KF5 5.24 REQUIRED CoreAddons Config Crash DBusAddons I18n Archive D find_package(KF5Kirigami 1.1) find_package(packagekitqt5) -if (NOT packagekitqt5_FOUND) - find_package(QApt 3.0.0) - if(QApt_FOUND) - find_package(DebconfKDE 1.0.0 REQUIRED) - find_package(KF5 REQUIRED IconThemes Notifications KIO) - endif() -endif() find_package(AppstreamQt 0.10) find_package(KF5Attica 5.23) find_package(KF5NewStuff 5.23) diff --git a/libdiscover/backends/ApplicationBackend/Application.cpp b/libdiscover/backends/ApplicationBackend/Application.cpp deleted file mode 100644 index ae1d95e..0000000 --- a/libdiscover/backends/ApplicationBackend/Application.cpp +++ /dev/null @@ -1,546 +0,0 @@ -/*************************************************************************** - * Copyright © 2010-2011 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "Application.h" - -// Qt includes -#include <QFile> -#include <QJsonDocument> -#include <QStandardPaths> -#include <QStringList> -#include <QThread> -#include <QIcon> -#include <QVector> - -// KDE includes -#include <KIconLoader> -#include <KService> -#include <KServiceGroup> -#include <KToolInvocation> -#include <KLocalizedString> -#include <KIO/Job> -#include <KConfigGroup> -#include <KFormat> - -// QApt includes -#include <QApt/Backend> -#include <QApt/Config> -#include <QApt/Changelog> -#include <qapt/qaptversion.h> - -#include <MuonDataSources.h> - -#include "ApplicationBackend.h" -#include "resources/PackageState.h" - -Application::Application(const Appstream::Component &component, QApt::Backend* backend) - : AbstractResource(nullptr) - , m_data(component) - , m_package(nullptr) - , m_isValid(true) - , m_isTechnical(component.kind() != Appstream::Component::KindDesktop) - , m_isExtrasApp(false) - , m_sourceHasScreenshot(true) -{ - static QByteArray currentDesktop = qgetenv("XDG_CURRENT_DESKTOP"); - - Q_ASSERT(component.packageNames().count() == 1); - if (!component.packageNames().isEmpty()) - m_packageName = component.packageNames().at(0); - - m_package = backend->package(packageName()); - m_isValid = bool(m_package); -} - -Application::Application(QApt::Package* package, QApt::Backend* backend) - : AbstractResource(nullptr) - , m_package(package) - , m_packageName(m_package->name()) - , m_isValid(true) - , m_isTechnical(true) - , m_isExtrasApp(false) -{ - QString arch = m_package->architecture(); - if (arch != backend->nativeArchitecture() && arch != QLatin1String("all")) { - m_packageName.append(QLatin1Char(':')); - m_packageName.append(arch); - } - - if (m_package->origin() == QLatin1String("LP-PPA-app-review-board")) { - if (!m_package->controlField(QLatin1String("Appname")).isEmpty()) { - m_isExtrasApp = true; - m_isTechnical = false; - } - } -} - -QString Application::name() -{ - QString name = m_data.isValid() ? m_data.name() : QString(); - if (name.isEmpty() && package()) { - // extras.ubuntu.com packages can have this - if (m_isExtrasApp) - name = m_package->controlField(QLatin1String("Appname")); - else - name = m_package->name(); - } - - if (package() && m_package->isForeignArch()) - name = i18n("%1 (%2)", name, m_package->architecture()); - - return name; -} - -QString Application::comment() -{ - QString comment = m_data.isValid() ? m_data.summary() : QString(); - if (comment.isEmpty()) { - return package()->shortDescription(); - } - - return i18n(comment.toUtf8().constData()); -} - -QString Application::packageName() const -{ - return m_packageName; -} - -QApt::Package *Application::package() -{ - if (!m_package && parent()) { - m_package = backend()->package(packageName()); - Q_EMIT stateChanged(); - } - - // Packages removed from archive will remain in app-install-data until the - // next refresh, so we can have valid .desktops with no package - if (!m_package) { - m_isValid = false; - } - - return m_package; -} - -QVariant Application::icon() const -{ - QIcon ret; - - const auto icons = m_appdata.iconUrls(); - if (icons.isEmpty()) - return m_appdata.name(); - else { - for (auto it = icons.constBegin(), itEnd = icons.constEnd(); it!=itEnd; ++it) { - if (it->isLocalFile()) - ret.addFile(it->toLocalFile(), it.key()); - } - } - return ret; -} - -QStringList Application::findProvides(Appstream::Provides::Kind kind) const -{ - QStringList ret; - Q_FOREACH (Appstream::Provides p, m_data.provides()) - if (p.kind() == kind) - ret += p.value(); - return ret; -} - -QStringList Application::mimetypes() const -{ - return findProvides(Appstream::Provides::KindMimetype); -} - -QStringList Application::categories() -{ - QStringList categories = m_data.isValid() ? m_data.categories() : QStringList(); - - if (categories.isEmpty()) { - // extras.ubuntu.com packages can have this field - if (m_isExtrasApp) - categories = package()->controlField(QLatin1String("Category")).split(QLatin1Char(';')); - } - return categories; -} - -QUrl Application::thumbnailUrl() -{ - QUrl url(package()->controlField(QLatin1String("Thumbnail-Url"))); - if(m_sourceHasScreenshot) { - url = QUrl(MuonDataSources::screenshotsSource().toString() + QStringLiteral("/thumbnail/") + packageName()); - } - return url; -} - -QUrl Application::screenshotUrl() -{ - QUrl url(package()->controlField(QLatin1String("Screenshot-Url"))); - if(m_sourceHasScreenshot) { - url = QUrl(MuonDataSources::screenshotsSource().toString() + QStringLiteral("/screenshot/") + packageName()); - } - return url; -} - -QString Application::license() -{ - QString component = package()->component(); - if (component == QLatin1String("main") || component == QLatin1String("universe")) { - return i18nc("@info license", "Open Source"); - } else if (component == QLatin1String("restricted")) { - return i18nc("@info license", "Proprietary"); - } else { - return i18nc("@info license", "Unknown"); - } -} - -QApt::PackageList Application::addons() -{ - QApt::PackageList addons; - - QApt::Package *pkg = package(); - if (!pkg) { - return addons; - } - - QStringList tempList; - // Only add recommends or suggests to the list if they aren't already going to be - // installed - if (!backend()->config()->readEntry(QStringLiteral("APT::Install-Recommends"), true)) { - tempList << m_package->recommendsList(); - } - if (!backend()->config()->readEntry(QStringLiteral("APT::Install-Suggests"), false)) { - tempList << m_package->suggestsList(); - } - tempList << m_package->enhancedByList(); - - QStringList languagePackages; - QFile l10nFilterFile(QStringLiteral("/usr/share/language-selector/data/pkg_depends")); - - if (l10nFilterFile.open(QFile::ReadOnly)) { - QString contents = QString::fromLatin1(l10nFilterFile.readAll()); - - foreach (const QString &line, contents.split(QLatin1Char('\n'))) { - if (line.startsWith(QLatin1Char('#'))) { - continue; - } - languagePackages << line.split(QLatin1Char(':')).last(); - } - - languagePackages.removeAll(QString()); - } - - foreach (const QString &addon, tempList) { - bool shouldShow = true; - QApt::Package *package = backend()->package(addon); - - if (!package || QString(package->section()).contains(QLatin1String("lib")) || addons.contains(package)) { - continue; - } - - foreach (const QString &langpack, languagePackages) { - if (addon.contains(langpack)) { - shouldShow = false; - break; - } - } - - if (shouldShow) { - addons << package; - } - } - - return addons; -} - -QList<PackageState> Application::addonsInformation() -{ - QList<PackageState> ret; - QApt::PackageList pkgs = addons(); - foreach(QApt::Package* p, pkgs) { - ret += PackageState(p->name(), p->shortDescription(), p->isInstalled()); - } - return ret; -} - -bool Application::isValid() const -{ - return m_isValid; -} - -bool Application::isTechnical() const -{ - return m_isTechnical; -} - -QUrl Application::homepage() -{ - if(!m_package) return QUrl(); - return QUrl(m_package->homepage()); -} - -QString Application::origin() const -{ - if(!m_package) return QString(); - return m_package->origin(); -} - -QString Application::longDescription() -{ - const QString comment = m_data.isValid() ? m_data.description() : QString(); - if(!comment.isEmpty()) return comment; - if(m_package) return QString(); - return m_package->longDescription(); -} - -QString Application::availableVersion() const -{ - if(!m_package) return QString(); - return m_package->availableVersion(); -} - -QString Application::installedVersion() const -{ - if(!m_package) return QString(); - return m_package->installedVersion(); -} - -QString Application::sizeDescription() -{ - KFormat f; - if (!isInstalled()) { - return i18nc("@info app size", "%1 to download, %2 on disk", - f.formatByteSize(package()->downloadSize()), - f.formatByteSize(package()->availableInstalledSize())); - } else { - return i18nc("@info app size", "%1 on disk", - f.formatByteSize(package()->currentInstalledSize())); - } -} - -int Application::size() -{ - return m_package->downloadSize(); -} - -void Application::clearPackage() -{ - m_package = nullptr; -} - -QVector<KService::Ptr> Application::findExecutables() const -{ - QVector<KService::Ptr> ret; - if (!m_package) { - qWarning() << "trying to find the executables for an uninitialized package!" << packageName(); - return ret; - } - - QRegExp rx(QStringLiteral(".+\\.desktop$"), Qt::CaseSensitive); - foreach (const QString &desktop, m_package->installedFilesList().filter(rx)) { - // Important to use serviceByStorageId to ensure we get a service even - // if the KSycoca database doesn't have our .desktop file yet. - KService::Ptr service = KService::serviceByStorageId(desktop); - if (service && - service->isApplication() && - !service->noDisplay() && - !service->exec().isEmpty()) - { - ret << service; - } - } - return ret; -} - -void Application::emitStateChanged() -{ - emit stateChanged(); -} - -void Application::invokeApplication() const -{ - QVector< KService::Ptr > execs = findExecutables(); - Q_ASSERT(!execs.isEmpty()); - KToolInvocation::startServiceByDesktopName(execs.first()->desktopEntryName()); -} - -bool Application::canExecute() const -{ - return !findExecutables().isEmpty(); -} - -QString Application::section() -{ - return package()->section(); -} - -AbstractResource::State Application::state() -{ - if (!package()) - return Broken; - - int s = package()->state(); - - if (s & QApt::Package::Upgradeable) { -#if QAPT_VERSION >= QT_VERSION_CHECK(3, 1, 0) - if (package()->isInUpdatePhase()) - return Upgradeable; -#else - return Upgradeable; -#endif - } - - if (s & QApt::Package::Installed) { - return Installed; - } - - return None; // Actually: none of interest to us here in plasma-discover. -} - -void Application::fetchScreenshots() -{ - if(!m_sourceHasScreenshot) - return; - - QString dest = QStandardPaths::locate(QStandardPaths::TempLocation, QStringLiteral("screenshots.")+m_packageName); - const QUrl packageUrl(MuonDataSources::screenshotsSource().toString() + QStringLiteral("/json/package/")+m_packageName); - KIO::StoredTransferJob* job = KIO::storedGet(packageUrl, KIO::NoReload, KIO::HideProgressInfo); - connect(job, &KIO::StoredTransferJob::finished, this, &Application::downloadingScreenshotsFinished); -} - -void Application::downloadingScreenshotsFinished(KJob* j) -{ - KIO::StoredTransferJob* job = qobject_cast< KIO::StoredTransferJob* >(j); - bool done = false; - if(job) { - QJsonParseError error; - QJsonDocument doc = QJsonDocument::fromJson(job->data(), &error); - if(error.error != QJsonParseError::NoError) { - QVariantMap values = doc.toVariant().toMap(); - QVariantList screenshots = values[QStringLiteral("screenshots")].toList(); - - QList<QUrl> thumbnailUrls, screenshotUrls; - foreach(const QVariant& screenshot, screenshots) { - QVariantMap s = screenshot.toMap(); - thumbnailUrls += s[QStringLiteral("small_image_url")].toUrl(); - screenshotUrls += s[QStringLiteral("large_image_url")].toUrl(); - } - emit screenshotsFetched(thumbnailUrls, screenshotUrls); - done = true; - } - } - if(!done) { - QList<QUrl> thumbnails, screenshots; - if(!thumbnailUrl().isEmpty()) { - thumbnails += thumbnailUrl(); - screenshots += screenshotUrl(); - } - emit screenshotsFetched(thumbnails, screenshots); - } - -} - -void Application::setHasScreenshot(bool has) -{ - m_sourceHasScreenshot = has; -} - -QStringList Application::executables() const -{ - QStringList ret; - const QVector<KService::Ptr> exes = findExecutables(); - for(KService::Ptr exe : exes) { - ret += exe->exec(); - } - return ret; -} - -bool Application::isFromSecureOrigin() const -{ - Q_FOREACH (const QString &archive, m_package->archives()) { - if (archive.contains(QLatin1String("security"))) { - return true; - } - } - return false; -} - -void Application::fetchChangelog() -{ - KIO::StoredTransferJob* getJob = KIO::storedGet(m_package->changelogUrl(), KIO::NoReload, KIO::HideProgressInfo); - connect(getJob, &KIO::StoredTransferJob::result, this, &Application::processChangelog); -} - -void Application::processChangelog(KJob* j) -{ - KIO::StoredTransferJob* job = qobject_cast<KIO::StoredTransferJob*>(j); - if (!m_package || !job) { - return; - } - - QString changelog; - if(j->error()==0) - changelog = buildDescription(job->data(), m_package->sourcePackage()); - - if (changelog.isEmpty()) { - if (m_package->origin() == QStringLiteral("Ubuntu")) { - changelog = xi18nc("@info/rich", "The list of changes is not yet available. " - "Please use <link url='%1'>Launchpad</link> instead.", - QStringLiteral("http://launchpad.net/ubuntu/+source/") + m_package->sourcePackage()); - } else { - changelog = xi18nc("@info", "The list of changes is not yet available."); - } - } - emit changelogFetched(changelog); -} - -QString Application::buildDescription(const QByteArray& data, const QString& source) -{ - QApt::Changelog changelog(QString::fromLatin1(data), source); - QString description; - - QApt::ChangelogEntryList entries = changelog.newEntriesSince(m_package->installedVersion()); - - if (entries.size() < 1) { - return description; - } - - foreach(const QApt::ChangelogEntry &entry, entries) { - description += i18nc("@info:label Refers to a software version, Ex: Version 1.2.1:", - "Version %1:", entry.version()); - - KFormat f; - QString issueDate = entry.issueDateTime().toString(Qt::DefaultLocaleShortDate); - description += QLatin1String("<p>") + - i18nc("@info:label", "This update was issued on %1", issueDate) + - QLatin1String("</p>"); - - QString updateText = entry.description(); - updateText.replace(QLatin1Char('\n'), QLatin1String("<br/>")); - description += QLatin1String("<p><pre>") + updateText + QLatin1String("</pre></p>"); - } - - return description; -} - -QApt::Backend *Application::backend() const -{ - return qobject_cast<ApplicationBackend*>(parent())->backend(); -} diff --git a/libdiscover/backends/ApplicationBackend/Application.h b/libdiscover/backends/ApplicationBackend/Application.h deleted file mode 100644 index 7414280..0000000 --- a/libdiscover/backends/ApplicationBackend/Application.h +++ /dev/null @@ -1,114 +0,0 @@ -/*************************************************************************** - * Copyright © 2010-2011 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef APPLICATION_H -#define APPLICATION_H - -#include <QtCore/QByteArray> -#include <QtCore/QHash> -#include <QtCore/QStringList> - -#include <KService> - -#include <AppstreamQt/component.h> -#include <QApt/Package> - -#include "discovercommon_export.h" -#include "resources/AbstractResource.h" - -class KJob; -class KConfig; -namespace QApt { - class Backend; -} - -class DISCOVERCOMMON_EXPORT Application : public AbstractResource -{ -Q_OBJECT -public: - explicit Application(const Appstream::Component &component, QApt::Backend *backend); - explicit Application(QApt::Package *package, QApt::Backend *backend); - - QString name() override; - QString comment() override; - QApt::Package *package(); - QVariant icon() const override; - QStringList mimetypes() const override; - QStringList categories() override; - QString license() override; - QUrl screenshotUrl() override; - QUrl thumbnailUrl() override; - QList< PackageState > addonsInformation() override; - bool isValid() const; - bool isTechnical() const override; - QString packageName() const override; - - //QApt::Package forwarding - QUrl homepage() override; - QString longDescription() override; - QString installedVersion() const override; - QString availableVersion() const override; - QString sizeDescription() override; - QString origin() const override; - int size() override; - - bool hasScreenshot() const { return m_sourceHasScreenshot; } - void setHasScreenshot(bool has); - - void clearPackage(); - QVector<KService::Ptr> findExecutables() const; - QStringList executables() const override; - - /** Used to trigger the stateChanged signal from the ApplicationBackend */ - void emitStateChanged(); - - void invokeApplication() const override; - - bool canExecute() const override; - QString section() override; - - State state() override; - void fetchScreenshots() override; - void fetchChangelog() override; - - bool isFromSecureOrigin() const; - -private Q_SLOTS: - void processChangelog(KJob*); - void downloadingScreenshotsFinished(KJob*); - -private: - QApt::Backend *backend() const; - QStringList findProvides(Appstream::Provides::Kind kind) const; - QString buildDescription(const QByteArray& data, const QString& source); - - const Appstream::Component m_data; - QApt::Package *m_package; - QString m_packageName; - - bool m_isValid; - bool m_isTechnical; - bool m_isExtrasApp; - bool m_sourceHasScreenshot; - - QApt::PackageList addons(); -}; - -#endif diff --git a/libdiscover/backends/ApplicationBackend/ApplicationBackend.cpp b/libdiscover/backends/ApplicationBackend/ApplicationBackend.cpp deleted file mode 100644 index c5993e5..0000000 --- a/libdiscover/backends/ApplicationBackend/ApplicationBackend.cpp +++ /dev/null @@ -1,676 +0,0 @@ -/*************************************************************************** - * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "ApplicationBackend.h" - -// Qt includes -#include <QtConcurrentRun> -#include <QtCore/QDir> -#include <QtCore/QStringBuilder> -#include <QtCore/QStringList> -#include <QtCore/QUuid> -#include <QTimer> -#include <QSignalMapper> -#include <QJsonDocument> -#include <QAction> - -// KDE includes -#include <KLocalizedString> -#include <KMessageBox> -#include <KProcess> -#include <KProtocolManager> -#include <KIO/Job> -#include <KActionCollection> -#include <KIconLoader> -#include <KXmlGuiWindow> - -#include <AppstreamQt/database.h> - -// QApt/DebconfKDE includes -#include <QApt/Backend> -#include <QApt/Transaction> -#include <DebconfGui.h> - -//libmuonapt includes -#include "MuonStrings.h" -#include "ChangesDialog.h" -#include "QAptActions.h" - -// Own includes -#include "AptSourcesBackend.h" -#include "Application.h" -#include "ReviewsBackend.h" -#include "Transaction/Transaction.h" -#include "Transaction/TransactionModel.h" -#include "ApplicationUpdates.h" -#include <resources/SourcesModel.h> -#include <MuonDataSources.h> - -MUON_BACKEND_PLUGIN(ApplicationBackend) - -class AptTransaction : public Transaction -{ -public: - AptTransaction(QObject *parent, AbstractResource *resource, Transaction::Role role, const AddonList &addons = {}) - : Transaction(parent, resource, role, addons), m_aptTrans(nullptr) {} - - void cancel() { - m_aptTrans->cancel(); - } - - QApt::Transaction *aptTrans() const { return m_aptTrans; } - void setAptTrans(QApt::Transaction *t) { m_aptTrans = t; } - -private: - QApt::Transaction *m_aptTrans; -}; - -ApplicationBackend::ApplicationBackend(QObject* parent) - : AbstractResourcesBackend(parent) - , m_backend(new QApt::Backend(this)) - , m_reviewsBackend(new ReviewsBackend(this)) - , m_isFetching(true) - , m_currentTransaction(nullptr) - , m_backendUpdater(new ApplicationUpdates(this)) - , m_aptify(nullptr) - , m_aptBackendInitialized(false) -{ - KIconLoader::global()->reconfigure(QString(), QStringList(QStringLiteral("/usr/share/app-install/icons/"))); - - m_watcher = new QFutureWatcher<QVector<Application*> >(this); - connect(m_watcher, &QFutureWatcher<QVector<Application*> >::finished, this, &ApplicationBackend::setApplications); - connect(m_reviewsBackend, &ReviewsBackend::ratingsReady, this, &AbstractResourcesBackend::emitRatingsReady); - - QTimer::singleShot(10, this, SLOT(initBackend())); -} - -ApplicationBackend::~ApplicationBackend() -{ - qDeleteAll(m_appList); -} - -QVector<Application *> init(QApt::Backend *backend, QThread* thread) -{ - Appstream::Database appdata; - bool opened = appdata.open(); - Q_ASSERT(opened); - - QVector<Application *> tempList; - QSet<QString> packages; - foreach(const Appstream::Component &component, appdata.allComponents()) { - if (component.packageNames().isEmpty()) - continue; - Application *app = new Application(component, backend); - packages.insert(app->packageName()); - tempList << app; - } - - foreach (QApt::Package *package, backend->availablePackages()) { - //Don't create applications twice - if(packages.contains(package->name())) - continue; - - if (package->isMultiArchDuplicate()) - continue; - - Application *app = new Application(package, backend); - tempList << app; - } - - // To be added an Application must have a package that: - // a) exists - // b) is not on the blacklist - // c) if not downloadable, then it must already be installed - QVector<Application *> appList; - appList.reserve(tempList.size()); - Q_FOREACH (Application *app, tempList) { - QApt::Package *pkg = app->package(); - if (app->isValid() && pkg) - { - appList << app; - app->moveToThread(thread); - } - else - delete app; - } - - return appList; -} - -void ApplicationBackend::setApplications() -{ - m_appList = m_watcher->future().result(); - Q_FOREACH (Application* app, m_appList) - app->setParent(this); - - KIO::StoredTransferJob* job = KIO::storedGet(QUrl(MuonDataSources::screenshotsSource().toString() + QStringLiteral("/json/packages")),KIO::NoReload, KIO::DefaultFlags|KIO::HideProgressInfo); - connect(job, &KIO::StoredTransferJob::finished, this, &ApplicationBackend::initAvailablePackages); - - if (m_aptify) - QAptActions::self()->setCanExit(true); - setFetching(false); -} - -void ApplicationBackend::reload() -{ - if(isFetching()) { - qWarning() << "Reloading while already reloading... Please report."; - return; - } - setFetching(true); - if (m_aptify) - QAptActions::self()->setCanExit(false); - foreach(Application* app, m_appList) - app->clearPackage(); - qDeleteAll(m_transQueue); - m_transQueue.clear(); - m_reviewsBackend->stopPendingJobs(); - - if (!m_backend->reloadCache()) - QAptActions::self()->initError(); - - foreach(Application* app, m_appList) - app->package(); - - if (m_aptify) - QAptActions::self()->setCanExit(true); - setFetching(false); -} - -bool ApplicationBackend::isFetching() const -{ - return m_isFetching; -} - -bool ApplicationBackend::isValid() const -{ - // ApplicationBackend will force an application quit if it is invalid, so - // if it has not done that, the backend is valid. - return true; -} - -void ApplicationBackend::aptTransactionsChanged(QString active) -{ - // Find the newly-active QApt transaction in our list - AptTransaction* discTrans = nullptr; - - Q_FOREACH (AptTransaction *t, m_transQueue) { - if (t->aptTrans()->transactionId() == active) { - discTrans = t; - break; - } - } - - if (!discTrans || discTrans == m_currentTransaction) - return; - - m_currentTransaction = discTrans; - QApt::Transaction *trans = discTrans->aptTrans(); - connect(trans, &QApt::Transaction::statusChanged, this, &ApplicationBackend::transactionEvent); - connect(trans, &QApt::Transaction::errorOccurred, this, &ApplicationBackend::errorOccurred); - connect(trans, &QApt::Transaction::progressChanged, this, &ApplicationBackend::updateProgress); - // FIXME: untrusted packages, conf file prompt, media change -} - -void ApplicationBackend::transactionEvent(QApt::TransactionStatus status) -{ - if (!m_currentTransaction->aptTrans()) - return; - - TransactionModel *transModel = TransactionModel::global(); - - switch (status) { - case QApt::SetupStatus: - case QApt::AuthenticationStatus: - case QApt::WaitingStatus: - case QApt::WaitingLockStatus: - case QApt::WaitingMediumStatus: - case QApt::WaitingConfigFilePromptStatus: - case QApt::LoadingCacheStatus: - m_currentTransaction->setStatus(Transaction::SetupStatus); - break; - case QApt::RunningStatus: - m_currentTransaction->setStatus(Transaction::QueuedStatus); - break; - case QApt::DownloadingStatus: - m_currentTransaction->setStatus(Transaction::DownloadingStatus); - m_currentTransaction->setCancellable(false); - break; - case QApt::CommittingStatus: - m_currentTransaction->setStatus(Transaction::CommittingStatus); - - // Set up debconf - m_debconfGui = new DebconfKde::DebconfGui(m_currentTransaction->aptTrans()->debconfPipe()); - m_debconfGui->connect(m_debconfGui, &DebconfKde::DebconfGui::activated, m_debconfGui, &DebconfKde::DebconfGui::show); - m_debconfGui->connect(m_debconfGui, &DebconfKde::DebconfGui::deactivated, m_debconfGui, &DebconfKde::DebconfGui::hide); - break; - case QApt::FinishedStatus: - m_currentTransaction->setStatus(Transaction::DoneStatus); - - // Clean up manually created debconf pipe - QApt::Transaction *trans = m_currentTransaction->aptTrans(); - if (!trans->debconfPipe().isEmpty()) - QFile::remove(trans->debconfPipe()); - - // Cleanup - trans->deleteLater(); - - if (trans->exitStatus() == QApt::ExitCancelled) - transModel->cancelTransaction(m_currentTransaction); - else - transModel->removeTransaction(m_currentTransaction); - m_transQueue.removeAll(m_currentTransaction); - - qobject_cast<Application*>(m_currentTransaction->resource())->emitStateChanged(); - delete m_currentTransaction; - m_currentTransaction = nullptr; - - if (m_transQueue.isEmpty()) - reload(); - break; - } -} - -void ApplicationBackend::errorOccurred(QApt::ErrorCode error) -{ - if (m_transQueue.isEmpty()) // Shouldn't happen - return; - - if( error == QApt::AuthError){ - m_currentTransaction->cancel(); - m_transQueue.removeAll(m_currentTransaction); - m_currentTransaction->deleteLater(); - m_currentTransaction = nullptr; - } - QAptActions::self()->displayTransactionError(error, m_currentTransaction->aptTrans()); -} - -void ApplicationBackend::updateProgress(int percentage) -{ - if(!m_currentTransaction) { - qDebug() << "missing transaction"; - return; - } - m_currentTransaction->setProgress(percentage); -} - -bool ApplicationBackend::confirmRemoval(QApt::StateChanges changes) -{ - const QApt::PackageList removeList = changes.value(QApt::Package::ToRemove); - if (removeList.isEmpty()) - return true; - - QApt::StateChanges removals; - removals[QApt::Package::ToRemove] = removeList; - - QPointer<ChangesDialog> dialog = new ChangesDialog(mainWindow(), removals); - bool ret = dialog->exec() == QDialog::Accepted; - delete dialog; - return ret; -} - -void ApplicationBackend::markTransaction(Transaction *transaction) -{ - Application *app = qobject_cast<Application*>(transaction->resource()); - - switch (transaction->role()) { - case Transaction::InstallRole: - app->package()->setInstall(); - markLangpacks(transaction); - break; - case Transaction::RemoveRole: - app->package()->setRemove(); - break; - default: - break; - } - - AddonList addons = transaction->addons(); - - Q_FOREACH (const QString &pkgStr, addons.addonsToInstall()) { - QApt::Package *package = m_backend->package(pkgStr); - package->setInstall(); - } - - Q_FOREACH (const QString &pkgStr, addons.addonsToRemove()) { - QApt::Package *package = m_backend->package(pkgStr); - package->setRemove(); - } -} - -void ApplicationBackend::markLangpacks(Transaction *transaction) -{ - QString prog = QStandardPaths::findExecutable(QStringLiteral("check-language-support")); - if (prog.isEmpty()){ - prog = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("discover/scripts/check-language-support")); - if ( prog.isEmpty()){ - return; - } - } - - QString language = QLocale().name(); - QString pkgName = transaction->resource()->packageName(); - - QStringList args; - args << prog << QLatin1String("-l") << language << QLatin1String("-p") << pkgName; - - KProcess proc; - proc.setOutputChannelMode(KProcess::OnlyStdoutChannel); - proc.setProgram(args); - proc.start(); - proc.waitForFinished(); - - QString res = QString::fromLatin1(proc.readAllStandardOutput()); - res.remove(QString()); - - m_backend->setCompressEvents(true); - foreach(const QString &pkg, res.split(QLatin1Char(' '))) - { - QApt::Package *langPack = m_backend->package(pkg.trimmed()); - - if (langPack) - langPack->setInstall(); - } - m_backend->setCompressEvents(false); -} - -void ApplicationBackend::addTransaction(AptTransaction *transaction) -{ - if(!transaction){ - return; - } - QApt::CacheState oldCacheState = m_backend->currentCacheState(); - m_backend->saveCacheState(); - - markTransaction(transaction); - - // Find changes due to markings - QApt::PackageList excluded; - excluded.append(qobject_cast<Application*>(transaction->resource())->package()); - // Exclude addons being marked - Q_FOREACH (const QString &pkgStr, transaction->addons().addonsToInstall()) { - QApt::Package *addon = m_backend->package(pkgStr); - - if (addon) - excluded.append(addon); - } - - Q_FOREACH (const QString &pkgStr, transaction->addons().addonsToRemove()) { - QApt::Package *addon = m_backend->package(pkgStr); - - if (addon) - excluded.append(addon); - } - - QApt::StateChanges changes = m_backend->stateChanges(oldCacheState, excluded); - - if (!confirmRemoval(changes)) { - m_backend->restoreCacheState(oldCacheState); - transaction->deleteLater(); - return; - } - - Application *app = qobject_cast<Application*>(transaction->resource()); - - if (app->package()->wouldBreak()) { - m_backend->restoreCacheState(oldCacheState); - //TODO Notify of error - } - - QApt::Transaction *aptTrans = m_backend->commitChanges(); - setupTransaction(aptTrans); - transaction->setAptTrans(aptTrans); - TransactionModel::global()->addTransaction(transaction); - aptTrans->run(); - m_backend->restoreCacheState(oldCacheState); // Undo temporary simulation marking - - if (m_transQueue.count() == 1) { - aptTransactionsChanged(aptTrans->transactionId()); - m_currentTransaction = transaction; - } -} - -QApt::Backend* ApplicationBackend::backend() const -{ - return m_backend; -} - -AbstractReviewsBackend *ApplicationBackend::reviewsBackend() const -{ - return m_reviewsBackend; -} - -QVector<AbstractResource*> ApplicationBackend::allResources() const -{ - QVector<AbstractResource*> ret; - - Q_FOREACH (Application* app, m_appList) { - ret += app; - } - return ret; -} - -void ApplicationBackend::installApplication(AbstractResource* res, const AddonList& addons) -{ - Application* app = qobject_cast<Application*>(res); - Transaction::Role role = app->package()->isInstalled() ? Transaction::ChangeAddonsRole : Transaction::InstallRole; - addTransaction(new AptTransaction(this, res, role, addons)); -} - -void ApplicationBackend::installApplication(AbstractResource* app) -{ - addTransaction(new AptTransaction(this, app, Transaction::InstallRole)); -} - -void ApplicationBackend::removeApplication(AbstractResource* app) -{ - addTransaction(new AptTransaction(this, app, Transaction::RemoveRole)); -} - -int ApplicationBackend::updatesCount() const -{ - if(m_isFetching) - return 0; - - int count = 0; - foreach(Application* app, m_appList) { - count += app->canUpgrade(); - } - return count; -} - -AbstractResource* ApplicationBackend::resourceByPackageName(const QString& name) const -{ - foreach(Application* app, m_appList) { - if(app->packageName()==name) - return app; - } - return nullptr; -} - -QList<AbstractResource*> ApplicationBackend::searchPackageName(const QString& searchText) -{ - QList<AbstractResource*> resources; - if(m_isFetching) { - qWarning() << "searching while fetching!!!"; - return resources; - } - - QSet<QApt::Package*> packages = m_backend->search(searchText).toSet(); - - foreach(Application* a, m_appList) { - if(packages.contains(a->package())) { - resources += a; - } - } - return resources; -} - -AbstractBackendUpdater* ApplicationBackend::backendUpdater() const -{ - return m_backendUpdater; -} - -void ApplicationBackend::integrateActions(KActionCollection* w) -{ - m_aptify = w; - QAptActions* apt = QAptActions::self(); - apt->setActionCollection(w); - if(!m_aptBackendInitialized) - connect(this, &ApplicationBackend::aptBackendInitialized, apt, &QAptActions::setBackend); - if (apt->reloadWhenSourcesEditorFinished()) - connect(apt, &QAptActions::sourcesEditorClosed, this, &ApplicationBackend::reload); - QAction* updateAction = w->addAction(QStringLiteral("update")); - updateAction->setIcon(QIcon::fromTheme(QStringLiteral("system-software-update"))); - updateAction->setText(i18nc("@action Checks the Internet for updates", "Check for Updates")); - updateAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R)); - updateAction->setEnabled(apt->isConnected()); - connect(updateAction, &QAction::triggered, this, &ApplicationBackend::checkForUpdates); - connect(apt, &QAptActions::shouldConnect, updateAction, &QAction::setEnabled); -} - -QWidget* ApplicationBackend::mainWindow() const -{ - return QAptActions::self()->mainWindow(); -} - -void ApplicationBackend::initBackend() -{ - setFetching(true); - if (m_aptify) { - QAptActions::self()->setCanExit(false); - QAptActions::self()->setReloadWhenEditorFinished(true); - } - - QAptActions::self()->setBackend(m_backend); - if (m_backend->xapianIndexNeedsUpdate()) - m_backend->updateXapianIndex(); - - m_aptBackendInitialized = true; - emit aptBackendInitialized(m_backend); - - m_backend->setUndoRedoCacheSize(1); - m_reviewsBackend->setAptBackend(m_backend); - m_backendUpdater->setBackend(m_backend); - - QFuture<QVector<Application*> > future = QtConcurrent::run(init, m_backend, QThread::currentThread()); - m_watcher->setFuture(future); - connect(m_backend, &QApt::Backend::transactionQueueChanged, this, &ApplicationBackend::aptTransactionsChanged); - connect(m_backend, &QApt::Backend::xapianUpdateFinished, this, &ApplicationBackend::searchInvalidated); - - SourcesModel::global()->addSourcesBackend(new AptSourcesBackend(this)); -} - -void ApplicationBackend::setupTransaction(QApt::Transaction *trans) -{ - // Provide proxy/locale to the transaction - if (KProtocolManager::proxyType() == KProtocolManager::ManualProxy) { - trans->setProxy(KProtocolManager::proxyFor(QStringLiteral("http"))); - } - - trans->setLocale(QLatin1String(setlocale(LC_MESSAGES, nullptr))); - - // Debconf - QString uuid = QUuid::createUuid().toString(); - uuid.remove(QLatin1Char('{')).remove(QLatin1Char('}')).remove(QLatin1Char('-')); - QFile pipe(QDir::tempPath() % QLatin1String("/qapt-sock-") % uuid); - pipe.open(QFile::ReadWrite); - pipe.close(); - trans->setDebconfPipe(pipe.fileName()); -} - -void ApplicationBackend::sourcesEditorClosed() -{ - reload(); - emit sourcesEditorFinished(); -} - -void ApplicationBackend::initAvailablePackages(KJob* j) -{ - KIO::StoredTransferJob* job = qobject_cast<KIO::StoredTransferJob*>(j); - Q_ASSERT(job); - - QJsonParseError error; - QJsonDocument doc = QJsonDocument::fromJson(job->data(), &error); - if(error.error != QJsonParseError::NoError) - qWarning() << "errors!" << error.errorString(); - else { - QVariantList data = doc.toVariant().toMap().value(QStringLiteral("packages")).toList(); - Q_ASSERT(!m_appList.isEmpty()); - QSet<QString> packages; - foreach(const QVariant& v, data) { - packages += v.toMap().value(QStringLiteral("name")).toString(); - } - Q_ASSERT(packages.count()==data.count()); - Q_FOREACH (Application* a, m_appList) { - a->setHasScreenshot(packages.contains(a->packageName())); - } - } -} - -void ApplicationBackend::checkForUpdates() -{ - QApt::Transaction* transaction = backend()->updateCache(); - m_backendUpdater->setupTransaction(transaction); - transaction->run(); - m_backendUpdater->setProgressing(true); - connect(transaction, &QApt::Transaction::finished, this, &ApplicationBackend::updateFinished); -} - -void ApplicationBackend::updateFinished(QApt::ExitStatus status) -{ - if(status != QApt::ExitSuccess) { - qWarning() << "updating was not successful"; - } - m_backendUpdater->setProgressing(false); -} - -void ApplicationBackend::setFetching(bool f) -{ - if(m_isFetching != f) { - m_isFetching = f; - emit fetchingChanged(); - if(!m_isFetching) { - emit searchInvalidated(); - emit updatesCountChanged(); - } - } -} - -QList<QAction*> ApplicationBackend::messageActions() const -{ - QList<QAction*> ret; - //high priority - ret += QAptActions::self()->actionCollection()->action(QStringLiteral("dist-upgrade")); - - //normal priority - ret += QAptActions::self()->actionCollection()->action(QStringLiteral("update")); - - //low priority - ret += QAptActions::self()->actionCollection()->action(QStringLiteral("software_properties")); - ret += QAptActions::self()->actionCollection()->action(QStringLiteral("load_archives")); - ret += QAptActions::self()->actionCollection()->action(QStringLiteral("save_package_list")); - ret += QAptActions::self()->actionCollection()->action(QStringLiteral("download_from_list")); - ret += QAptActions::self()->actionCollection()->action(QStringLiteral("history")); - Q_ASSERT(!ret.contains(nullptr)); - return ret; -} - -#include "ApplicationBackend.moc" diff --git a/libdiscover/backends/ApplicationBackend/ApplicationBackend.h b/libdiscover/backends/ApplicationBackend/ApplicationBackend.h deleted file mode 100644 index 6e0b732..0000000 --- a/libdiscover/backends/ApplicationBackend/ApplicationBackend.h +++ /dev/null @@ -1,128 +0,0 @@ -/*************************************************************************** - * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef APPLICATIONBACKEND_H -#define APPLICATIONBACKEND_H - -#include <QFutureWatcher> -#include <QtCore/QObject> -#include <QtCore/QPointer> -#include <QtCore/QQueue> -#include <QtCore/QSet> -#include <QtCore/QStringList> -#include <QtCore/QVector> - -#include <QApt/Package> -#include <QApt/Backend> - -#include "resources/AbstractResourcesBackend.h" - -namespace QApt { - class Backend; - class Transaction; -} -namespace DebconfKde { - class DebconfGui; -} - -class Application; -class ApplicationUpdates; -class ReviewsBackend; -class Transaction; -class AptTransaction; -class QAptActions; -class KJob; - -class ApplicationBackend : public AbstractResourcesBackend -{ - Q_OBJECT - Q_PROPERTY(QObject* backend READ backend) -public: - explicit ApplicationBackend(QObject *parent = nullptr); - ~ApplicationBackend() override; - - bool isValid() const override; - AbstractReviewsBackend *reviewsBackend() const override; - Q_SCRIPTABLE AbstractResource* resourceByPackageName(const QString& name) const override; - QApt::Backend* backend() const; - - int updatesCount() const override; - - bool confirmRemoval(QApt::StateChanges changes); - bool isFetching() const override; - void markTransaction(Transaction *transaction); - void markLangpacks(Transaction *transaction); - - QVector< AbstractResource* > allResources() const override; - QList<AbstractResource*> searchPackageName(const QString& searchText) override; - - void installApplication(AbstractResource *res, const AddonList& addons) override; - void installApplication(AbstractResource *app) override; - void removeApplication(AbstractResource *app) override; - - AbstractBackendUpdater* backendUpdater() const override; - void integrateActions(KActionCollection* w) override; - QWidget* mainWindow() const; - QList<QAction*> messageActions() const override; - -private: - void setFetching(bool f); - - QApt::Backend *m_backend; - ReviewsBackend *m_reviewsBackend; - bool m_isFetching; - - QFutureWatcher<QVector<Application*> >* m_watcher; - QVector<Application *> m_appList; - - // Transactions - QVector<AptTransaction *> m_transQueue; - QPointer<AptTransaction> m_currentTransaction; - - DebconfKde::DebconfGui *m_debconfGui; - ApplicationUpdates* m_backendUpdater; - KActionCollection *m_aptify; - bool m_aptBackendInitialized; - -public Q_SLOTS: - void reload(); - void addTransaction(AptTransaction *transaction); - //helper functions - void initAvailablePackages(KJob*); - -private Q_SLOTS: - void setApplications(); - void aptTransactionsChanged(QString active); - void transactionEvent(QApt::TransactionStatus status); - void errorOccurred(QApt::ErrorCode error); - void updateProgress(int percentage); - void initBackend(); - void setupTransaction(QApt::Transaction *trans); - void sourcesEditorClosed(); - void checkForUpdates(); - void updateFinished(QApt::ExitStatus); - -Q_SIGNALS: - void startingFirstTransaction(); - void sourcesEditorFinished(); - void aptBackendInitialized(QApt::Backend* backend); -}; - -#endif diff --git a/libdiscover/backends/ApplicationBackend/ApplicationNotifier.cpp b/libdiscover/backends/ApplicationBackend/ApplicationNotifier.cpp deleted file mode 100644 index aba5dbc..0000000 --- a/libdiscover/backends/ApplicationBackend/ApplicationNotifier.cpp +++ /dev/null @@ -1,172 +0,0 @@ -/*************************************************************************** - * Copyright © 2013 Lukas Appelhans <l.appelhans@gmx.de> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ -#include "ApplicationNotifier.h" - -// Qt includes -#include <QtCore/QFile> -#include <QtCore/QTimer> -#include <QtCore/QDebug> -#include <QtCore/QStandardPaths> -#include <QtCore/QProcess> -#include <QtGui/QIcon> - -// KDE includes -#include <KDirWatch> -#include <KLocalizedString> -#include <KPluginFactory> -#include <KNotification> - -ApplicationNotifier::ApplicationNotifier(QObject* parent) - : BackendNotifierModule(parent) - , m_checkerProcess(Q_NULLPTR) - , m_updateCheckerProcess(Q_NULLPTR) - , m_securityUpdates(0) - , m_normalUpdates(0) -{ - KDirWatch *stampDirWatch = new KDirWatch(this); - stampDirWatch->addFile(QStringLiteral("/var/lib/update-notifier/dpkg-run-stamp")); - connect(stampDirWatch, &KDirWatch::dirty, this, &ApplicationNotifier::distUpgradeEvent); - - QTimer* t = new QTimer(this); - t->setSingleShot(true); - t->setInterval(2000); - connect(t, &QTimer::timeout, this, &ApplicationNotifier::recheckSystemUpdateNeeded); - - stampDirWatch = new KDirWatch(this); - stampDirWatch->addDir(QStringLiteral("/var/lib/apt/lists/")); - stampDirWatch->addDir(QStringLiteral("/var/lib/apt/lists/partial/")); - stampDirWatch->addFile(QStringLiteral("/var/lib/update-notifier/updates-available")); - stampDirWatch->addFile(QStringLiteral("/var/lib/update-notifier/dpkg-run-stamp")); - connect(stampDirWatch, &KDirWatch::dirty, t, static_cast<void(QTimer::*)()>(&QTimer::start)); -// connect(stampDirWatch, &KDirWatch::dirty, this, [](const QString& dirty){ qDebug() << "dirty path" << dirty;}); - - m_updateCheckerProcess = new QProcess(this); - m_updateCheckerProcess->setProgram(QStringLiteral("/usr/lib/update-notifier/apt-check")); - connect(m_updateCheckerProcess, static_cast<void(QProcess::*)(int)>(&QProcess::finished), this, &ApplicationNotifier::parseUpdateInfo); - - init(); -} - -ApplicationNotifier::~ApplicationNotifier() = default; - -void ApplicationNotifier::init() -{ - recheckSystemUpdateNeeded(); - distUpgradeEvent(); -} - -void ApplicationNotifier::distUpgradeEvent() -{ - QString checkerFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("libdiscover/applicationsbackend/releasechecker")); - if (checkerFile.isEmpty()) { - qWarning() << "Couldn't find the releasechecker" << checkerFile << QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); - return; - } - m_checkerProcess = new QProcess(this); - connect(m_checkerProcess, static_cast<void (QProcess::*)(int)>(&QProcess::finished), this, &ApplicationNotifier::checkUpgradeFinished); - m_checkerProcess->start(QStringLiteral("/usr/bin/python3"), QStringList() << checkerFile); -} - -void ApplicationNotifier::checkUpgradeFinished(int exitStatus) -{ - if (exitStatus == 0) { - KNotification *n = KNotification::event(QStringLiteral("DistUpgrade"), - i18n("System update available!"), - i18nc("Notification when a new version of Kubuntu is available", - "A new version of Kubuntu is available"), - QStringLiteral("system-software-update"), - nullptr, - KNotification::CloseOnTimeout, - QStringLiteral("muonapplicationnotifier")); - n->setActions(QStringList() << i18n("Upgrade")); - connect(n, &KNotification::action1Activated, this, &ApplicationNotifier::upgradeActivated); - } - - m_checkerProcess->deleteLater(); - m_checkerProcess = nullptr; -} - -void ApplicationNotifier::upgradeActivated() -{ - const QString kdesu = QFile::decodeName(CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/kdesu"); - QProcess::startDetached(kdesu, { QStringLiteral("--"), QStringLiteral("do-release-upgrade"), QStringLiteral("-m"), QStringLiteral("desktop"), QStringLiteral("-f"), QStringLiteral("DistUpgradeViewKDE") }); -} - -void ApplicationNotifier::recheckSystemUpdateNeeded() -{ - qDebug() << "should recheck..." << m_updateCheckerProcess << m_updateCheckerProcess->state(); - - if (m_updateCheckerProcess->state() == QProcess::Running) - return; - - m_updateCheckerProcess->start(); -} - -void ApplicationNotifier::parseUpdateInfo() -{ - if (!m_updateCheckerProcess) - return; - -#warning why does this parse stdout and not use qapt, wtf... - // Weirdly enough, apt-check gives output on stderr - QByteArray line = m_updateCheckerProcess->readAllStandardError(); - if (line.isEmpty()) - return; - - // Format updates;security - int eqpos = line.indexOf(';'); - - if (eqpos > 0) { - QByteArray updatesString = line.left(eqpos); - QByteArray securityString = line.right(line.size() - eqpos - 1); - - int securityUpdates = securityString.toInt(); - setUpdates(updatesString.toInt() - securityUpdates, securityUpdates); - } else { - //if the format is wrong consider as up to date - setUpdates(0, 0); - } -} - -void ApplicationNotifier::setUpdates(int normal, int security) -{ - if (m_normalUpdates != normal || security != m_securityUpdates) { - m_normalUpdates = normal; - m_securityUpdates = security; - emit foundUpdates(); - } -} - -bool ApplicationNotifier::isSystemUpToDate() const -{ - return (m_securityUpdates+m_normalUpdates)==0; -} - -uint ApplicationNotifier::securityUpdatesCount() -{ - return m_securityUpdates; -} - -uint ApplicationNotifier::updatesCount() -{ - return m_normalUpdates; -} - -#include "ApplicationNotifier.moc" diff --git a/libdiscover/backends/ApplicationBackend/ApplicationNotifier.h b/libdiscover/backends/ApplicationBackend/ApplicationNotifier.h deleted file mode 100644 index 3b46ac3..0000000 --- a/libdiscover/backends/ApplicationBackend/ApplicationNotifier.h +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************** - * Copyright © 2013 Lukas Appelhans <l.appelhans@gmx.de> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ -#ifndef APPLICATIONNOTIFIER_H -#define APPLICATIONNOTIFIER_H - -#include <BackendNotifierModule.h> -#include <QVariantList> - -class DistUpgradeEvent; -class UpdateEvent; -class QProcess; - -class ApplicationNotifier : public BackendNotifierModule -{ - Q_OBJECT - Q_PLUGIN_METADATA(IID "org.kde.discover.BackendNotifierModule") - Q_INTERFACES(BackendNotifierModule) -public: - explicit ApplicationNotifier(QObject* parent = nullptr); - ~ApplicationNotifier() override; - - bool isSystemUpToDate() const final; - uint securityUpdatesCount() final; - uint updatesCount() final; - -private Q_SLOTS: - void checkUpgradeFinished(int exitStatus); - void distUpgradeEvent(); - void recheckSystemUpdateNeeded() final; - void parseUpdateInfo(); - void upgradeActivated(); - void init(); - -private: - void setUpdates(int normal, int security); - - QProcess *m_checkerProcess; - QProcess *m_updateCheckerProcess; - int m_securityUpdates; - int m_normalUpdates; -}; - -#endif diff --git a/libdiscover/backends/ApplicationBackend/ApplicationUpdates.cpp b/libdiscover/backends/ApplicationBackend/ApplicationUpdates.cpp deleted file mode 100644 index b283473..0000000 --- a/libdiscover/backends/ApplicationBackend/ApplicationUpdates.cpp +++ /dev/null @@ -1,467 +0,0 @@ -/*************************************************************************** - * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "ApplicationUpdates.h" - -// Qt includes -#include <QIcon> -#include <QAction> -#include <QApplication> - -// KDE includes -#include <KProtocolManager> -#include <KMessageBox> -#include <KActionCollection> -#include <KLocalizedString> -#include <KXmlGuiWindow> - -// Own includes -#include <QApt/Transaction> - -#include <ChangesDialog.h> -#include <MuonStrings.h> -#include <QAptActions.h> - -#include "Application.h" -#include "ApplicationBackend.h" - -ApplicationUpdates::ApplicationUpdates(ApplicationBackend* parent) - : AbstractBackendUpdater(parent) - , m_aptBackend(nullptr) - , m_appBackend(parent) - , m_lastRealProgress(0) - , m_eta(0) - , m_progressing(false) -{ - connect(m_appBackend, &ApplicationBackend::fetchingChanged, this, &ApplicationUpdates::fetchingChanged); -} - -bool ApplicationUpdates::hasUpdates() const -{ - return m_appBackend->updatesCount()>0; -} - -qreal ApplicationUpdates::progress() const -{ - return m_lastRealProgress; -} - -long unsigned int ApplicationUpdates::remainingTime() const -{ - return m_eta; -} - -void ApplicationUpdates::setBackend(QApt::Backend* backend) -{ - Q_ASSERT(!m_aptBackend || m_aptBackend==backend); - m_aptBackend = backend; - // FIXME: Debconf support was lost during the port - QApt::FrontendCaps caps = (QApt::FrontendCaps)(QApt::MediumPromptCap | - QApt::ConfigPromptCap | QApt::UntrustedPromptCap); - m_aptBackend->setFrontendCaps(caps); -} - -QList<AbstractResource*> ApplicationUpdates::toUpdate() const -{ - return m_toUpdate; -} - -void ApplicationUpdates::restoreToCleanCache() -{ - if(!m_updatesCache.isEmpty()) - m_aptBackend->restoreCacheState(m_updatesCache); - else { - //this is my best bet for retrieving a clean cache, I'm unsure if there's a better way - m_updatesCache = m_aptBackend->currentCacheState(); - } - Q_ASSERT(m_aptBackend->markedPackages().isEmpty()); -} - -void ApplicationUpdates::prepare() -{ - restoreToCleanCache(); - - m_aptBackend->markPackagesForDistUpgrade(); - calculateUpdates(); -} - -void ApplicationUpdates::start() -{ - Q_ASSERT(!m_updatesCache.isEmpty()); - auto changes = m_aptBackend->stateChanges(m_updatesCache, QApt::PackageList()); - if(changes.isEmpty()) { - qWarning() << "couldn't find any apt updates"; - setProgressing(false); - return; - } - for(auto it=changes.begin(); it!=changes.end(); ) { - if(it.key()&QApt::Package::ToUpgrade) { - it = changes.erase(it); - } else { - ++it; - } - } - // Confirm additional changes beyond upgrading the files - if(!changes.isEmpty()) { - ChangesDialog d(m_appBackend->mainWindow(), changes); - if(d.exec()==QDialog::Rejected) { - setProgressing(false); - return; - } - } - - // Create and run the transaction - setupTransaction(m_aptBackend->commitChanges()); - m_trans->run(); - setProgressing(true); -} - -void ApplicationUpdates::addResources(const QList<AbstractResource*>& apps) -{ - if (apps.size() > 1) { - QApplication::setOverrideCursor(Qt::WaitCursor); - } - QList<QApt::Package*> packages; - foreach(AbstractResource* res, apps) { - Application* app = qobject_cast<Application*>(res); - Q_ASSERT(app); - packages += app->package(); - } - m_aptBackend->markPackages(packages, QApt::Package::ToInstall); - QApplication::restoreOverrideCursor(); -} - -void ApplicationUpdates::removeResources(const QList<AbstractResource*>& apps) -{ - QList<QApt::Package*> packages; - foreach(AbstractResource* res, apps) { - Application* app = qobject_cast<Application*>(res); - Q_ASSERT(app); - packages += app->package(); - } - m_aptBackend->markPackages(packages, QApt::Package::ToKeep); -} - -void ApplicationUpdates::setProgress(int progress) -{ - if (progress > 100) - return; - - if (progress > m_lastRealProgress || progress<0) { - m_lastRealProgress = progress; - emit progressChanged((qreal)progress); - } -} - -void ApplicationUpdates::etaChanged(quint64 eta) -{ - if(m_eta != eta) { - m_eta = eta; - emit remainingTimeChanged(); - } -} - -void ApplicationUpdates::installMessage(const QString& msg) -{ - setStatusMessage(msg); -} - -void ApplicationUpdates::errorOccurred(QApt::ErrorCode error) -{ - if(error!=QApt::Success) { - QAptActions::self()->displayTransactionError(error, m_trans); - setProgressing(false); - } -} - -void ApplicationUpdates::setupTransaction(QApt::Transaction *trans) -{ - Q_ASSERT(trans); - m_trans = trans; - - // Provide proxy/locale to the transaction - if (KProtocolManager::proxyType() == KProtocolManager::ManualProxy) { - trans->setProxy(KProtocolManager::proxyFor(QStringLiteral("http"))); - } - - trans->setLocale(QLatin1String(setlocale(LC_MESSAGES, nullptr))); - - connect(trans, SIGNAL(errorOccurred(QApt::ErrorCode)), - SLOT(errorOccurred(QApt::ErrorCode))); - connect(trans, SIGNAL(progressChanged(int)), SLOT(setProgress(int))); - connect(trans, SIGNAL(statusDetailsChanged(QString)), SLOT(installMessage(QString))); - connect(trans, SIGNAL(cancellableChanged(bool)), SIGNAL(cancelableChanged(bool))); - connect(trans, SIGNAL(finished(QApt::ExitStatus)), trans, SLOT(deleteLater())); - connect(trans, SIGNAL(statusChanged(QApt::TransactionStatus)), - this, SLOT(statusChanged(QApt::TransactionStatus))); - connect(trans, SIGNAL(mediumRequired(QString,QString)), - this, SLOT(provideMedium(QString,QString))); - connect(trans, SIGNAL(promptUntrusted(QStringList)), - this, SLOT(untrustedPrompt(QStringList))); - connect(trans, SIGNAL(configFileConflict(QString,QString)), - this, SLOT(configFileConflict(QString,QString))); - connect(trans, SIGNAL(downloadSpeedChanged(quint64)), - this, SIGNAL(downloadSpeedChanged(quint64))); - connect(trans, SIGNAL(finished(QApt::ExitStatus)), - this, SLOT(transactionFinished(QApt::ExitStatus))); -} - -void ApplicationUpdates::transactionFinished(QApt::ExitStatus ) -{ - m_lastRealProgress = 0; - m_updatesCache.clear(); - m_toUpdate.clear(); - m_appBackend->reload(); - setProgressing(false); -} - - -QDateTime ApplicationUpdates::lastUpdate() const -{ - return m_aptBackend->timeCacheLastUpdated(); -} - -bool ApplicationUpdates::isCancelable() const -{ - return m_trans && m_trans->isCancellable(); -} - -bool ApplicationUpdates::isProgressing() const -{ - return m_progressing; -} - -void ApplicationUpdates::provideMedium(const QString &label, const QString &medium) -{ - QString title = i18nc("@title:window", "Media Change Required"); - QString text = xi18nc("@label", "Please insert %1 into <filename>%2</filename>", - label, medium); - - KMessageBox::information(QAptActions::self()->mainWindow(), text, title); - m_trans->provideMedium(medium); -} - -void ApplicationUpdates::untrustedPrompt(const QStringList &untrustedPackages) -{ - QString title = i18nc("@title:window", "Warning - Unverified Software"); - QString text = xi18ncp("@label", - "The following piece of software cannot be verified. " - "<warning>Installing unverified software represents a " - "security risk, as the presence of unverifiable software " - "can be a sign of tampering.</warning> Do you wish to continue?", - "The following pieces of software cannot be verified. " - "<warning>Installing unverified software represents a " - "security risk, as the presence of unverifiable software " - "can be a sign of tampering.</warning> Do you wish to continue?", - untrustedPackages.size()); - int result = KMessageBox::warningContinueCancelList(QAptActions::self()->mainWindow(), - text, untrustedPackages, title); - - bool installUntrusted = (result == KMessageBox::Continue); - m_trans->replyUntrustedPrompt(installUntrusted); -} - -void ApplicationUpdates::configFileConflict(const QString ¤tPath, const QString &newPath) -{ - QString title = i18nc("@title:window", "Configuration File Changed"); - QString text = xi18nc("@label Notifies a config file change", - "A new version of the configuration file " - "<filename>%1</filename> is available, but your version has " - "been modified. Would you like to keep your current version " - "or install the new version?", currentPath); - - KGuiItem useNew(i18nc("@action Use the new config file", "Use New Version")); - KGuiItem useOld(i18nc("@action Keep the old config file", "Keep Old Version")); - - // TODO: diff current and new paths - Q_UNUSED(newPath) - - int ret = KMessageBox::questionYesNo(QAptActions::self()->mainWindow(), text, title, useNew, useOld); - - m_trans->resolveConfigFileConflict(currentPath, (ret == KMessageBox::Yes)); -} - -void ApplicationUpdates::statusChanged(QApt::TransactionStatus status) -{ - switch (status) { - case QApt::SetupStatus: - setProgressing(true); - setStatusMessage(i18nc("@info Status info, widget title", - "Starting")); - setProgress(-1); - break; - case QApt::AuthenticationStatus: - setStatusMessage(i18nc("@info Status info, widget title", - "Waiting for Authentication")); - setProgress(-1); - break; - case QApt::WaitingStatus: - setStatusMessage(i18nc("@info Status information, widget title", - "Waiting")); - setStatusDetail(i18nc("@info Status info", - "Waiting for other transactions to finish")); - setProgress(-1); - break; - case QApt::WaitingLockStatus: - setStatusMessage(i18nc("@info Status information, widget title", - "Waiting")); - setStatusDetail(i18nc("@info Status info", - "Waiting for other software managers to quit")); - setProgress(-1); - break; - case QApt::WaitingMediumStatus: - setStatusMessage(i18nc("@info Status information, widget title", - "Waiting")); - setStatusDetail(i18nc("@info Status info", - "Waiting for required medium")); - setProgress(-1); - break; - case QApt::WaitingConfigFilePromptStatus: - setStatusMessage(i18nc("@info Status information, widget title", - "Waiting")); - setStatusDetail(i18nc("@info Status info", - "Waiting for configuration file")); - setProgress(-1); - break; - case QApt::RunningStatus: - setStatusMessage(QString()); - setStatusDetail(QString()); - break; - case QApt::LoadingCacheStatus: - setStatusDetail(QString()); - setStatusMessage(i18nc("@info Status info", - "Loading Software List")); - break; - case QApt::DownloadingStatus: - switch (m_trans->role()) { - case QApt::UpdateCacheRole: - setStatusMessage(i18nc("@info Status information, widget title", - "Updating software sources")); - break; - case QApt::DownloadArchivesRole: - case QApt::CommitChangesRole: - setStatusMessage(i18nc("@info Status information, widget title", - "Downloading Packages")); - break; - default: - break; - } - break; - case QApt::CommittingStatus: - emit downloadSpeedChanged(-1); - setStatusMessage(i18nc("@info Status information, widget title", - "Applying Changes")); - setStatusDetail(QString()); - break; - case QApt::FinishedStatus: - setProgress(100); - setStatusMessage(i18nc("@info Status information, widget title", - "Finished")); - break; - } -} - -void ApplicationUpdates::setProgressing(bool progressing) -{ - if(progressing!=m_progressing) { - m_progressing = progressing; - emit progressingChanged(progressing); - - if(m_progressing) - setProgress(-1); - else - restoreToCleanCache(); - } -} - -void ApplicationUpdates::setStatusDetail(const QString& msg) -{ - if(m_statusDetail!=msg) { - m_statusDetail = msg; - emit statusDetailChanged(msg); - } -} - -void ApplicationUpdates::setStatusMessage(const QString& msg) -{ - if(m_statusMessage!=msg) { - m_statusMessage = msg; - emit statusMessageChanged(msg); - } -} - -QString ApplicationUpdates::statusDetail() const -{ - return m_statusDetail; -} - -QString ApplicationUpdates::statusMessage() const -{ - return m_statusMessage; -} - -void ApplicationUpdates::cancel() -{ - Q_ASSERT(m_trans->isCancellable()); - m_trans->cancel(); -} - -quint64 ApplicationUpdates::downloadSpeed() const -{ - return m_trans->downloadSpeed(); -} - -void ApplicationUpdates::fetchingChanged() -{ - if(m_appBackend && m_appBackend->isFetching()) - return; - - calculateUpdates(); - setProgressing(false); -} - -void ApplicationUpdates::calculateUpdates() -{ - m_toUpdate.clear(); - auto changes = m_aptBackend->stateChanges(m_updatesCache, QApt::PackageList()); - Q_FOREACH (const auto &pkgList, changes) { - Q_FOREACH (QApt::Package* it, pkgList) { - AbstractResource* res = m_appBackend->resourceByPackageName(it->name()); - if(!res) //If we couldn't find it by its name, try with - res = m_appBackend->resourceByPackageName(QStringLiteral("%1:%2").arg(it->name()).arg(it->architecture())); - - if(res) { - if (res->state() == Application::Upgradeable) - m_toUpdate += res; - } else { - qWarning() << "Couldn't find the package:" << it->name(); - } - Q_ASSERT(res); - } - } -} - -bool ApplicationUpdates::isMarked(AbstractResource* res) const -{ - Q_ASSERT(!res->backend()->isFetching()); - Application* app = qobject_cast<Application*>(res); - Q_ASSERT(app); - return app->package()->state() & QApt::Package::ToInstall; -} diff --git a/libdiscover/backends/ApplicationBackend/ApplicationUpdates.h b/libdiscover/backends/ApplicationBackend/ApplicationUpdates.h deleted file mode 100644 index e30b8a4..0000000 --- a/libdiscover/backends/ApplicationBackend/ApplicationUpdates.h +++ /dev/null @@ -1,97 +0,0 @@ -/*************************************************************************** - * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef APPLICATIONUPDATES_H -#define APPLICATIONUPDATES_H - -// Qt includes -#include <QtCore/QObject> -#include <QPointer> - -// QApt includes -#include <QApt/Globals> - -// Own includes -#include "resources/AbstractBackendUpdater.h" - -namespace QApt { - class Backend; - class Transaction; -} - -class ApplicationBackend; - -class ApplicationUpdates : public AbstractBackendUpdater -{ - Q_OBJECT -public: - explicit ApplicationUpdates(ApplicationBackend* parent); - - bool hasUpdates() const override; - qreal progress() const override; - void start() override; - void setBackend(QApt::Backend* backend); - long unsigned int remainingTime() const override; - void addResources(const QList<AbstractResource*>& apps) override; - void removeResources(const QList<AbstractResource*>& apps) override; - QList<AbstractResource*> toUpdate() const override; - QDateTime lastUpdate() const override; - bool isCancelable() const override; - bool isProgressing() const override; - QString statusDetail() const override; - QString statusMessage() const override; - void cancel() override; - quint64 downloadSpeed() const override; - void prepare() override; - void setupTransaction(QApt::Transaction *trans); - bool isMarked(AbstractResource* res) const override; - void setProgressing(bool progressing); - -private: - void restoreToCleanCache(); - - QPointer<QApt::Transaction> m_trans; - QApt::Backend* m_aptBackend; - ApplicationBackend* m_appBackend; - int m_lastRealProgress; - long unsigned int m_eta; - QApt::CacheState m_updatesCache; - bool m_progressing; - QString m_statusMessage; - QString m_statusDetail; - QList<AbstractResource*> m_toUpdate; - -private Q_SLOTS: - void errorOccurred(QApt::ErrorCode error); - void setProgress(int progress); - void etaChanged(quint64 eta); - void installMessage(const QString& message); - void provideMedium(const QString &label, const QString &medium); - void untrustedPrompt(const QStringList &untrustedPackages); - void configFileConflict(const QString ¤tPath, const QString &newPath); - void statusChanged(QApt::TransactionStatus status); - void setStatusMessage(const QString& msg); - void setStatusDetail(const QString& msg); - void fetchingChanged(); - void calculateUpdates(); - void transactionFinished(QApt::ExitStatus); -}; - -#endif // APPLICATIONUPDATES_H diff --git a/libdiscover/backends/ApplicationBackend/AptSourcesBackend.cpp b/libdiscover/backends/ApplicationBackend/AptSourcesBackend.cpp deleted file mode 100644 index 067a69a..0000000 --- a/libdiscover/backends/ApplicationBackend/AptSourcesBackend.cpp +++ /dev/null @@ -1,244 +0,0 @@ -/*************************************************************************** - * Copyright © 2014 Aleix Pol Gonzalez <aleixpol@blue-systems.com> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "AptSourcesBackend.h" -#include "ApplicationBackend.h" -#include <QAptActions.h> -#include <qapt/sourceentry.h> -#include <kauthexecutejob.h> -#include <KActionCollection> -#include <KLocalizedString> -#include <KMessageWidget> -#include <KMessageBox> -#include <QProcess> - -class EntryItem : public QStandardItem -{ -public: - explicit EntryItem(const QApt::SourceEntry &sEntry) - : m_sEntry(sEntry) - {} - QApt::SourceEntry& sourceEntry() { return m_sEntry; } - -private: - QApt::SourceEntry m_sEntry; -}; - -class SourceItem : public QStandardItem -{ -public: - explicit SourceItem(QUrl uri) - : m_uri(std::move(uri)) - {} - - QVariant data(int role = Qt::UserRole + 1) const override; - QUrl uri() const { return m_uri; } - -private: - QUrl m_uri; -}; - -AptSourcesBackend::AptSourcesBackend(ApplicationBackend* backend) - : AbstractSourcesBackend(backend) - , m_sources(new QStandardItemModel(this)) -{ - connect(backend, SIGNAL(fetchingChanged()), SLOT(load()), Qt::UniqueConnection); - if (!backend->isFetching()) { - load(); - } -} - -void AptSourcesBackend::load() -{ - m_sources->clear(); - - Q_FOREACH (const QApt::SourceEntry &sEntry, m_sourcesList.entries()) { - if (!sEntry.isValid()) { - continue; -} - - SourceItem* newSource = sourceForUri(sEntry.uri()); - auto entry = new EntryItem(sEntry); - newSource->appendRow(entry); - } -} - -SourceItem* AptSourcesBackend::sourceForUri(const QString& uri) -{ - QUrl uriUrl(uri); - - for(int r = 0, c = m_sources->rowCount(); r<c; ++r) { - SourceItem* s = static_cast<SourceItem*>(m_sources->item(r)); - if(s->uri()==uriUrl) - return s; - } - SourceItem* s = new SourceItem(uriUrl); - s->setData(uriUrl, UriRole); - m_sources->appendRow(s); - return s; -} - -QAbstractItemModel* AptSourcesBackend::sources() -{ - return m_sources; -} - -bool AptSourcesBackend::removeSource(const QString& repository) -{ - KAuth::Action readAction(QStringLiteral("org.kde.discover.repo.modify")); - readAction.setHelperId(QStringLiteral("org.kde.discover.repo")); - QVariantMap args = { - { QStringLiteral("repository"), repository }, - { QStringLiteral("action"), QStringLiteral("remove") } - }; - readAction.setArguments(args); - qDebug() << "removing..." << args; - KAuth::ExecuteJob* reply = readAction.execute(); - removalDone(reply->error()); - return true; -} - -bool AptSourcesBackend::addSource(const QString& repository) -{ - KAuth::Action readAction(QStringLiteral("org.kde.discover.repo.modify")); - readAction.setHelperId(QStringLiteral("org.kde.discover.repo")); - QVariantMap args = { - { QStringLiteral("repository"), repository }, - { QStringLiteral("action"), QStringLiteral("add") } - }; - readAction.setArguments(args); - qDebug() << "adding..." << args; - KAuth::ExecuteJob* reply = readAction.execute(); - additionDone(reply->error()); - return true; -} - -void AptSourcesBackend::additionDone(int processErrorCode) -{ - if(processErrorCode==0) { - load(); - QMetaObject::invokeMethod(appsBackend(), "reload"); - } else { - QProcess* p = qobject_cast<QProcess*>(sender()); - Q_ASSERT(p); - QByteArray errorMessage = p->readAllStandardOutput(); - if(!errorMessage.isEmpty()) - KMessageBox::error(0, QString::fromUtf8(errorMessage), i18n("Adding Origins...")); - } -} - -void AptSourcesBackend::removalDone(int processErrorCode) -{ - if(processErrorCode==0) { - load(); - QMetaObject::invokeMethod(appsBackend(), "reload"); - } else { - QProcess* p = qobject_cast<QProcess*>(sender()); - Q_ASSERT(p); - QByteArray errorMessage = p->readAllStandardOutput(); - if(!errorMessage.isEmpty()) - KMessageBox::error(0, QString::fromUtf8(errorMessage), i18n("Removing Origins...")); - } -} - -ApplicationBackend* AptSourcesBackend::appsBackend() const -{ - return qobject_cast<ApplicationBackend*>(parent()); -} - -QVariant SourceItem::data(int role) const -{ - switch(role) { - case Qt::DisplayRole: { -// modelData.name=="" ? modelData.uri : i18n("%1. %2", modelData.name, modelData.uri) - QApt::Backend* backend = qobject_cast<AptSourcesBackend*>(model()->parent())->appsBackend()->backend(); - QStringList origins = !m_uri.host().isEmpty() ? backend->originsForHost(m_uri.host()) : QStringList(); - - if(origins.size()==1) - return origins.first(); - else if(origins.size()==0) - return m_uri.toDisplayString(); - else { - QString path = m_uri.path(); - int firstSlash = path.indexOf(QLatin1Char('/'), 1); - int secondSlash = path.indexOf(QLatin1Char('/'), firstSlash+1); - QString launchpadifyUri = path.mid(1,secondSlash-1).replace(QLatin1Char('/'), QLatin1Char('-')); - QStringList results = origins.filter(launchpadifyUri, Qt::CaseInsensitive); - if(results.isEmpty()) { - launchpadifyUri = path.mid(1,firstSlash-1).replace(QLatin1Char('/'), QLatin1Char('-')); - results = origins.filter(launchpadifyUri, Qt::CaseInsensitive); - } - return results.isEmpty() ? QString() : results.first(); - } - } - case Qt::ToolTipRole: { - QMap<QString, int> vals; - for(int i=0, c=rowCount(); i<c; ++i) { - EntryItem* entry = static_cast<EntryItem*>(child(i)); - - QString suite = entry->sourceEntry().dist(); - if(!vals.contains(suite)) - vals[suite]=0; - - bool hasSource = entry->sourceEntry().type() == QLatin1String("deb-src"); - if(hasSource) - vals[suite] += 2; - else - vals[suite] += 1; - } - QStringList ret; - Q_FOREACH (const QString& e, vals.keys()) { - if(vals[e]>1) - ret.append(e); - else - ret.append(i18n("%1 (Binary)", e)); - } - - return ret.join(QStringLiteral(", ")); - } - default: - return QStandardItem::data(role); - } -} - -QString AptSourcesBackend::idDescription() -{ - return i18n( "<sourceline> - The apt repository source line to add. This is one of:\n" - " a complete apt line, \n" - " a repo url and areas (areas defaults to 'main')\n" - " a PPA shortcut.\n\n" - - " Examples:\n" - " deb http://myserver/path/to/repo stable myrepo\n" - " http://myserver/path/to/repo myrepo\n" - " https://packages.medibuntu.org free non-free\n" - " http://extras.ubuntu.com/ubuntu\n" - " ppa:user/repository"); -} - -QString AptSourcesBackend::name() const -{ - return i18n("Software Management"); -} - -QList<QAction*> AptSourcesBackend::actions() const -{ - return { QAptActions::self()->actionCollection()->action(QStringLiteral("software_properties")) }; -} diff --git a/libdiscover/backends/ApplicationBackend/AptSourcesBackend.h b/libdiscover/backends/ApplicationBackend/AptSourcesBackend.h deleted file mode 100644 index b7dcc82..0000000 --- a/libdiscover/backends/ApplicationBackend/AptSourcesBackend.h +++ /dev/null @@ -1,60 +0,0 @@ -/*************************************************************************** - * Copyright © 2014 Aleix Pol Gonzalez <aleixpol@blue-systems.com> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef APTSOURCESBACKEND_H -#define APTSOURCESBACKEND_H - -#include <QStandardItemModel> -#include <resources/AbstractSourcesBackend.h> -#include <QApt/SourcesList> - -class ApplicationBackend; -class SourceItem; - -class AptSourcesBackend : public AbstractSourcesBackend -{ -Q_OBJECT -public: - enum Roles { - UriRole - }; - - explicit AptSourcesBackend(ApplicationBackend* backend); - QAbstractItemModel* sources() override; - bool removeSource(const QString& repository) override; - bool addSource(const QString& repository) override; - QString idDescription() override; - QString name() const override; - ApplicationBackend* appsBackend() const; - QList<QAction*> actions() const override; - -private Q_SLOTS: - void load(); - void removalDone(int processErrorCode); - void additionDone(int processErrorCode); - -private: - SourceItem* sourceForUri(const QString& uri); - - QStandardItemModel* m_sources; - QApt::SourcesList m_sourcesList; -}; - -#endif // APTSOURCESBACKEND_H diff --git a/libdiscover/backends/ApplicationBackend/CMakeLists.txt b/libdiscover/backends/ApplicationBackend/CMakeLists.txt deleted file mode 100644 index cc7b35f..0000000 --- a/libdiscover/backends/ApplicationBackend/CMakeLists.txt +++ /dev/null @@ -1,53 +0,0 @@ -# we will have our own fork of the library now, because they haven't still made their mind out of Qt5 -# find_package(QtOAuth REQUIRED) -add_subdirectory(qoauth) -add_subdirectory(libmuonapt) - -include_directories(.) - -add_subdirectory(tests) - -set(appsbackend_SRCS - ApplicationBackend.cpp - Application.cpp - ApplicationUpdates.cpp - ReviewsBackend.cpp #TODO: rename to AptReviewsBackend - UbuntuLoginBackend.cpp - AptSourcesBackend.cpp -) - -qt5_add_dbus_interface(appsbackend_SRCS ubuntu_sso_dbus_interface.xml ubuntu_sso OPTIONS -i "LoginMetaTypes.h") - -add_library(qapt-backend MODULE ${appsbackend_SRCS}) -target_link_libraries(qapt-backend Qt5::Widgets Qt5::DBus Qt5::Concurrent - KF5::Archive KF5::KIOWidgets KF5::XmlGui DebconfKDE::Main KF5::IconThemes AppstreamQt - Muon::QOAuth QApt::Main Discover::Common MuonApt -) -target_include_directories(qapt-backend PRIVATE /usr/include/Qca-qt5/QtCrypto) - -install(TARGETS qapt-backend DESTINATION ${PLUGIN_INSTALL_DIR}/discover) -install(FILES qapt-backend.desktop DESTINATION ${DATA_INSTALL_DIR}/libdiscover/backends) -install(FILES distupgradeevent/releasechecker DESTINATION ${DATA_INSTALL_DIR}/libdiscover/applicationsbackend/ - PERMISSIONS - OWNER_EXECUTE OWNER_READ OWNER_WRITE - GROUP_EXECUTE GROUP_READ - WORLD_EXECUTE WORLD_READ -) - -foreach(testing IN ITEMS ON OFF) - set(name MuonApplicationNotifier) - set(type MODULE) - if(${testing}) - set(name MuonApplicationNotifierTestLib) - set(type STATIC) - endif() - add_library(${name} ${type} ApplicationNotifier.cpp) - target_compile_definitions(${name} PRIVATE -DCMAKE_INSTALL_FULL_LIBEXECDIR_KF5=\"${CMAKE_INSTALL_FULL_LIBEXECDIR_KF5}\") - target_link_libraries(${name} KF5::CoreAddons KF5::I18n KF5::Notifications KF5::IconThemes Discover::Notifiers) -endforeach() - -install(TARGETS MuonApplicationNotifier DESTINATION ${PLUGIN_INSTALL_DIR}/discover-notifier) -install(FILES muonapplicationnotifier.notifyrc DESTINATION ${KNOTIFYRC_INSTALL_DIR}) - -install(FILES ../PackageKitBackend/packagekit-backend-categories.xml DESTINATION ${DATA_INSTALL_DIR}/libdiscover/categories/ RENAME qapt-backend-categories.xml) -# add_subdirectory(${CMAKE_SOURCE_DIR}/libdiscover/backends/PackageKitBackend/categoryimages) diff --git a/libdiscover/backends/ApplicationBackend/ReviewsBackend.cpp b/libdiscover/backends/ApplicationBackend/ReviewsBackend.cpp deleted file mode 100644 index ae97868..0000000 --- a/libdiscover/backends/ApplicationBackend/ReviewsBackend.cpp +++ /dev/null @@ -1,411 +0,0 @@ -/*************************************************************************** - * Copyright © 2011 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "ReviewsBackend.h" - -#include <QtCore/QStringBuilder> -#include <QtCore/QLocale> -#include <QDebug> -#include <QJsonDocument> -#include <QTemporaryFile> -#include <QStandardPaths> -#include <QFileInfo> -#include <QDir> - -#include <KIO/Job> -#include <KLocalizedString> -#include <KCompressionDevice> - -#include <QApt/Backend> - -#include <qoauth/src/interface.h> - -#include <Application.h> -#include <ReviewsBackend/Rating.h> -#include <ReviewsBackend/Review.h> -#include <ReviewsBackend/AbstractLoginBackend.h> -#include <ReviewsBackend/PopConParser.h> -#include "UbuntuLoginBackend.h" -#include <resources/AbstractResourcesBackend.h> -#include <MuonDataSources.h> - -static QString getCodename(const QString& value) -{ - QString ret; - QFile f(QStringLiteral("/etc/os-release")); - if(f.open(QIODevice::ReadOnly|QIODevice::Text)) { - QRegExp rx(QStringLiteral("%1=(.+)\n").arg(value)); - while(!f.atEnd()) { - QString line = QString::fromLatin1(f.readLine()); - if(rx.exactMatch(line)) { - ret = rx.cap(1); - break; - } - } - } - return ret; -} - -ReviewsBackend::ReviewsBackend(QObject *parent) - : AbstractReviewsBackend(parent) - , m_aptBackend(nullptr) - , m_serverBase(MuonDataSources::rnRSource()) -{ - m_distId = getCodename(QStringLiteral("ID")); - m_loginBackend = new UbuntuLoginBackend(this); - connect(m_loginBackend, &AbstractLoginBackend::connectionStateChanged, this, &ReviewsBackend::loginStateChanged); - connect(m_loginBackend, &AbstractLoginBackend::connectionStateChanged, this, &ReviewsBackend::refreshConsumerKeys); - m_oauthInterface = new QOAuth::Interface(this); - - QMetaObject::invokeMethod(this, "fetchRatings", Qt::QueuedConnection); -} - -ReviewsBackend::~ReviewsBackend() = default; - -void ReviewsBackend::refreshConsumerKeys() -{ - if(m_loginBackend->hasCredentials()) { - m_oauthInterface->setConsumerKey(m_loginBackend->consumerKey()); - m_oauthInterface->setConsumerSecret(m_loginBackend->consumerSecret()); - - QList<QPair<QString, QVariantMap> >::const_iterator it, itEnd; - for(it=m_pendingRequests.constBegin(), itEnd=m_pendingRequests.constEnd(); it!=itEnd; ++it) { - postInformation(it->first, it->second); - } - m_pendingRequests.clear(); - } -} - -void ReviewsBackend::setAptBackend(QApt::Backend *aptBackend) -{ - m_aptBackend = aptBackend; -} - -// void ReviewsBackend::clearReviewCache() -// { -// foreach (QList<Review *> reviewList, m_reviewsCache) { -// qDeleteAll(reviewList); -// } -// -// m_reviewsCache.clear(); -// } - -void ReviewsBackend::fetchRatings() -{ - QString ratingsCache = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QStringLiteral("/libdiscover/ratings.txt"); - QFileInfo file(ratingsCache); - QDir::temp().mkpath(file.dir().path()); - QUrl ratingsUrl(m_serverBase.toString()+QStringLiteral("review-stats/")); - //default to popcon if not using ubuntu - if(m_distId.toLower() == QLatin1String("ubuntu")){ - refreshConsumerKeys(); - // First, load our old ratings cache in case we don't have net connectivity - loadRatingsFromFile(); - // Try to fetch the latest ratings from the internet - } else { - ratingsUrl = QUrl(QStringLiteral("http://popcon.debian.org/all-popcon-results.gz")); - } - KIO::FileCopyJob *getJob = KIO::file_copy(ratingsUrl, QUrl::fromLocalFile(ratingsCache), -1, - KIO::Overwrite | KIO::HideProgressInfo); - connect(getJob, &KIO::FileCopyJob::result, this, &ReviewsBackend::ratingsFetched); -} - -void ReviewsBackend::ratingsFetched(KJob *job) -{ - if (job->error()) { - qWarning() << "Couldn't fetch the ratings" << job->errorString(); - return; - } - - loadRatingsFromFile(); -} - -void ReviewsBackend::loadRatingsFromFile() -{ - QString ratingsCache = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+QStringLiteral("/libdiscover/ratings.txt"); - QScopedPointer<QIODevice> dev(new KCompressionDevice(ratingsCache, KCompressionDevice::GZip)); - if (!dev->open(QIODevice::ReadOnly)) { - qWarning() << "Couldn't open ratings.txt" << ratingsCache; - return; - } - if(m_distId.toLower() == QLatin1String("ubuntu")) { - QJsonParseError error; - QJsonDocument doc = QJsonDocument::fromJson(dev->readAll(), &error); - - if (error.error != QJsonParseError::NoError) { - qDebug() << "error while parsing ratings: " << ratingsCache; - return; - } - - QVariant ratings = doc.toVariant(); - qDeleteAll(m_ratings); - m_ratings.clear(); - foreach (const QVariant &data, ratings.toList()) { - Rating *rating = new Rating(data.toMap()); - if (rating->ratingCount() == 0u) { - delete rating; - continue; - } - rating->setParent(this); - m_ratings[rating->packageName()] = rating; - } - } else { - qDeleteAll(m_ratings); - m_ratings = PopConParser::parsePopcon(this, dev.data()); - } - emit ratingsReady(); -} - -Rating *ReviewsBackend::ratingForApplication(AbstractResource* app) const -{ - return m_ratings.value(app->packageName()); -} - -void ReviewsBackend::stopPendingJobs() -{ - for(auto it = m_jobHash.constBegin(); it != m_jobHash.constEnd(); ++it) { - disconnect(it.key(), SIGNAL(result(KJob*)), this, SLOT(changelogFetched(KJob*))); - } - m_jobHash.clear(); -} - -void ReviewsBackend::fetchReviews(AbstractResource* res, int page) -{ - Q_ASSERT(!res->backend()->isFetching()); - Application* app = qobject_cast<Application*>(res); - - const QList<Review*> revs = m_reviewsCache.value(app); - if (revs.size()>(page*10)) { //there are 10 reviews per page - emit reviewsReady(app, revs.mid(page*10, 10)); - return; - } - - QString lang = getLanguage(); - QString origin = app->package()->origin().toLower(); - - QString version = QLatin1String("any"); - QString packageName = app->package()->name(); - QString appName = app->name(); - // Replace spaces with %2B for the url - appName.replace(QLatin1Char(' '), QLatin1String("%2B")); - - // Figuring out how this damn Django url was put together took more - // time than figuring out QJson... - // But that could be because the Ubuntu Software Center (which I used to - // figure it out) is written in python, so you have to go hunting to where - // a variable was initially initialized with a primitive to figure out its type. - QUrl reviewsUrl(m_serverBase.toString() + QLatin1String("/reviews/filter/") % lang % QLatin1Char('/') - % origin % QLatin1Char('/') % QLatin1String("any") % QLatin1Char('/') % version % QLatin1Char('/') % packageName - % QLatin1Char(';') % appName % QLatin1String("/page/") % QString::number(page)); - - KIO::StoredTransferJob* getJob = KIO::storedGet(reviewsUrl, KIO::NoReload, KIO::Overwrite | KIO::HideProgressInfo); - m_jobHash[getJob] = app; - connect(getJob, &KIO::StoredTransferJob::result, this, &ReviewsBackend::reviewsFetched); -} - -static Review* constructReview(const QVariantMap& data) -{ - QString reviewUsername = data.value(QStringLiteral("reviewer_username")).toString(); - QString reviewDisplayName = data.value(QStringLiteral("reviewer_displayname")).toString(); - QString reviewer = reviewDisplayName.isEmpty() ? reviewUsername : reviewDisplayName; - return new Review( - data.value(QStringLiteral("app_name")).toString(), - data.value(QStringLiteral("package_name")).toString(), - data.value(QStringLiteral("language")).toString(), - data.value(QStringLiteral("summary")).toString(), - data.value(QStringLiteral("review_text")).toString(), - reviewer, - QDateTime::fromString(data.value(QStringLiteral("date_created")).toString(), QStringLiteral("yyyy-MM-dd HH:mm:ss")), - !data.value(QStringLiteral("hide")).toBool(), - data.value(QStringLiteral("id")).toULongLong(), - data.value(QStringLiteral("rating")).toInt() * 2, - data.value(QStringLiteral("usefulness_total")).toInt(), - data.value(QStringLiteral("usefulness_favorable")).toInt(), - data.value(QStringLiteral("version")).toString()); -} - -void ReviewsBackend::reviewsFetched(KJob *j) -{ - KIO::StoredTransferJob* job = qobject_cast<KIO::StoredTransferJob*>(j); - Application *app = m_jobHash.take(job); - if (job->error() || !app) { - return; - } - - QJsonParseError error; - QJsonDocument doc = QJsonDocument::fromJson(job->data(), &error); - - if (error.error != QJsonParseError::NoError) { - return; - } - QVariant reviews = doc.toVariant(); - - QList<Review *> reviewsList; - foreach (const QVariant &data, reviews.toList()) { - reviewsList << constructReview(data.toMap()); - } - - m_reviewsCache[app].append(reviewsList); - - emit reviewsReady(app, reviewsList); -} - -QString ReviewsBackend::getLanguage() -{ - // The reviews API abbreviates all langs past the _ char except these - const QStringList fullLangs = { QStringLiteral("pt_BR"), QStringLiteral("zh_CN"), QStringLiteral("zh_TW") }; - - QString language = QLocale().bcp47Name(); - - if (fullLangs.contains(language)) { - return language; - } - - return language.split(QLatin1Char('_')).first(); -} - -void ReviewsBackend::submitUsefulness(Review* r, bool useful) -{ - QVariantMap data = { { QStringLiteral("useful"), useful } }; - - postInformation(QStringLiteral("reviews/%1/recommendations/").arg(r->id()), data); -} - -void ReviewsBackend::submitReview(AbstractResource* application, const QString& summary, - const QString& review_text, const QString& rating) -{ - Application* app = qobject_cast<Application*>(application); - - QVariantMap data = { - { QStringLiteral("app_name"), app->name() }, - { QStringLiteral("package_name"), app->packageName() }, - { QStringLiteral("summary"), summary }, - { QStringLiteral("version"), app->package()->version() }, - { QStringLiteral("review_text"), review_text }, - { QStringLiteral("rating"), rating }, - { QStringLiteral("language"), getLanguage() }, - { QStringLiteral("origin"), app->package()->origin() } - }; - - QString distroSeries = getCodename(QStringLiteral("VERSION")); - if(!distroSeries.isEmpty()){ - data[QStringLiteral("distroseries")] = distroSeries.split(QLatin1Char(' ')).last().remove(QLatin1Char('(')).remove(QLatin1Char(')')); - }else{ - data[QStringLiteral("distroseries")] = getCodename(QStringLiteral("PRETTY_NAME")).split(QLatin1Char(' ')).last(); - } - data[QStringLiteral("arch_tag")] = app->package()->architecture(); - - postInformation(QStringLiteral("reviews/"), data); -} - -void ReviewsBackend::deleteReview(Review* r) -{ - postInformation(QStringLiteral("reviews/delete/%1/").arg(r->id()), QVariantMap()); -} - -void ReviewsBackend::flagReview(Review* r, const QString& reason, const QString& text) -{ - QVariantMap data = { - { QStringLiteral("reason"), reason }, - { QStringLiteral("text"), text } - }; - - postInformation(QStringLiteral("reviews/%1/flags/").arg(r->id()), data); -} - -QByteArray authorization(QOAuth::Interface* oauth, const QUrl& url, AbstractLoginBackend* login) -{ - return oauth->createParametersString(url.url(), QOAuth::POST, login->token(), login->tokenSecret(), - QOAuth::HMAC_SHA1, QOAuth::ParamMap(), QOAuth::ParseForHeaderArguments); -} - -void ReviewsBackend::postInformation(const QString& path, const QVariantMap& data) -{ - if(!hasCredentials()) { - m_pendingRequests += qMakePair(path, data); - login(); - return; - } - - QUrl url(m_serverBase.toString() +QLatin1Char('/')+ path); - url.setScheme(QStringLiteral("https")); - - KIO::StoredTransferJob* job = KIO::storedHttpPost(QJsonDocument::fromVariant(data).toJson(), url, KIO::Overwrite | KIO::HideProgressInfo); //TODO port to QJsonDocument - job->addMetaData(QStringLiteral("content-type"), QStringLiteral("Content-Type: application/json") ); - job->addMetaData(QStringLiteral("customHTTPHeader"), QStringLiteral("Authorization: ") + QString::fromLatin1(authorization(m_oauthInterface, url, m_loginBackend))); - connect(job, &KIO::StoredTransferJob::result, this, &ReviewsBackend::informationPosted); - job->start(); -} - -void ReviewsBackend::informationPosted(KJob* j) -{ - KIO::StoredTransferJob* job = qobject_cast<KIO::StoredTransferJob*>(j); - if(job->error()==0) { - qDebug() << "success" << job->data(); - } else { - qDebug() << "error..." << job->error() << job->errorString() << job->errorText(); - } -} - -bool ReviewsBackend::isFetching() const -{ - return !m_jobHash.isEmpty(); -} - -bool ReviewsBackend::hasCredentials() const -{ - return m_loginBackend->hasCredentials(); -} - -QString ReviewsBackend::userName() const -{ - Q_ASSERT(m_loginBackend->hasCredentials()); - return m_loginBackend->displayName(); -} - -void ReviewsBackend::login() -{ - Q_ASSERT(!m_loginBackend->hasCredentials()); - m_loginBackend->login(); -} - -void ReviewsBackend::registerAndLogin() -{ - Q_ASSERT(!m_loginBackend->hasCredentials()); - m_loginBackend->registerAndLogin(); -} - -void ReviewsBackend::logout() -{ - Q_ASSERT(m_loginBackend->hasCredentials()); - m_loginBackend->logout(); -} - -QString ReviewsBackend::errorMessage() const -{ - return i18n("No reviews available for Debian."); -} - -bool ReviewsBackend::isReviewable() const -{ - QString m_distId = getCodename(QLatin1String("ID")); - return m_distId == QLatin1String("ubuntu"); -} - diff --git a/libdiscover/backends/ApplicationBackend/ReviewsBackend.h b/libdiscover/backends/ApplicationBackend/ReviewsBackend.h deleted file mode 100644 index 3164831..0000000 --- a/libdiscover/backends/ApplicationBackend/ReviewsBackend.h +++ /dev/null @@ -1,105 +0,0 @@ -/*************************************************************************** - * Copyright © 2011 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef REVIEWSBACKEND_H -#define REVIEWSBACKEND_H - -#include <QtCore/QString> -#include <QtCore/QUrl> -#include <QtCore/QVariant> - -#include "discovercommon_export.h" -#include <ReviewsBackend/AbstractReviewsBackend.h> - -namespace QOAuth { - class Interface; -} - -class KJob; -class KTemporaryFile; - -namespace QApt { - class Backend; -} - -class AbstractLoginBackend; -class Application; -class Rating; -class Review; - -class DISCOVERCOMMON_EXPORT ReviewsBackend : public AbstractReviewsBackend -{ - Q_OBJECT -public: - explicit ReviewsBackend(QObject *parent); - ~ReviewsBackend() override; - - Rating *ratingForApplication(AbstractResource *app) const override; - - void setAptBackend(QApt::Backend *aptBackend); - void fetchReviews(AbstractResource* res, int page=1) override; -// void clearReviewCache(); - void stopPendingJobs(); - bool isFetching() const override; - - QString userName() const override; - bool hasCredentials() const override; - QString errorMessage() const override; - bool isReviewable() const override; - -Q_SIGNALS: - void ratingsReady(); - -private: - QApt::Backend *m_aptBackend; - - QString m_distId; - const QUrl m_serverBase; - QHash<QString, Rating *> m_ratings; - // cache key is package name + app name, since both by their own may not be unique - QHash<Application*, QList<Review *> > m_reviewsCache; - QHash<KJob *, Application *> m_jobHash; - - void loadRatingsFromFile(); - QString getLanguage(); - AbstractLoginBackend* m_loginBackend; - QOAuth::Interface* m_oauthInterface; - QList<QPair<QString, QVariantMap> > m_pendingRequests; - -private Q_SLOTS: - void ratingsFetched(KJob *job); - void reviewsFetched(KJob *j); - void informationPosted(KJob* j); - void postInformation(const QString& path, const QVariantMap& data); - void fetchRatings(); - -public Q_SLOTS: - void login() override; - void registerAndLogin() override; - void logout() override; - void submitUsefulness(Review* r, bool useful) override; - void submitReview(AbstractResource* application, const QString& summary, - const QString& review_text, const QString& rating) override; - void deleteReview(Review* r) override; - void flagReview(Review* r, const QString& reason, const QString &text) override; - void refreshConsumerKeys(); -}; - -#endif diff --git a/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.cpp b/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.cpp deleted file mode 100644 index f73a8cb..0000000 --- a/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/*************************************************************************** - * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "UbuntuLoginBackend.h" -#include <QDebug> -#include <QDBusMetaType> -#include <QApplication> -#include <QWidget> -#include <KLocalizedString> -#include "ubuntu_sso.h" - -//NOTE: this is needed because the method is called register. see the xml file for more info -struct HackedComUbuntuSsoCredentialsManagementInterface : public ComUbuntuSsoCredentialsManagementInterface -{ - HackedComUbuntuSsoCredentialsManagementInterface(const QString& service, const QString& path, const QDBusConnection& connection, QObject* parent = nullptr) - : ComUbuntuSsoCredentialsManagementInterface(service, path, connection, parent) - {} - - inline QDBusPendingReply<> register_hack(const QString &app_name, const QMap<QString,QString>& args) - { - QList<QVariant> argumentList; - argumentList << QVariant::fromValue(app_name) << QVariant::fromValue(args); - return asyncCallWithArgumentList(QLatin1String("register"), argumentList); - } -}; - -UbuntuLoginBackend::UbuntuLoginBackend(QObject* parent) - : AbstractLoginBackend(parent) -{ - qDBusRegisterMetaType< QMap<QString,QString> >(); - m_interface = new HackedComUbuntuSsoCredentialsManagementInterface( QStringLiteral("com.ubuntu.sso"), QStringLiteral("/com/ubuntu/sso/credentials"), QDBusConnection::sessionBus(), this); - connect(m_interface, &HackedComUbuntuSsoCredentialsManagementInterface::CredentialsError, this, &UbuntuLoginBackend::credentialsError); - connect(m_interface, &HackedComUbuntuSsoCredentialsManagementInterface::AuthorizationDenied, this, &UbuntuLoginBackend::authorizationDenied); - connect(m_interface, &HackedComUbuntuSsoCredentialsManagementInterface::CredentialsFound, this, &UbuntuLoginBackend::successfulLogin); - - m_interface->find_credentials(appname(), QMap<QString,QString>()); -} - -void UbuntuLoginBackend::login() -{ - QMap<QString,QString> data; - data[QStringLiteral("help_text")] = i18n("Log in to the Ubuntu SSO service"); - data[QStringLiteral("window_id")] = winId(); - QDBusPendingReply< void > ret = m_interface->login(appname(), data); -} - -void UbuntuLoginBackend::registerAndLogin() -{ - QMap<QString,QString> data; - data[QStringLiteral("help_text")] = i18n("Log in to the Ubuntu SSO service"); - data[QStringLiteral("window_id")] = winId(); - m_interface->register_hack(appname(), data); -} - -QString UbuntuLoginBackend::displayName() const -{ - return m_credentials[QStringLiteral("name")]; -} - -bool UbuntuLoginBackend::hasCredentials() const -{ - return !m_credentials.isEmpty(); -} - -void UbuntuLoginBackend::successfulLogin(const QString& app, const QMap<QString,QString>& credentials) -{ -// qDebug() << "logged in" << appname() << app << credentials; - if(app==appname()) { - m_credentials = credentials; - emit connectionStateChanged(); - } -} - -QString UbuntuLoginBackend::appname() const -{ - return QCoreApplication::instance()->applicationName(); -} - -QString UbuntuLoginBackend::winId() const -{ - QString windowId; - QApplication *app = qobject_cast<QApplication*>(qApp); - - if (app->activeWindow()) - windowId = QString::number(app->activeWindow()->winId()); - - return windowId; -} - -void UbuntuLoginBackend::authorizationDenied(const QString& app) -{ - qDebug() << "denied" << app; - if(app==appname()) - emit connectionStateChanged(); -} - -void UbuntuLoginBackend::credentialsError(const QString& app, const QMap<QString,QString>& a) -{ - //TODO: provide error message? - qDebug() << "error" << app << a; - if(app==appname()) - emit connectionStateChanged(); -} - -void UbuntuLoginBackend::logout() -{ - m_interface->clear_credentials(appname(), QMap<QString,QString>()); - m_credentials.clear(); - emit connectionStateChanged(); -} - -QByteArray UbuntuLoginBackend::token() const -{ - return m_credentials[QStringLiteral("token")].toLatin1(); -} - -QByteArray UbuntuLoginBackend::tokenSecret() const -{ - return m_credentials[QStringLiteral("token_secret")].toLatin1(); -} - -QByteArray UbuntuLoginBackend::consumerKey() const -{ - return m_credentials[QStringLiteral("consumer_key")].toLatin1(); -} - -QByteArray UbuntuLoginBackend::consumerSecret() const -{ - return m_credentials[QStringLiteral("consumer_secret")].toLatin1(); -} diff --git a/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.h b/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.h deleted file mode 100644 index 741bb00..0000000 --- a/libdiscover/backends/ApplicationBackend/UbuntuLoginBackend.h +++ /dev/null @@ -1,57 +0,0 @@ -/*************************************************************************** - * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef UBUNTULOGINBACKEND_H -#define UBUNTULOGINBACKEND_H - -#include <ReviewsBackend/AbstractLoginBackend.h> -#include <QVariant> - -struct HackedComUbuntuSsoCredentialsManagementInterface; -class UbuntuLoginBackend : public AbstractLoginBackend -{ - Q_OBJECT - public: - explicit UbuntuLoginBackend(QObject* parent=nullptr); - - void login() override; - void registerAndLogin() override; - void logout() override; - QString displayName() const override; - bool hasCredentials() const override; - - QByteArray token() const override; - QByteArray tokenSecret() const override; - QByteArray consumerKey() const override; - QByteArray consumerSecret() const override; - - private Q_SLOTS: - void credentialsError(const QString& app, const QMap<QString,QString>& a); - void authorizationDenied(const QString& app); - void successfulLogin(const QString& app, const QMap<QString,QString>& credentials); - - private: - QString appname() const; - QString winId() const; - HackedComUbuntuSsoCredentialsManagementInterface* m_interface; - QMap<QString,QString> m_credentials; -}; - -#endif // UBUNTULOGINBACKEND_H diff --git a/libdiscover/backends/ApplicationBackend/distupgradeevent/releasechecker b/libdiscover/backends/ApplicationBackend/distupgradeevent/releasechecker deleted file mode 100644 index d045f37..0000000 --- a/libdiscover/backends/ApplicationBackend/distupgradeevent/releasechecker +++ /dev/null @@ -1,46 +0,0 @@ -#! /usr/bin/python3 - -# releasechecker.py -# -# Copyright (c) 2010 Jonathan Thomas <echidnaman@kubuntu.org> -# -# Author: Jonathan Thomas <echidnaman@kubuntu.org> -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License or (at your option) version 3 or any later version -# accepted by the membership of KDE e.V. (or its successor approved -# by the membership of KDE e.V.), which shall act as a proxy -# defined in Section 14 of version 3 of the license. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see <http://www.gnu.org/licenses/>. - -import sys, time -sys.path.insert(0, '/usr/lib/python3/dist-packages/') - -from UpdateManager.Core.MetaRelease import MetaReleaseCore -from UpdateManager.Core.utils import init_proxy - -if __name__ == "__main__": - """ check for updates, if there are any say so """ - - init_proxy() - #FIXME: implement command line options for MetaReleaseCore args - metaRelease = MetaReleaseCore(False, False) - while metaRelease.downloading: - time.sleep(0.5) - new_dist = metaRelease.new_dist - - if new_dist is not None: - print("Found a release") - sys.exit(0) - else: - sys.exit(1) - diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.cpp deleted file mode 100644 index 7b43707..0000000 --- a/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.cpp +++ /dev/null @@ -1,41 +0,0 @@ -#include "AddRepositoryHelper.h" -#include <QProcess> -#include <QDebug> -#include <unistd.h> -#include <stdlib.h> -#include <kauthhelpersupport.h> - -ActionReply AddRepositoryHelper::modify(QVariantMap args) -{ - ActionReply reply = ActionReply::SuccessReply(); - if(args[QStringLiteral("repository")].isNull() || args[QStringLiteral("action")].isNull()) { - reply.setErrorDescription(QStringLiteral("Invalid action arguments.")); - reply = ActionReply::HelperErrorReply(); - return reply; - } - QProcess *p = new QProcess(this); - p->setProcessChannelMode(QProcess::MergedChannels); - QString modRepo(QStringLiteral("apt-add-repository")); - QStringList arguments; - if(args[QStringLiteral("action")].toString() == QLatin1String("add")) { - arguments.append(QStringLiteral("-y")); - arguments.append(args[QStringLiteral("repository")].toString()); - } else { - if(args[QStringLiteral("action")] == QLatin1String("remove")) - { - arguments.append(QStringLiteral("--remove")); - arguments.append(QStringLiteral("-y")); - arguments.append(args[QStringLiteral("repository")].toString()); - } - } - p->start(modRepo,arguments); - p->waitForFinished(); - if(p->exitCode() != 0) { - reply.setErrorDescription(QStringLiteral("Could not modify source.")); - reply= ActionReply::HelperErrorReply(); - } - p->deleteLater(); - return reply; -} - -KAUTH_HELPER_MAIN("org.kde.muon.repo", AddRepositoryHelper) diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.h b/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.h deleted file mode 100644 index 4244ca4..0000000 --- a/libdiscover/backends/ApplicationBackend/libmuonapt/AddRepositoryHelper.h +++ /dev/null @@ -1,15 +0,0 @@ -#ifndef ADDREPOSITORYHELPER_H -#define ADDREPOSITORYHELPER_H - -#include <kauthactionreply.h> - -using namespace KAuth; - -class AddRepositoryHelper : public QObject -{ - Q_OBJECT -public Q_SLOTS: - ActionReply modify(QVariantMap args); -}; - -#endif //ADDREPOSITORYHELPER_H
\ No newline at end of file diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/CMakeLists.txt b/libdiscover/backends/ApplicationBackend/libmuonapt/CMakeLists.txt deleted file mode 100644 index 536a5c6..0000000 --- a/libdiscover/backends/ApplicationBackend/libmuonapt/CMakeLists.txt +++ /dev/null @@ -1,26 +0,0 @@ -add_definitions(-DTRANSLATION_DOMAIN=\"libmuon\") - -add_library(MuonApt STATIC ChangesDialog.cpp - MuonStrings.cpp - QAptActions.cpp - HistoryView/HistoryProxyModel.cpp - HistoryView/HistoryView.cpp) - -target_link_libraries(MuonApt Qt5::Core - KF5::KIOWidgets KF5::XmlGui - QApt::Main KF5::I18n -) - -target_compile_definitions(MuonApt PRIVATE -DCMAKE_INSTALL_FULL_LIBEXECDIR_KF5=\"${CMAKE_INSTALL_FULL_LIBEXECDIR_KF5}\") - -target_include_directories(MuonApt PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) - -add_executable(muon_repo_helper AddRepositoryHelper.cpp) -target_link_libraries(muon_repo_helper Qt5::Core KF5::Auth) - -install(TARGETS muon_repo_helper DESTINATION ${LIBEXEC_INSTALL_DIR}) -kauth_install_actions(org.kde.muon.repo policies/org.kde.muon.repo.action) -kauth_install_helper_files(muon_repo_helper org.kde.muon.repo root) - -install(TARGETS MuonApt ${INSTALL_TARGETS_DEFAULT_ARGS}) - diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.cpp deleted file mode 100644 index 048decc..0000000 --- a/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.cpp +++ /dev/null @@ -1,118 +0,0 @@ -/*************************************************************************** - * Copyright © 2011 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "ChangesDialog.h" - -// Qt includes -#include <QtWidgets/QLabel> -#include <QtWidgets/QPushButton> -#include <QtWidgets/QTreeView> -#include <QtWidgets/QVBoxLayout> - -// KDE includes -#include <KLocalizedString> -#include <KStandardGuiItem> - -// Own includes -#include "../libmuonapt/MuonStrings.h" - -ChangesDialog::ChangesDialog(QWidget *parent, const QApt::StateChanges &changes) - : QDialog(parent) -{ - setWindowTitle(i18nc("@title:window", "Confirm Additional Changes")); - QVBoxLayout *layout = new QVBoxLayout(this); - setLayout(layout); - - QLabel *headerLabel = new QLabel(this); - headerLabel->setText(i18nc("@info", "<h2>Mark additional changes?</h2>")); - - int count = countChanges(changes); - QLabel *label = new QLabel(this); - label->setText(i18np("This action requires a change to another package:", - "This action requires changes to other packages:", - count)); - - QTreeView *packageView = new QTreeView(this); - packageView->setHeaderHidden(true); - packageView->setRootIsDecorated(false); - - QWidget *bottomBox = new QWidget(this); - QHBoxLayout *bottomLayout = new QHBoxLayout(bottomBox); - bottomLayout->setSpacing(0); - bottomLayout->setMargin(0); - bottomBox->setLayout(bottomLayout); - - QWidget *bottomSpacer = new QWidget(bottomBox); - bottomSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum); - - QPushButton *okButton = new QPushButton(bottomBox); - KGuiItem okItem = KStandardGuiItem::ok(); - okButton->setText(okItem.text()); - okButton->setIcon(okItem.icon()); - connect(okButton, &QPushButton::clicked, this, &ChangesDialog::accept); - - QPushButton *cancelButton = new QPushButton(bottomBox); - KGuiItem cancelItem = KStandardGuiItem::cancel(); - cancelButton->setText(cancelItem.text()); - cancelButton->setIcon(cancelItem.icon()); - connect(cancelButton, &QPushButton::clicked, this, &ChangesDialog::reject); - - bottomLayout->addWidget(bottomSpacer); - bottomLayout->addWidget(okButton); - bottomLayout->addWidget(cancelButton); - - m_model = new QStandardItemModel(this); - packageView->setModel(m_model); - addPackages(changes); - packageView->expandAll(); - packageView->setEditTriggers(QAbstractItemView::NoEditTriggers); - - layout->addWidget(headerLabel); - layout->addWidget(label); - layout->addWidget(packageView); - layout->addWidget(bottomBox); -} - -void ChangesDialog::addPackages(const QApt::StateChanges &changes) -{ - for (auto i = changes.constBegin(); i != changes.constEnd(); ++i) { - QStandardItem *root = new QStandardItem; - root->setText(MuonStrings::global()->packageStateName(i.key())); - - QFont font = root->font(); - font.setBold(true); - root->setFont(font); - - Q_FOREACH (QApt::Package *package, *i) { - root->appendRow(new QStandardItem(QIcon::fromTheme(QStringLiteral("muon")), package->name())); - } - - m_model->appendRow(root); - } -} - -int ChangesDialog::countChanges(const QApt::StateChanges &changes) -{ - int count = 0; - foreach (const QApt::PackageList& pkgs, changes) { - count += pkgs.size(); - } - return count; -} diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.h b/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.h deleted file mode 100644 index ed17c46..0000000 --- a/libdiscover/backends/ApplicationBackend/libmuonapt/ChangesDialog.h +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************** - * Copyright © 2011 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef CHANGESDIALOG_H -#define CHANGESDIALOG_H - -// Qt includes -#include <QStandardItemModel> -#include <QDialog> - -// QApt includes -#include <QApt/Package> - -class QStandardItemModel; - -class ChangesDialog : public QDialog -{ -public: - ChangesDialog(QWidget *parent, const QApt::StateChanges &changes); - -private: - QStandardItemModel *m_model; - - void addPackages(const QApt::StateChanges &changes); - int countChanges(const QApt::StateChanges &changes); -}; - -#endif // CHANGESDIALOG_H diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.cpp deleted file mode 100644 index 09c9037..0000000 --- a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.cpp +++ /dev/null @@ -1,85 +0,0 @@ -/*************************************************************************** - * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "HistoryProxyModel.h" - -#include <QStandardItemModel> -#include <QStandardItem> - -HistoryProxyModel::HistoryProxyModel(QObject *parent) - : QSortFilterProxyModel(parent) - , m_stateFilter(static_cast<QApt::Package::State>(0)) -{ -} - -HistoryProxyModel::~HistoryProxyModel() = default; - -void HistoryProxyModel::search(const QString &searchText) -{ - m_searchText = searchText; - invalidate(); -} - -void HistoryProxyModel::setStateFilter(QApt::Package::State state) -{ - m_stateFilter = state; - invalidate(); -} - -bool HistoryProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const -{ - QModelIndex sourceIndex = sourceModel()->index(sourceRow, 0, sourceParent); - for(int i = 0 ; i < sourceModel()->rowCount(sourceIndex); i++) { - if (filterAcceptsRow(i, sourceIndex)) { - return true; - } - } - - //Our "main"-method - QStandardItem *item = static_cast<QStandardItemModel *>(sourceModel())->itemFromIndex(sourceModel()->index(sourceRow, 0, sourceParent)); - - if (!item) { - return false; - } - - if (!m_stateFilter == 0) { - if ((bool)(item->data(HistoryActionRole).toInt() & m_stateFilter) == false) { - return false; - } - } - - if (!m_searchText.isEmpty()) { - if ((bool)(item->data(Qt::DisplayRole).toString().contains(m_searchText)) == false) { - return false; - } - } - - return true; -} - -bool HistoryProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const -{ - QStandardItemModel *parentModel = dynamic_cast<QStandardItemModel *>(sourceModel()); - - QStandardItem *leftItem = parentModel->itemFromIndex(left); - QStandardItem *rightItem = parentModel->itemFromIndex(right); - - return (leftItem->data(HistoryDateRole).toDateTime() > rightItem->data(HistoryDateRole).toDateTime()); -} diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.h b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.h deleted file mode 100644 index f5e2cc6..0000000 --- a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryProxyModel.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************** - * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef HISTORYPROXYMODEL_H -#define HISTORYPROXYMODEL_H - -#include <QSortFilterProxyModel> - -#include <QApt/Package> - -class HistoryProxyModel : public QSortFilterProxyModel -{ - Q_OBJECT -public: - enum { - HistoryDateRole = Qt::UserRole + 1, - HistoryActionRole = Qt::UserRole + 2 - }; - explicit HistoryProxyModel(QObject *parent); - ~HistoryProxyModel() override; - - void search(const QString &searchText); - void setStateFilter(QApt::Package::State state); - - bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const override; - -protected: - bool lessThan(const QModelIndex &left, const QModelIndex &right) const override; - -private: - QString m_searchText; - QApt::Package::State m_stateFilter; -}; - -#endif diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.cpp deleted file mode 100644 index 88e6cc5..0000000 --- a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.cpp +++ /dev/null @@ -1,238 +0,0 @@ -/*************************************************************************** - * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "HistoryView.h" - -#include <QtCore/QTimer> -#include <QtWidgets/QLabel> -#include <QListView> -#include <QtWidgets/QTreeView> -#include <QtWidgets/QVBoxLayout> -#include <QtWidgets/QLineEdit> -#include <QtWidgets/QComboBox> -#include <QStandardItemModel> - -#include <KLocalizedString> - -#include <QApt/History> - -#include "HistoryProxyModel.h" - -HistoryView::HistoryView(QWidget *parent) - : QWidget(parent) -{ - QVBoxLayout* layout = new QVBoxLayout(this); - setLayout(layout); - m_history = new QApt::History(this); - - QWidget *headerWidget = new QWidget(this); - QHBoxLayout *headerLayout = new QHBoxLayout(headerWidget); - headerWidget->setLayout(headerLayout); - - QLabel *headerLabel = new QLabel(headerWidget); - headerLabel->setText(xi18nc("@info", "<title>History</title>")); - - QWidget *headerSpacer = new QWidget(headerWidget); - headerSpacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); - - m_searchEdit = new QLineEdit(headerWidget); - m_searchEdit->setPlaceholderText(i18nc("@label Line edit click message", "Search")); - m_searchEdit->setClearButtonEnabled(true); - - m_searchTimer = new QTimer(this); - m_searchTimer->setInterval(300); - m_searchTimer->setSingleShot(true); - connect(m_searchTimer, &QTimer::timeout, this, &HistoryView::startSearch); - connect(m_searchEdit, &QLineEdit::textChanged, m_searchTimer, static_cast<void(QTimer::*)()>(&QTimer::start)); - - m_filterBox = new QComboBox(headerWidget); - m_filterBox->insertItem(AllChangesItem, QIcon::fromTheme(QStringLiteral("bookmark-new-list")), - i18nc("@item:inlistbox Filters all changes in the history view", - "All changes"), - 0); - m_filterBox->insertItem(InstallationsItem, QIcon::fromTheme(QStringLiteral("download")), - i18nc("@item:inlistbox Filters installations in the history view", - "Installations"), - QApt::Package::ToInstall); - m_filterBox->insertItem(UpdatesItem, QIcon::fromTheme(QStringLiteral("system-software-update")), - i18nc("@item:inlistbox Filters updates in the history view", - "Updates"), - QApt::Package::ToUpgrade); - m_filterBox->insertItem(RemovalsItem, QIcon::fromTheme(QStringLiteral("edit-delete")), - i18nc("@item:inlistbox Filters removals in the history view", - "Removals"), - (QApt::Package::State)(QApt::Package::ToRemove | QApt::Package::ToPurge)); - connect(m_filterBox, static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this, &HistoryView::setStateFilter); - - headerLayout->addWidget(headerLabel); - headerLayout->addWidget(headerSpacer); - headerLayout->addWidget(m_searchEdit); - headerLayout->addWidget(m_filterBox); - - m_historyModel = new QStandardItemModel(this); - m_historyModel->setColumnCount(1); - m_historyModel->setHeaderData(0, Qt::Horizontal, i18nc("@title:column", "Date")); - m_historyView = new QTreeView(this); - - layout->addWidget(headerWidget); - layout->addWidget(m_historyView); - - QIcon itemIcon(QIcon::fromTheme(QStringLiteral("applications-other"))); - - QHash<QString, QString> categoryHash; - - QHash<PastActions, QString> actionHash; - actionHash[InstalledAction] = i18nc("@info:status describes a past-tense action", "Installed"); - actionHash[UpgradedAction] = i18nc("@info:status describes a past-tense action", "Upgraded"); - actionHash[DowngradedAction] = i18nc("@status describes a past-tense action", "Downgraded"); - actionHash[RemovedAction] = i18nc("@status describes a past-tense action", "Removed"); - actionHash[PurgedAction] = i18nc("@status describes a past-tense action", "Purged"); - - Q_FOREACH (const QApt::HistoryItem &item, m_history->historyItems()) { - QDateTime startDateTime = item.startDate(); - QString formattedTime = startDateTime.toString(); - QString category; - - QString date = startDateTime.date().toString(); - if (categoryHash.contains(date)) { - category = categoryHash.value(date); - } else { - category = startDateTime.date().toString(Qt::DefaultLocaleShortDate); - categoryHash[date] = category; - } - - QStandardItem *parentItem = nullptr; - - if (!m_categoryHash.contains(category)) { - parentItem = new QStandardItem; - parentItem->setEditable(false); - parentItem->setText(category); - parentItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole); - - m_historyModel->appendRow(parentItem); - m_categoryHash[category] = parentItem; - } else { - parentItem = m_categoryHash.value(category); - } - - foreach (const QString &package, item.installedPackages()) { - QStandardItem *historyItem = new QStandardItem; - historyItem->setEditable(false); - historyItem->setIcon(itemIcon); - - QString action = actionHash.value(InstalledAction); - QString text = i18nc("@item example: muon installed at 16:00", "%1 %2 at %3", - package, action, formattedTime); - historyItem->setText(text); - historyItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole); - historyItem->setData(QApt::Package::ToInstall, HistoryProxyModel::HistoryActionRole); - - parentItem->appendRow(historyItem); - } - - foreach (const QString &package, item.upgradedPackages()) { - QStandardItem *historyItem = new QStandardItem; - historyItem->setEditable(false); - historyItem->setIcon(itemIcon); - - QString action = actionHash.value(UpgradedAction); - QString text = i18nc("@item example: muon installed at 16:00", "%1 %2 at %3", - package, action, formattedTime); - historyItem->setText(text); - historyItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole); - historyItem->setData(QApt::Package::ToUpgrade, HistoryProxyModel::HistoryActionRole); - - parentItem->appendRow(historyItem); - } - - foreach (const QString &package, item.downgradedPackages()) { - QStandardItem *historyItem = new QStandardItem; - historyItem->setEditable(false); - historyItem->setIcon(itemIcon); - - QString action = actionHash.value(DowngradedAction); - QString text = i18nc("@item example: muon installed at 16:00", "%1 %2 at %3", - package, action, formattedTime); - historyItem->setText(text); - historyItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole); - historyItem->setData(QApt::Package::ToDowngrade, HistoryProxyModel::HistoryActionRole); - - parentItem->appendRow(historyItem); - } - - foreach (const QString &package, item.removedPackages()) { - QStandardItem *historyItem = new QStandardItem; - historyItem->setEditable(false); - historyItem->setIcon(itemIcon); - - QString action = actionHash.value(RemovedAction); - QString text = i18nc("@item example: muon installed at 16:00", "%1 %2 at %3", - package, action, formattedTime); - historyItem->setText(text); - historyItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole); - historyItem->setData(QApt::Package::ToRemove, HistoryProxyModel::HistoryActionRole); - - parentItem->appendRow(historyItem); - } - - foreach (const QString &package, item.purgedPackages()) { - QStandardItem *historyItem = new QStandardItem; - historyItem->setEditable(false); - historyItem->setIcon(itemIcon); - - QString action = actionHash.value(PurgedAction); - QString text = i18nc("@item example: muon installed at 16:00", "%1 %2 at %3", - package, action, formattedTime); - historyItem->setText(text); - historyItem->setData(startDateTime, HistoryProxyModel::HistoryDateRole); - historyItem->setData(QApt::Package::ToPurge, HistoryProxyModel::HistoryActionRole); - - parentItem->appendRow(historyItem); - } - } - - m_historyView->setMouseTracking(true); - m_historyView->setVerticalScrollMode(QListView::ScrollPerPixel); - - m_proxyModel = new HistoryProxyModel(this); - m_proxyModel->setSourceModel(m_historyModel); - m_proxyModel->sort(0); - - m_historyView->setModel(m_proxyModel); - - setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); -} - -QSize HistoryView::sizeHint() const -{ - return QWidget::sizeHint().expandedTo(QSize(500, 500)); -} - -void HistoryView::setStateFilter(int index) -{ - QApt::Package::State state = (QApt::Package::State)m_filterBox->itemData(index).toInt(); - m_proxyModel->setStateFilter(state); -} - -void HistoryView::startSearch() -{ - m_proxyModel->search(m_searchEdit->text()); -} - diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.h b/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.h deleted file mode 100644 index 7ffb2b0..0000000 --- a/libdiscover/backends/ApplicationBackend/libmuonapt/HistoryView/HistoryView.h +++ /dev/null @@ -1,79 +0,0 @@ -/*************************************************************************** - * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef HISTORYVIEW_H -#define HISTORYVIEW_H - -#include <QtCore/QHash> - -#include <QWidget> - -class QStandardItem; -class QStandardItemModel; -class QTimer; -class QTreeView; -class QLineEdit; -class QComboBox; - -namespace QApt { - class History; -} - -class HistoryProxyModel; - -class HistoryView : public QWidget -{ - Q_OBJECT -public: - enum ComboItems { - AllChangesItem = 0, - InstallationsItem = 1, - UpdatesItem = 2, - RemovalsItem = 3 - }; - enum PastActions { - InvalidAction = 0, - InstalledAction = 1, - UpgradedAction = 2, - DowngradedAction = 3, - RemovedAction = 4, - PurgedAction = 5 - }; - explicit HistoryView(QWidget *parent); - - QSize sizeHint() const override; - -private: - QApt::History *m_history; - QStandardItemModel *m_historyModel; - HistoryProxyModel *m_proxyModel; - QHash<QString, QStandardItem *> m_categoryHash; - - QLineEdit *m_searchEdit; - QTimer *m_searchTimer; - QComboBox *m_filterBox; - QTreeView *m_historyView; - -private Q_SLOTS: - void setStateFilter(int index); - void startSearch(); -}; - -#endif diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.cpp deleted file mode 100644 index 16eb44f..0000000 --- a/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/*************************************************************************** - * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "MuonStrings.h" - -#include <KLocalizedString> -#include <QDebug> - -#include <QApt/Transaction> - -Q_GLOBAL_STATIC_WITH_ARGS(MuonStrings, globalMuonStrings, (0)) - -using namespace QApt; - -MuonStrings *MuonStrings::global() -{ - return globalMuonStrings; -} - -MuonStrings::MuonStrings(QObject *parent) - : QObject(parent) - , m_stateHash(stateHash()) -{ -} - -QHash<int, QString> MuonStrings::stateHash() -{ - QHash<int, QString> hash; - hash[Package::ToKeep] = i18nc("@info:status Package state", "No Change"); - hash[Package::ToInstall] = i18nc("@info:status Requested action", "Install"); - hash[Package::NewInstall] = i18nc("@info:status Requested action", "Install"); - hash[Package::ToReInstall] = i18nc("@info:status Requested action", "Reinstall"); - hash[Package::ToUpgrade] = i18nc("@info:status Requested action", "Upgrade"); - hash[Package::ToDowngrade] = i18nc("@info:status Requested action", "Downgrade"); - hash[Package::ToRemove] = i18nc("@info:status Requested action", "Remove"); - hash[Package::Held] = i18nc("@info:status Package state" , "Held"); - hash[Package::Installed] = i18nc("@info:status Package state", "Installed"); - hash[Package::Upgradeable] = i18nc("@info:status Package state", "Upgradeable"); - hash[Package::NowBroken] = i18nc("@info:status Package state", "Broken"); - hash[Package::InstallBroken] = i18nc("@info:status Package state", "Install Broken"); - hash[Package::Orphaned] = i18nc("@info:status Package state", "Orphaned"); - hash[Package::Pinned] = i18nc("@info:status Package state", "Locked"); - hash[Package::New] = i18nc("@info:status Package state", "New in repository"); - hash[Package::ResidualConfig] = i18nc("@info:status Package state", "Residual Configuration"); - hash[Package::NotDownloadable] = i18nc("@info:status Package state", "Not Downloadable"); - hash[Package::ToPurge] = i18nc("@info:status Requested action", "Purge"); - hash[Package::IsImportant] = i18nc("@info:status Package state", "Important for base install"); - hash[Package::OverrideVersion] = i18nc("@info:status Package state", "Version overridden"); - hash[Package::IsAuto] = i18nc("@info:status Package state", "Required by other packages"); - hash[Package::IsGarbage] = i18nc("@info:status Package state", "Installed (auto-removable)"); - hash[Package::NowPolicyBroken] = i18nc("@info:status Package state", "Policy Broken"); - hash[Package::InstallPolicyBroken] = i18nc("@info:status Package state", "Policy Broken"); - hash[Package::NotInstalled] = i18nc("@info:status Package state" , "Not Installed"); - hash[Package::IsPinned] = i18nc("@info:status Package locked at a certain version", - "Locked"); - hash[Package::IsManuallyHeld] = i18nc("@info:status Package state", "Manually held back"); - - return hash; -} - -QString MuonStrings::packageStateName(Package::State state) const -{ - return m_stateHash.value(state); -} - -QString MuonStrings::packageChangeStateName(Package::State state) const -{ - int ns = state & (Package::ToKeep | Package::ToInstall | Package::ToReInstall | Package::NewInstall - | Package::ToUpgrade | Package::ToRemove - | Package::ToPurge | Package::ToDowngrade); - return m_stateHash.value(ns); -} - -QString MuonStrings::errorTitle(ErrorCode error) const -{ - switch (error) { - case InitError: - return i18nc("@title:window", "Initialization Error"); - case LockError: - return i18nc("@title:window", "Unable to Obtain Package System Lock"); - case DiskSpaceError: - return i18nc("@title:window", "Low Disk Space"); - case FetchError: - case CommitError: - return i18nc("@title:window", "Failed to Apply Changes"); - case AuthError: - return i18nc("@title:window", "Authentication error"); - case WorkerDisappeared: - return i18nc("@title:window", "Unexpected Error"); - case UntrustedError: - return i18nc("@title:window", "Untrusted Packages"); - case UnknownError: - default: - return i18nc("@title:window", "Unknown Error"); - } -} - -QString MuonStrings::errorText(ErrorCode error, Transaction *trans) const -{ - QString text; - - switch (error) { - case InitError: - text = i18nc("@label", "The package system could not be initialized, your " - "configuration may be broken."); - break; - case LockError: - text = i18nc("@label", - "Another application seems to be using the package " - "system at this time. You must close all other package " - "managers before you will be able to install or remove " - "any packages."); - break; - case DiskSpaceError: - text = i18nc("@label", - "You do not have enough disk space in the directory " - "at %1 to continue with this operation.", trans->errorDetails()); - break; - case FetchError: - text = i18nc("@label", "Could not download packages"); - break; - case CommitError: - text = i18nc("@label", "An error occurred while applying changes:"); - break; - case AuthError: - text = i18nc("@label", - "This operation cannot continue since proper " - "authorization was not provided"); - break; - case WorkerDisappeared: - text = i18nc("@label", "It appears that the QApt worker has either crashed " - "or disappeared. Please report a bug to the QApt maintainers"); - break; - case UntrustedError: - text = i18ncp("@label", - "The following package has not been verified by its author. " - "Downloading untrusted packages has been disallowed " - "by your current configuration.", - "The following packages have not been verified by " - "their authors. " - "Downloading untrusted packages has " - "been disallowed by your current configuration.", - trans->untrustedPackages().size()); - break; - default: - break; - } - - return text; -} diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.h b/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.h deleted file mode 100644 index d7886d3..0000000 --- a/libdiscover/backends/ApplicationBackend/libmuonapt/MuonStrings.h +++ /dev/null @@ -1,56 +0,0 @@ -/*************************************************************************** - * Copyright © 2010 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef MUONSTRINGS_H -#define MUONSTRINGS_H - -#include <QtCore/QHash> - -#include <QApt/Package> - -namespace QApt { - class Transaction; -} - -class MuonStrings : public QObject -{ - Q_OBJECT -public: - explicit MuonStrings(QObject *parent); - - static MuonStrings* global(); - - /** @returns the state name for a given @p state, for displaying it to the user */ - QString packageStateName(QApt::Package::State state) const; - - /** @returns the state name for the given @p state changes, for displaying it to the user - * This means, the flags that are related to a state change, like ToInstall, ToUpgrade, etc - */ - QString packageChangeStateName(QApt::Package::State state) const; - QString errorTitle(QApt::ErrorCode error) const; - QString errorText(QApt::ErrorCode error, QApt::Transaction *trans) const; - -private: - const QHash<int, QString> m_stateHash; - - static QHash<int, QString> stateHash(); -}; - -#endif diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.cpp b/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.cpp deleted file mode 100644 index 74810c7..0000000 --- a/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.cpp +++ /dev/null @@ -1,537 +0,0 @@ -/*************************************************************************** - * Copyright © 2012 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "QAptActions.h" -#include "MuonStrings.h" -#include "HistoryView/HistoryView.h" - -// Qt includes -#include <QtCore/QDir> -#include <QtCore/QStringBuilder> -#include <QAction> -#include <QDebug> -#include <QDialog> -#include <QFileDialog> -#include <QStandardPaths> -#include <QDialogButtonBox> -#include <QLayout> -#include <QNetworkConfigurationManager> -#include <QApplication> - -// KDE includes -#include <KActionCollection> -#include <KConfigGroup> -#include <KLocalizedString> -#include <KMessageBox> -#include <KProcess> -#include <KStandardAction> -#include <KSharedConfig> -#include <KXmlGuiWindow> -#include <KWindowConfig> - -// QApt includes -#include <QApt/Backend> -#include <QApt/DebFile> -#include <QApt/Transaction> - -QAptActions::QAptActions() - : QObject(nullptr) - , m_backend(nullptr) - , m_actionsDisabled(false) - , m_reloadWhenEditorFinished(false) - , m_historyDialog(nullptr) - , m_distUpgradeAvailable(false) - , m_config(new QNetworkConfigurationManager(this)) -{ - connect(m_config, &QNetworkConfigurationManager::onlineStateChanged, this, &QAptActions::shouldConnect); -} - -QAptActions* QAptActions::self() -{ - static QPointer<QAptActions> self; - if(!self) { - self = new QAptActions; - } - return self; -} - -void QAptActions::setActionCollection(KActionCollection* actions) -{ - setParent(actions); - m_actionCollection = actions; - - setupActions(); -} - -QWidget* QAptActions::mainWindow() const -{ - return nullptr; -} - -void QAptActions::setBackend(QApt::Backend* backend) -{ - if(backend == m_backend) - return; - m_backend = backend; - if (!m_backend->init()) - initError(); - - connect(m_backend, SIGNAL(packageChanged()), this, SLOT(setActionsEnabled())); - - setOriginalState(m_backend->currentCacheState()); - - setReloadWhenEditorFinished(true); - // Some actions need an initialized backend to be able to set their enabled state - setActionsEnabled(true); - checkDistUpgrade(); -} - -void QAptActions::setupActions() -{ - QAction* undoAction = KStandardAction::undo(this, SLOT(undo()), actionCollection()); - actionCollection()->addAction(QStringLiteral("undo"), undoAction); - m_actions.append(undoAction); - - QAction* redoAction = KStandardAction::redo(this, SLOT(redo()), actionCollection()); - actionCollection()->addAction(QStringLiteral("redo"), redoAction); - m_actions.append(redoAction); - - QAction* revertAction = actionCollection()->addAction(QStringLiteral("revert")); - revertAction->setIcon(QIcon::fromTheme(QStringLiteral("document-revert"))); - revertAction->setText(i18nc("@action Reverts all potential changes to the cache", "Unmark All")); - connect(revertAction, &QAction::triggered, this, &QAptActions::revertChanges); - m_actions.append(revertAction); - - QAction* softwarePropertiesAction = actionCollection()->addAction(QStringLiteral("software_properties")); - softwarePropertiesAction->setPriority(QAction::LowPriority); - softwarePropertiesAction->setIcon(QIcon::fromTheme(QStringLiteral("configure"))); - softwarePropertiesAction->setText(i18nc("@action Opens the software sources configuration dialog", "Configure Software Sources")); - connect(softwarePropertiesAction, &QAction::triggered, this, &QAptActions::runSourcesEditor); - m_actions.append(softwarePropertiesAction); - - QAction* loadSelectionsAction = actionCollection()->addAction(QStringLiteral("open_markings")); - loadSelectionsAction->setIcon(QIcon::fromTheme(QStringLiteral("document-open"))); - loadSelectionsAction->setText(i18nc("@action", "Read Markings...")); - connect(loadSelectionsAction, &QAction::triggered, this, &QAptActions::loadSelections); - m_actions.append(loadSelectionsAction); - - QAction* saveSelectionsAction = actionCollection()->addAction(QStringLiteral("save_markings")); - saveSelectionsAction->setIcon(QIcon::fromTheme(QStringLiteral("document-save-as"))); - saveSelectionsAction->setText(i18nc("@action", "Save Markings As...")); - connect(saveSelectionsAction, &QAction::triggered, this, &QAptActions::saveSelections); - m_actions.append(saveSelectionsAction); - - QAction* createDownloadListAction = actionCollection()->addAction(QStringLiteral("save_download_list")); - createDownloadListAction->setPriority(QAction::LowPriority); - createDownloadListAction->setIcon(QIcon::fromTheme(QStringLiteral("document-save-as"))); - createDownloadListAction->setText(i18nc("@action", "Save Package Download List...")); - connect(createDownloadListAction, &QAction::triggered, this, &QAptActions::createDownloadList); - m_actions.append(createDownloadListAction); - - QAction* downloadListAction = actionCollection()->addAction(QStringLiteral("download_from_list")); - downloadListAction->setPriority(QAction::LowPriority); - downloadListAction->setIcon(QIcon::fromTheme(QStringLiteral("download"))); - downloadListAction->setText(i18nc("@action", "Download Packages From List...")); - connect(downloadListAction, &QAction::triggered, this, &QAptActions::downloadPackagesFromList); - downloadListAction->setEnabled(isConnected()); - connect(this, &QAptActions::shouldConnect, downloadListAction, &QAction::setEnabled); - m_actions.append(downloadListAction); - - QAction* loadArchivesAction = actionCollection()->addAction(QStringLiteral("load_archives")); - loadArchivesAction->setPriority(QAction::LowPriority); - loadArchivesAction->setIcon(QIcon::fromTheme(QStringLiteral("document-open"))); - loadArchivesAction->setText(i18nc("@action", "Add Downloaded Packages")); - connect(loadArchivesAction, &QAction::triggered, this, &QAptActions::loadArchives); - m_actions.append(loadArchivesAction); - - QAction* saveInstalledAction = actionCollection()->addAction(QStringLiteral("save_package_list")); - saveInstalledAction->setPriority(QAction::LowPriority); - saveInstalledAction->setIcon(QIcon::fromTheme(QStringLiteral("document-save-as"))); - saveInstalledAction->setText(i18nc("@action", "Save Installed Packages List...")); - connect(saveInstalledAction, &QAction::triggered, this, &QAptActions::saveInstalledPackagesList); - - QAction* historyAction = actionCollection()->addAction(QStringLiteral("history")); - historyAction->setPriority(QAction::LowPriority); - historyAction->setIcon(QIcon::fromTheme(QStringLiteral("view-history"))); - historyAction->setText(i18nc("@action::inmenu", "History...")); - actionCollection()->setDefaultShortcut(historyAction, QKeySequence(Qt::CTRL + Qt::Key_H)); - connect(historyAction, &QAction::triggered, this, &QAptActions::showHistoryDialog); - - QAction *distUpgradeAction = actionCollection()->addAction(QStringLiteral("dist-upgrade")); - distUpgradeAction->setIcon(QIcon::fromTheme(QStringLiteral("system-software-update"))); - distUpgradeAction->setText(i18nc("@action", "Upgrade")); - distUpgradeAction->setPriority(QAction::HighPriority); - distUpgradeAction->setWhatsThis(i18nc("Notification when a new version of Kubuntu is available", - "A new version of Kubuntu is available.")); - distUpgradeAction->setEnabled(m_distUpgradeAvailable); - connect(distUpgradeAction, &QAction::triggered, this, &QAptActions::launchDistUpgrade); - - m_actions.append(saveInstalledAction); -} - -void QAptActions::setActionsEnabled(bool enabled) -{ - m_actionsDisabled = !enabled; - - Q_FOREACH (QAction *action, m_actions) { - action->setEnabled(enabled); - } - - if (!enabled || !actionCollection()) - return; - - actionCollection()->action(QStringLiteral("update"))->setEnabled(isConnected() && enabled); - - actionCollection()->action(QStringLiteral("undo"))->setEnabled(m_backend && !m_backend->isUndoStackEmpty()); - actionCollection()->action(QStringLiteral("redo"))->setEnabled(m_backend && !m_backend->isRedoStackEmpty()); - actionCollection()->action(QStringLiteral("revert"))->setEnabled(m_backend && !m_backend->isUndoStackEmpty()); - - actionCollection()->action(QStringLiteral("save_download_list"))->setEnabled(isConnected()); - - bool changesPending = m_backend && m_backend->areChangesMarked(); - actionCollection()->action(QStringLiteral("save_markings"))->setEnabled(changesPending); - actionCollection()->action(QStringLiteral("save_download_list"))->setEnabled(changesPending); - actionCollection()->action(QStringLiteral("dist-upgrade"))->setEnabled(m_distUpgradeAvailable); -} - -bool QAptActions::reloadWhenSourcesEditorFinished() const -{ - return m_reloadWhenEditorFinished; -} - -bool QAptActions::isConnected() const -{ - return m_config->isOnline(); -} - -bool QAptActions::saveSelections() -{ - QString filename = QFileDialog::getSaveFileName(mainWindow(), i18nc("@title:window", "Save Markings As")); - - if (filename.isEmpty()) { - return false; - } - - if (!m_backend->saveSelections(filename)) { - QString text = xi18nc("@label", "The document could not be saved, as it " - "was not possible to write to " - "<filename>%1</filename>\n\nCheck " - "that you have write access to this file " - "or that enough disk space is available.", - filename); - KMessageBox::error(mainWindow(), text, QString()); - return false; - } - - return true; -} - -bool QAptActions::saveInstalledPackagesList() -{ - QString filename; - - filename = QFileDialog::getSaveFileName(mainWindow(), - i18nc("@title:window", "Save Installed Packages List As")); - - if (filename.isEmpty()) { - return false; - } - - if (!m_backend->saveInstalledPackagesList(filename)) { - QString text = xi18nc("@label", "The document could not be saved, as it " - "was not possible to write to " - "<filename>%1</filename>\n\nCheck " - "that you have write access to this file " - "or that enough disk space is available.", - filename); - KMessageBox::error(mainWindow(), text, QString()); - return false; - } - - return true; -} - -bool QAptActions::createDownloadList() -{ - QString filename; - filename = QFileDialog::getSaveFileName(mainWindow(), - i18nc("@title:window", "Save Download List As")); - - if (filename.isEmpty()) { - return false; - } - - if (!m_backend->saveDownloadList(filename)) { - QString text = xi18nc("@label", "The document could not be saved, as it " - "was not possible to write to " - "<filename>%1</filename>\n\nCheck " - "that you have write access to this file " - "or that enough disk space is available.", - filename); - KMessageBox::error(mainWindow(), text, QString()); - return false; - } - - return true; -} - -void QAptActions::downloadPackagesFromList() -{ - QString filename = QFileDialog::getOpenFileName(mainWindow(), i18nc("@title:window", "Open File")); - - if (filename.isEmpty()) { - return; - } - - QString dirName = filename.left(filename.lastIndexOf(QLatin1Char('/'))); - - setActionsEnabled(false); - QApt::Transaction *trans = m_backend->downloadArchives(filename, dirName % QLatin1String("/packages")); - - if (trans) - emit downloadArchives(trans); -} - -void QAptActions::loadSelections() -{ - QString filename = QFileDialog::getOpenFileName(mainWindow(), i18nc("@title:window", "Open File")); - - if (filename.isEmpty()) { - return; - } - - m_backend->saveCacheState(); - if (!m_backend->loadSelections(filename)) { - QString text = i18nc("@label", "Could not mark changes. Please make sure " - "that the file is a markings file created by " - "either the Muon Package Manager or the " - "Synaptic Package Manager."); - KMessageBox::error(mainWindow(), text, QString()); - } -} - -void QAptActions::loadArchives() -{ - QString dirName = QFileDialog::getExistingDirectory(mainWindow(), - i18nc("@title:window", "Choose a Directory")); - - if (dirName.isEmpty()) { - // User canceled - return; - } - - QDir dir(dirName); - QStringList archiveFiles = dir.entryList(QDir::Files, QDir::Name); - - int successCount = 0; - foreach (const QString &archiveFile, archiveFiles) { - const QApt::DebFile debFile(dirName % QLatin1Char('/') % archiveFile); - - if (debFile.isValid()) { - if (m_backend->addArchiveToCache(debFile)) { - successCount++; - } - } - } - - if (successCount != 0) { - QString message = i18ncp("@label", - "%1 package was successfully added to the cache", - "%1 packages were successfully added to the cache", - successCount); - KMessageBox::information(mainWindow(), message, QString()); - } else { - QString message = i18nc("@label", - "No valid packages could be found in this directory. " - "Please make sure the packages are compatible with your " - "computer and are at the latest version."); - KMessageBox::error(mainWindow(), message, i18nc("@title:window", - "Packages Could Not be Found")); - } -} - -void QAptActions::undo() -{ - m_backend->undo(); -} - -void QAptActions::redo() -{ - m_backend->redo(); -} - -void QAptActions::revertChanges() -{ - m_backend->restoreCacheState(m_originalState); - emit changesReverted(); -} - -void QAptActions::runSourcesEditor() -{ - KProcess *proc = new KProcess(this); - QStringList arguments; - int winID = 0; - foreach(QWindow* w, QGuiApplication::allWindows()) { - if (w->objectName() == QLatin1String("DiscoverMainWindow")) { - winID = w->winId(); - } - } - - const QString kdesu = QFile::decodeName(CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/kdesu"); - const QString editor = QStandardPaths::findExecutable(QStringLiteral("software-properties-kde")); - - arguments << kdesu << QStringLiteral("--") << editor << QStringLiteral("--attach") << QString::number(winID); - if (m_reloadWhenEditorFinished) { - arguments << QStringLiteral("--dont-update"); - } - - proc->setProgram(arguments); - proc->start(); - connect(proc, static_cast<void (KProcess::*)(int, QProcess::ExitStatus)>(&KProcess::finished), this, &QAptActions::sourcesEditorFinished); -} - -void QAptActions::sourcesEditorFinished(int exitStatus) -{ - bool reload = (exitStatus != 0); - if (m_reloadWhenEditorFinished && reload) { - actionCollection()->action(QStringLiteral("update"))->trigger(); - } - - emit sourcesEditorClosed(reload); -} - -KActionCollection* QAptActions::actionCollection() -{ - return m_actionCollection; -} - -void QAptActions::setOriginalState(QApt::CacheState state) -{ - m_originalState = state; -} - -void QAptActions::setReloadWhenEditorFinished(bool reload) -{ - m_reloadWhenEditorFinished = reload; -} - -void QAptActions::initError() -{ - QString details = m_backend->initErrorMessage(); - - MuonStrings *muonStrings = MuonStrings::global(); - - QString title = muonStrings->errorTitle(QApt::InitError); - QString text = muonStrings->errorText(QApt::InitError, nullptr); - - KMessageBox::detailedError(mainWindow(), text, details, title); - exit(-1); -} - -void QAptActions::displayTransactionError(QApt::ErrorCode error, QApt::Transaction* trans) -{ - if (error == QApt::Success) - return; - - MuonStrings *muonStrings = MuonStrings::global(); - - QString title = muonStrings->errorTitle(error); - QString text = muonStrings->errorText(error, trans); - - switch (error) { - case QApt::InitError: - case QApt::FetchError: - case QApt::CommitError: - KMessageBox::detailedError(QAptActions::self()->mainWindow(), text, trans->errorDetails(), title); - break; - default: - KMessageBox::error(QAptActions::self()->mainWindow(), text, title); - break; - } -} - -void QAptActions::showHistoryDialog() -{ - if (!m_historyDialog) { - m_historyDialog = new QDialog(mainWindow()); - QVBoxLayout* layout = new QVBoxLayout(m_historyDialog); - m_historyDialog->setLayout(layout); - m_historyDialog->setWindowTitle(i18nc("@title:window", "Package History")); - m_historyDialog->setWindowIcon(QIcon::fromTheme(QStringLiteral("view-history"))); - - KConfigGroup dialogConfig(KSharedConfig::openConfig(QStringLiteral("muonrc")), QStringLiteral("HistoryDialog")); - KWindowConfig::restoreWindowSize(m_historyDialog->windowHandle(), dialogConfig); - - HistoryView *historyView = new HistoryView(m_historyDialog); - layout->addWidget(historyView); - - QDialogButtonBox* box = new QDialogButtonBox(m_historyDialog); - box->setStandardButtons(QDialogButtonBox::Close); - connect(box, &QDialogButtonBox::accepted, m_historyDialog.data(), &QDialog::accept); - connect(box, &QDialogButtonBox::rejected, m_historyDialog.data(), &QDialog::reject); - connect(m_historyDialog, &QDialog::finished, this, &QAptActions::closeHistoryDialog); - layout->addWidget(box); - - m_historyDialog->show(); - } else { - m_historyDialog->raise(); - } -} - -void QAptActions::closeHistoryDialog() -{ - KConfigGroup dialogConfig(KSharedConfig::openConfig(QStringLiteral("muonrc")), "HistoryDialog"); - KWindowConfig::restoreWindowSize(m_historyDialog->windowHandle(), dialogConfig); - m_historyDialog->deleteLater(); - m_historyDialog = nullptr; -} - -void QAptActions::launchDistUpgrade() -{ - const QString kdesu = QFile::decodeName(CMAKE_INSTALL_FULL_LIBEXECDIR_KF5 "/kdesu"); - QProcess::startDetached(kdesu, {QStringLiteral("--"), QStringLiteral("do-release-upgrade"), QStringLiteral("-m"), QStringLiteral("desktop"), QStringLiteral("-f"), QStringLiteral("DistUpgradeViewKDE")}); -} - -void QAptActions::checkDistUpgrade() -{ - if(!QFile::exists(QStringLiteral("/usr/lib/python3/dist-packages/DistUpgrade/DistUpgradeFetcherKDE.py"))) { - qWarning() << "Couldn't find the /usr/lib/python3/dist-packages/DistUpgrade/DistUpgradeFetcherKDE.py file"; - return; - } - QString checkerFile = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QStringLiteral("libdiscover/applicationsbackend/releasechecker")); - if(checkerFile.isEmpty()) { - qWarning() << "Couldn't find the releasechecker script" << QStandardPaths::standardLocations(QStandardPaths::GenericDataLocation); - return; - } - - KProcess* checkerProcess = new KProcess(this); - checkerProcess->setProgram({ QStringLiteral("/usr/bin/python3"), checkerFile }); - connect(checkerProcess, static_cast<void (KProcess::*)(int)>(&KProcess::finished), this, &QAptActions::checkerFinished); - connect(checkerProcess, static_cast<void (KProcess::*)(int)>(&KProcess::finished), checkerProcess, &KProcess::deleteLater); - checkerProcess->start(); -} - -void QAptActions::checkerFinished(int res) -{ - m_distUpgradeAvailable = (res == 0); - if (!actionCollection()) - return; - actionCollection()->action(QStringLiteral("dist-upgrade"))->setEnabled(m_distUpgradeAvailable); -} diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.h b/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.h deleted file mode 100644 index b71b290..0000000 --- a/libdiscover/backends/ApplicationBackend/libmuonapt/QAptActions.h +++ /dev/null @@ -1,110 +0,0 @@ -/*************************************************************************** - * Copyright © 2012 Jonathan Thomas <echidnaman@kubuntu.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef QAPTACTIONS_H -#define QAPTACTIONS_H - -#include <QtCore/QObject> -#include <QPointer> -#include <QWindow> - -#include <QApt/Globals> - -class KXmlGuiWindow; -class KDialog; -class KXmlGuiWindow; -class KActionCollection; -class QAction; -class QDialog; -class QNetworkConfigurationManager; - -namespace QApt { - class Backend; - class Transaction; -} - -class QAptActions : public QObject -{ - Q_OBJECT -public: - static QAptActions* self(); - void setActionCollection(KActionCollection* actions); - Q_DECL_DEPRECATED QWidget* mainWindow() const; - - bool reloadWhenSourcesEditorFinished() const; - bool isConnected() const; - void setOriginalState(QApt::CacheState state); - void setReloadWhenEditorFinished(bool reload); - void initError(); - void displayTransactionError(QApt::ErrorCode error, QApt::Transaction* trans); - KActionCollection* actionCollection(); - - void setCanExit(bool e) { m_canExit = e; } - bool canExit() const { return m_canExit; } - -Q_SIGNALS: - void shouldConnect(bool isConnected); - void changesReverted(); - void sourcesEditorClosed(bool reload); - void downloadArchives(QApt::Transaction *trans); - -public Q_SLOTS: - void setBackend(QApt::Backend *backend); - void setupActions(); - - // KAction slots - bool saveSelections(); - bool saveInstalledPackagesList(); - void loadSelections(); - bool createDownloadList(); - void downloadPackagesFromList(); - void loadArchives(); - void undo(); - void redo(); - void revertChanges(); - void runSourcesEditor(); - void sourcesEditorFinished(int exitStatus); - void showHistoryDialog(); - void setActionsEnabled(bool enabled = true); - -private Q_SLOTS: - void closeHistoryDialog(); - void checkDistUpgrade(); - void launchDistUpgrade(); - void checkerFinished(int res); - -private: - QAptActions(); - - QApt::Backend *m_backend; - QApt::CacheState m_originalState; - bool m_actionsDisabled; - KActionCollection* m_actionCollection; - bool m_reloadWhenEditorFinished; - - QPointer<QDialog> m_historyDialog; - QList<QAction *> m_actions; - bool m_distUpgradeAvailable; - QNetworkConfigurationManager* m_config; - bool m_canExit; - -}; - -#endif // QAPTACTIONS_H diff --git a/libdiscover/backends/ApplicationBackend/libmuonapt/policies/org.kde.muon.repo.action b/libdiscover/backends/ApplicationBackend/libmuonapt/policies/org.kde.muon.repo.action deleted file mode 100644 index dd6ad20..0000000 --- a/libdiscover/backends/ApplicationBackend/libmuonapt/policies/org.kde.muon.repo.action +++ /dev/null @@ -1,5 +0,0 @@ -[org.kde.muon.repo.modify] -Name=Add Repo -Description=The system is attempting to modify the sources -Policy=auth_admin -Persistence=session
\ No newline at end of file diff --git a/libdiscover/backends/ApplicationBackend/muonapplicationnotifier.notifyrc b/libdiscover/backends/ApplicationBackend/muonapplicationnotifier.notifyrc deleted file mode 100644 index 8b7400b..0000000 --- a/libdiscover/backends/ApplicationBackend/muonapplicationnotifier.notifyrc +++ /dev/null @@ -1,109 +0,0 @@ -[Global] -IconName=muondiscover -Comment=Muon Application Backend Notifier -Comment[ar]=مُخطر سند تطبيقات ميون -Comment[ca]=Notificador del dorsal d'aplicacions del Muon -Comment[ca@valencia]=Notificador del dorsal d'aplicacions del Muon -Comment[cs]=Podpůrná vrstva upozorňování pro Muon -Comment[da]=Muon-program-backend-bekendtgørelser -Comment[de]=Muon-Dienstprogramm für Anwendungs-Benachrichtigungen -Comment[el]=Πρόγραμμα ειδοποιήσεων εφαρμογών υποστήριξης Muon -Comment[en_GB]=Muon Application Backend Notifier -Comment[es]=Notificador del motor de la aplicación Muon -Comment[et]=Muoni rakenduse taustaprogrammi märguanded -Comment[fi]=Muonin sovellustaustajärjestelmän ilmoitukset -Comment[fr]=Notifieur du moteur de l'application Muon -Comment[gl]=Motor de notificacións de aplicacións de Muon -Comment[id]=Pemberitahu Backend Aplikasi Muon -Comment[it]=Notifiche motore applicazioni di Muon -Comment[ko]=Muon 프로그램 백엔드 알림이 -Comment[nb]=Muon varsler for program-bakgrunnsmotor -Comment[nl]=Muon backend van melder van toepassingen -Comment[nn]=Muon-varslar for program-bakgrunnsmotor -Comment[pl]=Silnik powiadamiania o programach Muon -Comment[pt]=Notificação da Infra-Estrutura de Aplicações do Muon -Comment[pt_BR]=Notificador da Infraestrutura de Aplicativos do Muon -Comment[ru]=Модуль уведомлений Muon -Comment[sk]=Backendový oznamovač aplikácií Muon -Comment[sl]=Zaledja obvestilnika za programe Muon -Comment[sr]=Муонова позадина за извештавање о програмима -Comment[sr@ijekavian]=Муонова позадина за извештавање о програмима -Comment[sr@ijekavianlatin]=Muonova pozadina za izveštavanje o programima -Comment[sr@latin]=Muonova pozadina za izveštavanje o programima -Comment[sv]=Muon programgränssnittsunderrättelser -Comment[uk]=Сповіщувач модуля програми Muon -Comment[x-test]=xxMuon Application Backend Notifierxx -Comment[zh_CN]=Muon 应用程序后端提示器 - -[Event/DistUpgrade] -Name=Upgrade Available -Name[ar]=التّرقيّة متوفّرة -Name[ca]=Hi ha una actualització disponible -Name[ca@valencia]=Hi ha una actualització disponible -Name[cs]=Dostupná aktualizace distribuce -Name[da]=Opgradering tilgængelig -Name[de]=Paketaktualisierung verfügbar -Name[el]=Διαθέσιμη αναβάθμιση -Name[en_GB]=Upgrade Available -Name[es]=Actualización disponible -Name[et]=Saadaval on uuendus -Name[fi]=Versiopäivitys saatavilla -Name[fr]=Mise à niveau disponible -Name[gl]=Dispoñíbel unha actualización -Name[he]=יש שדרוג זמים -Name[id]=Pembaruan Tersedia -Name[it]=Aggiornamento disponibile -Name[ko]=업그레이드 사용 가능 -Name[nb]=Oppgradering tilgjengelig -Name[nl]=Opwaardering beschikbaar -Name[nn]=Oppgradering tilgjengeleg -Name[pl]=Dostępne uaktualnienie -Name[pt]=Actualização Disponível -Name[pt_BR]=Atualização disponível -Name[ru]=Доступно обновление дистрибутива -Name[sk]=Dostupné vylepšenia systému -Name[sl]=Na voljo je nadgradnja -Name[sr]=Доступна надоградња -Name[sr@ijekavian]=Доступна надоградња -Name[sr@ijekavianlatin]=Dostupna nadogradnja -Name[sr@latin]=Dostupna nadogradnja -Name[sv]=Uppgradering tillgänglig -Name[uk]=Доступне оновлення дистрибутива -Name[x-test]=xxUpgrade Availablexx -Name[zh_CN]=更新可用 -Comment=A new version of Kubuntu is available -Comment[ar]=إصدارة جديدة من كوبونتو متوفّرة -Comment[ca]=Hi ha disponible una nova versió del Kubuntu -Comment[ca@valencia]=Hi ha disponible una nova versió del Kubuntu -Comment[cs]=Je dostupná nová verze Kubuntu -Comment[da]=En ny version af Kubuntu er tilgængelig -Comment[de]=Eine neue Version von Kubuntu ist verfügbar -Comment[el]=Μια νέα έκδοση του Kubuntu είναι διαθέσιμη -Comment[en_GB]=A new version of Kubuntu is available -Comment[es]=Está disponible una nueva versión de Kubuntu -Comment[et]=Saadaval on Kubuntu uus versioon -Comment[fi]=Uusi Kubuntun versio on saatavilla -Comment[fr]=Une nouvelle version de Kubuntu est disponible -Comment[gl]=Hai dispoñíbel unha nova versión de Kubuntu. -Comment[he]=גרסה חדשה של Kubuntu זמינה -Comment[id]=Sebuah versi baru Kubuntu telah tersedia -Comment[it]=È disponibile una nuova versione di Kubuntu -Comment[ko]=Kubuntu 새 버전 사용 가능 -Comment[nb]=En ny versjon av Kubuntu er tilgjengelig -Comment[nl]=Er is een nieuwe versie van Kubuntu beschikbaar -Comment[nn]=Ein ny versjon av Kubuntu er tilgjengeleg -Comment[pl]=Dostępna jest nowa wersja Kubuntu -Comment[pt]=Está disponível uma nova versão do Kubuntu -Comment[pt_BR]=Está disponível uma nova versão do Kubuntu -Comment[ru]=Доступна новая версия Kubuntu -Comment[sk]=Nová verzia Kubuntu je dostupná -Comment[sl]=Na voljo je nova različica Kubuntu -Comment[sr]=Доступно је ново издање Кубунтуа -Comment[sr@ijekavian]=Доступно је ново издање Кубунтуа -Comment[sr@ijekavianlatin]=Dostupno je novo izdanje Kubuntua -Comment[sr@latin]=Dostupno je novo izdanje Kubuntua -Comment[sv]=En ny version av Kubuntu är tillgänglig -Comment[uk]=Випущено нову версію Kubuntu -Comment[x-test]=xxA new version of Kubuntu is availablexx -Comment[zh_CN]=有新版本的 Kubuntu 可用 -Action=Popup diff --git a/libdiscover/backends/ApplicationBackend/qapt-backend-categories.xml b/libdiscover/backends/ApplicationBackend/qapt-backend-categories.xml deleted file mode 100644 index 80f310a..0000000 --- a/libdiscover/backends/ApplicationBackend/qapt-backend-categories.xml +++ /dev/null @@ -1,559 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Menu> - - <Menu> - <Name>Accessories</Name> - <Icon>applications-utilities</Icon> - <Include> - <And> - <Category>Utility</Category> - <Not><Category>Accessibility</Category></Not> - </And> - </Include> - </Menu> - - <Menu> - <Name>Accessibility</Name> - <Icon>preferences-desktop-accessibility</Icon> - <Include> - <And> - <Category>Accessibility</Category> - <Not><Category>Settings</Category></Not> - </And> - </Include> - </Menu> - - <Menu> - <Name>Developer Tools</Name> - <Icon>applications-development</Icon> - <Include> - <Or> - <Category>Development</Category> - <PkgSection>devel</PkgSection> - <PkgSection>restricted/devel</PkgSection> - <PkgSection>universe/devel</PkgSection> - <PkgSection>multiverse/devel</PkgSection> - </Or> - <Filename>emacs.desktop</Filename> - </Include> - - - <Menu> - <Name>Debugging</Name> - <Icon>tools-report-bug</Icon> - <Include> - <And> - <Category>Debugger</Category> - </And> - </Include> - </Menu> - - <Menu> - <Name>Graphic Interface Design</Name> - <Include> - <And> - <Category>GUIDesigner</Category> - </And> - </Include> - </Menu> - - <Menu> - <Name>Haskell</Name> - <Icon>text-x-haskell</Icon> - <Include> - <Or> - <PkgSection>haskell</PkgSection> - <PkgSection>restricted/haskell</PkgSection> - <PkgSection>universe/haskell</PkgSection> - <PkgSection>multiverse/haskell</PkgSection> - </Or> - </Include> - </Menu> - - <Menu> - <Name>IDEs</Name> - <Include> - <And> - <Category>IDE</Category> - </And> - </Include> - </Menu> - - <Menu> - <Name>Java</Name> - <Icon>application-x-java</Icon> - <Include> - <Or> - <PkgSection>java</PkgSection> - <PkgSection>restricted/java</PkgSection> - <PkgSection>universe/java</PkgSection> - <PkgSection>multiverse/java</PkgSection> - </Or> - </Include> - </Menu> - - <Menu> - <Name>Localization</Name> - <Icon>preferences-desktop-locale</Icon> - <Include> - <And> - <Category>Translation</Category> - </And> - </Include> - </Menu> - - <Menu> - <Name>Perl</Name> - <Include> - <Or> - <PkgSection>perl</PkgSection> - <PkgSection>restricted/perl</PkgSection> - <PkgSection>universe/perl</PkgSection> - <PkgSection>multiverse/perl</PkgSection> - </Or> - </Include> - </Menu> - - <Menu> - <Name>Profiling</Name> - <Include> - <Or> - <Category>Profiling</Category> - </Or> - </Include> - </Menu> - - <Menu> - <Name>Python</Name> - <Icon>text-x-python</Icon> - <Include> - <Or> - <PkgSection>python</PkgSection> - <PkgSection>restricted/python</PkgSection> - <PkgSection>universe/python</PkgSection> - <PkgSection>multiverse/python</PkgSection> - </Or> - </Include> - </Menu> - - <Menu> - <Name>Version Control</Name> - <Icon>text-x-patch</Icon> - <Include> - <Or> - <PkgSection>vcs</PkgSection> - <PkgSection>restricted/vcs</PkgSection> - <PkgSection>universe/vcs</PkgSection> - <PkgSection>multiverse/vcs</PkgSection> - <Category>RevisionControl</Category> - </Or> - </Include> - </Menu> - - <Menu> - <Name>Web Development</Name> - <Include> - <And> - <Category>WebDevelopment</Category> - </And> - </Include> - <Icon>applications-internet</Icon> - </Menu> - - </Menu> - - - <Menu> - <Name>Education</Name> - <Icon>applications-education</Icon> - <Include> - <And> - <Category>Education</Category> - <Not> - <Category>Science</Category> - </Not> - </And> - </Include> - </Menu> - - - <Menu> - <Name>Science & 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 & 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 & 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 & 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 & Settings</Name> - <Icon>preferences-system</Icon> - <Include> - <Or> - <Category>Settings</Category> - <Category>System</Category> - </Or> - </Include> - </Menu> - - <Menu> - <Name>Plasma Addons</Name> - <Icon>plasma</Icon> - - <Menu> - <Name>Plasma Desktop Widgets</Name> - <Icon>plasma</Icon> - <ShowTechnical>true</ShowTechnical> <!-- needs to be like this as plasmoids don't get a appinstall file for some reason. --> - <Include> - <Or> - <PkgWildcard>plasma-widget-*</PkgWildcard> - </Or> - </Include> - </Menu> - </Menu> - -</Menu> diff --git a/libdiscover/backends/ApplicationBackend/qapt-backend.desktop b/libdiscover/backends/ApplicationBackend/qapt-backend.desktop deleted file mode 100644 index 265f69f..0000000 --- a/libdiscover/backends/ApplicationBackend/qapt-backend.desktop +++ /dev/null @@ -1,111 +0,0 @@ -[Desktop Entry] -Type=Service -Exec=blubb -Icon=applications-other -Comment=Install and browse applications in APT -Comment[ar]=ثبّت التّطبيقات في APT وتصفّحها -Comment[ca]=Instal·la i mostra aplicacions en l'APT -Comment[ca@valencia]=Instal·la i mostra aplicacions en l'APT -Comment[cs]=Instalujte a prohlížejte aplikace v APT -Comment[da]=Installér og gennemse programmer i APT -Comment[de]=Anwendungen in APT installieren und durchsuchen -Comment[el]=Εγκαταστήστε και περιηγηθείτε σε εφαρμογές με το APT -Comment[en_GB]=Install and browse applications in APT -Comment[es]=Instalar y explorar aplicaciones en APT -Comment[et]=Rakenduste paigaldamine ja sirvimine APT-is -Comment[fi]=Asenna ja selaa APT:n välityksellä tarjolla olevia sovelluksia -Comment[fr]=Installer et parcourir des applications dans « APT » -Comment[gl]=Instalar e buscar aplicacións en APT -Comment[he]=התקן ודפדפף ביישומים ב־APT -Comment[id]=Pasang dan jelajahi aplikasi di APT -Comment[it]=Installa e sfoglia le applicazioni in APT -Comment[ko]=APT에서 프로그램을 찾고 설치하기 -Comment[nb]=Installer og bla i programmer i APT -Comment[nl]=Installeer en blader door toepassingen in APT -Comment[nn]=Installer og bla gjennom program i APT -Comment[pl]=Wgrywaj i przeglądaj programy w APT -Comment[pt]=Instalar e navegar nas aplicações do APT -Comment[pt_BR]=Instala e navega pelos aplicativos no APT -Comment[ru]=Установка и обзор приложений в APT -Comment[sk]=Inštalácia a prehliadanie aplikácií v APT -Comment[sl]=Namestite in brskajte po programih v APT -Comment[sr]=Инсталирајте и прегледајте програме из АПТ‑а -Comment[sr@ijekavian]=Инсталирајте и прегледајте програме из АПТ‑а -Comment[sr@ijekavianlatin]=Instalirajte i pregledajte programe iz APT‑a -Comment[sr@latin]=Instalirajte i pregledajte programe iz APT‑a -Comment[sv]=Installera och bläddra bland program med APT -Comment[uk]=Встановіть і перегляньте встановлені програми у APT -Comment[x-test]=xxInstall and browse applications in APTxx -Comment[zh_CN]=安装浏览 APT 中的程序 -Name=Applications Backend -Name[ar]=سند التّطبيقات -Name[ca]=Dorsal d'aplicacions -Name[ca@valencia]=Dorsal d'aplicacions -Name[cs]=Podpůrná vrstva aplikace -Name[da]=Program-backend -Name[de]=Dienstprogramm für Anwendungen -Name[el]=Σύστημα υποστήριξης εφαρμογών -Name[en_GB]=Applications Backend -Name[es]=Motor de aplicaciones -Name[et]=Rakenduse taustaprogramm -Name[fi]=Sovellukset-taustajärjestelmä -Name[fr]=Moteur des applications -Name[gl]=Infraestrutura de programas -Name[id]=Backend Aplikasi -Name[it]=Motore applicazioni -Name[ko]=프로그램 백엔드 -Name[nb]=Program-bakgrunnsmotor -Name[nl]=Backend van toepassing -Name[nn]=Program-bakgrunnsmotor -Name[pl]=Silnik programów -Name[pt]=Infra-Estrutura de Aplicações -Name[pt_BR]=Infraestrutura de aplicativos -Name[ru]=Модуль приложений -Name[sk]=Backend aplikácií -Name[sl]=Zaledje programov -Name[sr]=Позадина за програме -Name[sr@ijekavian]=Позадина за програме -Name[sr@ijekavianlatin]=Pozadina za programe -Name[sr@latin]=Pozadina za programe -Name[sv]=Programgränssnitt -Name[uk]=Модуль програм -Name[x-test]=xxApplications Backendxx -Name[zh_CN]=应用程序后端 -GenericName=APT Support -GenericName[ar]=دعم APT -GenericName[ca]=Implementació de l'APT -GenericName[ca@valencia]=Implementació de l'APT -GenericName[cs]=Podpora APT -GenericName[da]=APT-understøttelse -GenericName[de]=Unterstützung für APT -GenericName[el]=Υποστήριξη APT -GenericName[en_GB]=APT Support -GenericName[es]=Uso de APT -GenericName[et]=APT toetus -GenericName[fi]=APT-tuki -GenericName[fr]=Prise en charge de « APT » -GenericName[gl]=Soporte para APT -GenericName[he]=APT תומך -GenericName[id]=APT Support -GenericName[it]=Supporto APT -GenericName[ko]=APT 지원 -GenericName[nb]=APT-støtte -GenericName[nl]=Ondersteuning van APT -GenericName[nn]=APT-støtte -GenericName[pl]=Obsługa APT -GenericName[pt]=Suporte para o APT -GenericName[pt_BR]=Suporte ao APT -GenericName[ru]=Поддержка APT -GenericName[sk]=Podpora APT -GenericName[sl]=Podpora APT -GenericName[sr]=Подршка за АПТ -GenericName[sr@ijekavian]=Подршка за АПТ -GenericName[sr@ijekavianlatin]=Podrška za APT -GenericName[sr@latin]=Podrška za APT -GenericName[sv]=Stöd för APT -GenericName[uk]=Підтримка APT -GenericName[x-test]=xxAPT Supportxx -GenericName[zh_CN]=APT 支持 -X-KDE-Library=qapt-backend -X-KDE-PluginInfo-Name=qapt-backend -X-KDE-PluginInfo-License=GPL diff --git a/libdiscover/backends/ApplicationBackend/qoauth/CMakeLists.txt b/libdiscover/backends/ApplicationBackend/qoauth/CMakeLists.txt deleted file mode 100644 index 06c858a..0000000 --- a/libdiscover/backends/ApplicationBackend/qoauth/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -find_package(Qca-qt5 REQUIRED) - -add_library(MuonQOAuth STATIC src/interface.cpp) -target_link_libraries(MuonQOAuth PUBLIC Qt5::Network qca-qt5) -add_library(Muon::QOAuth ALIAS MuonQOAuth) diff --git a/libdiscover/backends/ApplicationBackend/qoauth/src/interface.cpp b/libdiscover/backends/ApplicationBackend/qoauth/src/interface.cpp deleted file mode 100644 index 179f729..0000000 --- a/libdiscover/backends/ApplicationBackend/qoauth/src/interface.cpp +++ /dev/null @@ -1,1084 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Dominik Kapusta <d@ayoy.net> * - * * - * This library is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation; either version 2.1 of * - * the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; if not, write to * - * the Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - - -#include "interface.h" -#include "interface_p.h" - -#include <QtCrypto> - -#include <QNetworkAccessManager> -#include <QNetworkRequest> -#include <QNetworkReply> -#include <QUrl> -#include <QDateTime> -#include <QtDebug> -#include <QEventLoop> -#include <QTimer> -#include <QFileInfo> - -/*! - \mainpage - - \section sec_what What is the purpose of QOAuth? - - The main motivation to create this library was to provide an interface to OAuth - protocol for (Qt-based) C++ applications in an easy way. This is very early version - of the library, and it lacks some functionality, but in the same time it is capable - of sending OAuth authorization requests as well as preparing requests for accessing - User's Protected Resources. - - \section sec_lic License and Authors - - The project is licensed under <a href=http://www.gnu.org/licenses/lgpl-2.1.html>GNU LGPL - license</a> version 2.1 or later. The work is done by Dominik Kapusta (d at ayoy dot net). - - \section sec_inst How to install? - - \subsection ssec_deps Dependencies - - There are a few things necessary to get OAuth library working: - - <ol> - <li>Qt libraries, version 4.4 or higher,</li> - <li>QCA (Qt Cryptographic Architecture), available from - <a href=http://delta.affinix.com/qca>Delta XMPP Project</a>, version 2.0.0 - or higher,</li> - <li>OpenSSL plugin to QCA (qca-ossl), available from QCA page, and requiring OpenSSL.</li> - </ol> - - \b Note: KDE4 users meet all the requirements out of the box. - - \subsection ssec_inst Installation - - The source code repository is hosted on <a href=http://github.com/ayoy/qoauth>GitHub</a> - and the code can be checked out from there easily using git: - \verbatim - $ git clone git://github.com/ayoy/qoauth.git \endverbatim - - To compile the code, follow the simple procedure: - - \verbatim - $ qmake - $ make - $ sudo make install \endverbatim - - \subsection ssec_use Usage - - Configuring your project to work with QOAuth library is extremely simple. Firstly, - append a line to your project file: - \verbatim - CONFIG += oauth \endverbatim - - Then include the following header in your code: - \verbatim - #include <QtOAuth> \endverbatim - - \b Note: This follows the Qt scheme, i.e. <tt>QT += xml ==> #include <QtXml></tt>, etc. - - \section sec_bugs Bugs and issues - - Please file all the bug reports to the QOAuth bug tracking system at - <a href="http://ayoy.lighthouseapp.com/projects/32547-qoauth/tickets?q=all"> - lighthouseapp.com</a>. If you wish to contribute, you're extremely welcome - to fork a <a href=http://github.com/ayoy/qoauth>GitHub</a> repository and - add your input there. - -*/ - -/*! - \class QOAuth::Interface interface.h <QtOAuth> - \brief This class provides means for interaction with network services supporting - OAuth authorization scheme. - - The QOAuth::Interface class is meant to enable OAuth support in applications in as simple way - as possible. It provides 4 basic methods, two of which serve for authorization purposes: - \li \ref requestToken(), - \li \ref accessToken(), - - and the other two help with creation of requests for accessing Protected Resources: - \li \ref createParametersString(), - \li \ref inlineParameters(). - - \section sec_auth_scheme OAuth authorization scheme - - According to <a href=http://oauth.net/core/1.0/#consumer_req_param> - OAuth 1.0 Core specification</a>, <em>the OAuth protocol enables websites or applications - (Consumers) to access Protected Resources from a web service (Service Provider) via an - API, without requiring Users to disclose their Service Provider credentials to the - Consumers</em>. Simply, OAuth is a way of connecting an application to the Service - Provider's API without needing to provide User's login or password. The authorization - is based on an exchange of a Token (user-specific) together with a Consumer Key - (application-specific), encrypted with a combination of so called Token Secret and - Customer Secret. Getting access to Protected Resources consists in three basic steps: - <ol> - <li>obtaining an unauthorized Request Token from the Service Provider,</li> - <li>asking the User to authorize the Request Token,</li> - <li>exchanging the Request Token for the Access Token.</li> - </ol> - Details are covered in <a href=http://oauth.net/core/1.0/#anchor9>Section 6</a> of the - OAuth 1.0 Core Specification. As the authorization procedure is quite complex, the QOAuth - library helps to simplify it by doing all the dirty work behind the scenes. - - \section sec_req_token OAuth authorization with QOAuth - - First step of OAuth authorization can be done in one line using QOAuth library. - Consult the example: - - \include requestToken.cpp - - Once the unauthorized Request Token is received, User has to authorize it using - Service Provider-defined method. This is beyond the scope of this library. Once User - authorizes the Request Token, it can be exchanged for an Access Token that authorizes the - application to access User's Protected Resources. This can be done with another one line: - - \include accessToken.cpp - - Once the Access Token is received, the application is authorized. - - \section sec_acc_res Requesting Protected Resources with QOAuth - - In order to access Protected Resources, the application has to send a request containing - arguments including Customer Key and Access Token, and encrypt them with Customer Secret - and Token Secret. The process of constructing such a request can be reduced to another - one-line call with QOAuth::Interface. The example code for inlining all request parameters - (both User-specific and OAuth-related): - - \include getResources.cpp - - If Service Provider requires the OAuth authorization to be done in the <tt>Authorization</tt> - header field, then only User-specific parameters should be inlined with the URL: - - \include getResources2.cpp - - \section sec_capabilities Capabilities - - QOAuth library works with all 3 signature methods supported by the OAuth protocol, namely - HMAC-SHA1, RSA-SHA1 and PLAINTEXT. Hovewer, RSA-SHA1 and (especially) PLAINTEXT - methods may still need additional testing for various input conditions. -*/ - - -QByteArray QOAuth::supportedOAuthVersion() -{ - return InterfacePrivate::OAuthVersion; -} - -QByteArray QOAuth::tokenParameterName() -{ - return InterfacePrivate::ParamToken; -} - -QByteArray QOAuth::tokenSecretParameterName() -{ - return InterfacePrivate::ParamTokenSecret; -} - - -//! \brief The supported OAuth scheme version. -const QByteArray QOAuth::InterfacePrivate::OAuthVersion = "1.0"; - -//! \brief The <em>token</em> request parameter string -const QByteArray QOAuth::InterfacePrivate::ParamToken = "oauth_token"; -//! \brief The <em>token secret</em> request parameter string -const QByteArray QOAuth::InterfacePrivate::ParamTokenSecret = "oauth_token_secret"; - -//! \brief The <em>consumer key</em> request parameter string -const QByteArray QOAuth::InterfacePrivate::ParamConsumerKey = "oauth_consumer_key"; -//! \brief The <em>nonce</em> request parameter string -const QByteArray QOAuth::InterfacePrivate::ParamNonce = "oauth_nonce"; -//! \brief The <em>signature</em> request parameter string -const QByteArray QOAuth::InterfacePrivate::ParamSignature = "oauth_signature"; -//! \brief The <em>signature method</em> request parameter string -const QByteArray QOAuth::InterfacePrivate::ParamSignatureMethod = "oauth_signature_method"; -//! \brief The <em>timestamp</em> request parameter string -const QByteArray QOAuth::InterfacePrivate::ParamTimestamp = "oauth_timestamp"; -//! \brief The <em>version</em> request parameter string -const QByteArray QOAuth::InterfacePrivate::ParamVersion = "oauth_version"; - -QOAuth::InterfacePrivate::InterfacePrivate() : - privateKeySet( false ), - consumerKey( QByteArray() ), - consumerSecret( QByteArray() ), - manager(0), - loop(0), - requestTimeout(0), - error( NoError ) -{ -} - -void QOAuth::InterfacePrivate::init() -{ - Q_Q(QOAuth::Interface); - - ignoreSslErrors = false; - loop = new QEventLoop(q); - setupNetworkAccessManager(); - - q->connect( &eventHandler, SIGNAL(eventReady(int,QCA::Event)), SLOT(_q_setPassphrase(int,QCA::Event)) ); - eventHandler.start(); -} - -void QOAuth::InterfacePrivate::setupNetworkAccessManager() -{ - Q_Q(QOAuth::Interface); - - if (manager == 0) - manager = new QNetworkAccessManager; - - manager->setParent(q); - q->connect(manager, &QNetworkAccessManager::finished, loop, &QEventLoop::quit); - q->connect(manager, SIGNAL(finished(QNetworkReply*)), SLOT(_q_parseReply(QNetworkReply*))); - q->connect(manager, SIGNAL(sslErrors(QNetworkReply*, QList<QSslError>)), SLOT(_q_handleSslErrors(QNetworkReply*, QList<QSslError>))); -} - -QByteArray QOAuth::InterfacePrivate::httpMethodToString( HttpMethod method ) -{ - switch ( method ) { - case GET: - return "GET"; - case POST: - return "POST"; - case HEAD: - return "HEAD"; - case PUT: - return "PUT"; -#ifndef Q_WS_WIN - case DELETE: - return "DELETE"; -#endif - default: - qWarning() << __FUNCTION__ << "- Unrecognized method"; - return QByteArray(); - } -} - -QByteArray QOAuth::InterfacePrivate::signatureMethodToString( SignatureMethod method ) -{ - switch ( method ) { - case HMAC_SHA1: - return "HMAC-SHA1"; - case RSA_SHA1: - return "RSA-SHA1"; - case PLAINTEXT: - return "PLAINTEXT"; - default: - qWarning() << __FUNCTION__ << "- Unrecognized method"; - return QByteArray(); - } -} - -QOAuth::ParamMap QOAuth::InterfacePrivate::replyToMap( const QByteArray &data ) -{ - // split reply to name=value strings - QList<QByteArray> replyParams = data.split( '&' ); - // we'll store them in a map - ParamMap parameters; - - QByteArray replyParam; - QByteArray key; - int separatorIndex; - - // iterate through name=value pairs - Q_FOREACH ( replyParam, replyParams ) { - // find occurrence of '=' - separatorIndex = replyParam.indexOf( '=' ); - // key is on the left - key = replyParam.left( separatorIndex ); - // value is on the right - parameters.insert( key , replyParam.right( replyParam.length() - separatorIndex - 1 ) ); - } - - return parameters; -} - -void QOAuth::InterfacePrivate::_q_parseReply( QNetworkReply *reply ) -{ - int returnCode = reply->attribute( QNetworkRequest::HttpStatusCodeAttribute ).toInt(); - - switch ( returnCode ) { - case NoError: - replyParams = replyToMap( reply->readAll() ); - if ( !replyParams.contains( InterfacePrivate::ParamToken ) ) { - qWarning() << __FUNCTION__ << "- oauth_token not present in reply!"; - } - if ( !replyParams.contains( InterfacePrivate::ParamTokenSecret ) ) { - qWarning() << __FUNCTION__ << "- oauth_token_secret not present in reply!"; - } - - case BadRequest: - case Unauthorized: - case Forbidden: - error = returnCode; - break; - default: - error = OtherError; - } - - reply->close(); -} - -void QOAuth::InterfacePrivate::_q_handleSslErrors(QNetworkReply *reply, const QList<QSslError> &errors) -{ - Q_UNUSED(errors); - - if (ignoreSslErrors) - reply->ignoreSslErrors(); -} - -QByteArray QOAuth::InterfacePrivate::paramsToString( const ParamMap ¶meters, 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 ¶ms ) -{ - 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 ¶ms ) -{ - 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 ¶ms, 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, ¶meters ); - - // 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 ¶ms, 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 ¶ms ) -{ - 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, ¶meters ); - - // if signature wasn't created, return an empty map - if ( error != NoError ) { - return ParamMap(); - } - - // add signature to parameters - parameters.insert( InterfacePrivate::ParamSignature, signature ); - - QByteArray authorizationHeader; - QNetworkRequest request; - - if ( httpMethod == GET ) { - authorizationHeader = paramsToString( parameters, ParseForHeaderArguments ); - // create the authorization header - request.setRawHeader( "Authorization", authorizationHeader ); - } else if ( httpMethod == POST ) { - authorizationHeader = paramsToString( parameters, ParseForRequestContent ); - // create a network request - request.setHeader( QNetworkRequest::ContentTypeHeader, QStringLiteral("application/x-www-form-urlencoded") ); - } - - request.setUrl( QUrl( requestUrl ) ); - - // fire up a single shot timer if timeout was specified - if ( requestTimeout > 0 ) { - QTimer::singleShot( requestTimeout, loop, SLOT(quit()) ); - // if the request finishes on time, the error value is overriden - // if not, it remains equal to QOAuth::Interface::Timeout - error = Timeout; - } - - // clear the reply container and send the request - replyParams.clear(); - QNetworkReply *reply; - if ( httpMethod == GET ) { - reply = manager->get( request ); - } else if ( httpMethod == POST ) { - reply = manager->post( request, authorizationHeader ); - } - - // start the event loop and wait for the response - loop->exec(); - - // if request completed successfully, error is different than QOAuth::Interface::Timeout - // if it failed, we have to abort the request - if ( error == Timeout ) { - reply->abort(); - } - - return replyParams; -} - -QByteArray QOAuth::InterfacePrivate::createSignature( const QString &requestUrl, HttpMethod httpMethod, - SignatureMethod signatureMethod, const QByteArray &token, - const QByteArray &tokenSecret, ParamMap *params ) -{ - if ( ( signatureMethod == HMAC_SHA1 || - signatureMethod == RSA_SHA1 ) && - consumerKey.isEmpty() ) { - qWarning() << __FUNCTION__ << "- consumer key is empty, make sure that you set it" - "with QOAuth::Interface::setConsumerKey()"; - error = ConsumerKeyEmpty; - return QByteArray(); - } - if ( consumerSecret.isEmpty() ) { - qWarning() << __FUNCTION__ << "- consumer secret is empty, make sure that you set it" - "with QOAuth::Interface::setConsumerSecret()"; - error = ConsumerSecretEmpty; - return QByteArray(); - } - - if ( signatureMethod == RSA_SHA1 && - privateKey.isNull() ) { - qWarning() << __FUNCTION__ << "- RSA private key is empty, make sure that you provide it" - "with QOAuth::Interface::setRSAPrivateKey{,FromFile}()"; - error = RSAPrivateKeyEmpty; - return QByteArray(); - } - - // create nonce - QCA::InitializationVector iv( 16 ); - QByteArray nonce = iv.toByteArray().toHex(); - - // create timestamp - uint time = QDateTime::currentDateTime().toTime_t(); - QByteArray timestamp = QByteArray::number( time ); - - // create signature base string - // 1. create the method string - QByteArray httpMethodString = httpMethodToString( httpMethod ); - // 2. prepare percent-encoded request URL - QByteArray percentRequestUrl = requestUrl.toLatin1().toPercentEncoding(); - // 3. prepare percent-encoded parameters string - params->insert( InterfacePrivate::ParamConsumerKey, consumerKey ); - params->insert( InterfacePrivate::ParamNonce, nonce ); - params->insert( InterfacePrivate::ParamSignatureMethod, - signatureMethodToString( signatureMethod ) ); - params->insert( InterfacePrivate::ParamTimestamp, timestamp ); - params->insert( InterfacePrivate::ParamVersion, InterfacePrivate::OAuthVersion ); - // append token only if it is defined (requestToken() doesn't use a token at all) - if ( !token.isEmpty() ) { - params->insert( InterfacePrivate::ParamToken, token ); - } - - QByteArray parametersString = paramsToString( *params, ParseForSignatureBaseString ); - QByteArray percentParametersString = parametersString.toPercentEncoding(); - - QByteArray digest; - - // PLAINTEXT doesn't use the Signature Base String - if ( signatureMethod == PLAINTEXT ) { - digest = createPlaintextSignature( tokenSecret ); - } else { - // 4. create signature base string - QByteArray signatureBaseString; - signatureBaseString.append( httpMethodString + '&' ); - signatureBaseString.append( percentRequestUrl + '&' ); - signatureBaseString.append( percentParametersString ); - - - if ( signatureMethod == HMAC_SHA1 ) { - if( !QCA::isSupported( "hmac(sha1)" ) ) { - qFatal( "HMAC(SHA1) is not supported!" ); - } - // create key for HMAC-SHA1 hashing - QByteArray key( consumerSecret.toPercentEncoding() + '&' + tokenSecret.toPercentEncoding() ); - - // create HMAC-SHA1 digest in Base64 - QCA::MessageAuthenticationCode hmac( QStringLiteral("hmac(sha1)"), QCA::SymmetricKey( key ) ); - QCA::SecureArray array( signatureBaseString ); - hmac.update( array ); - QCA::SecureArray resultArray = hmac.final(); - digest = resultArray.toByteArray().toBase64(); - - } else if ( signatureMethod == RSA_SHA1 ) { - // sign the Signature Base String with the RSA key - digest = privateKey.signMessage( QCA::MemoryRegion( signatureBaseString ), - QCA::EMSA3_SHA1 ).toBase64(); - } - } - - // percent-encode the digest - QByteArray signature = digest.toPercentEncoding(); - return signature; -} - -QByteArray QOAuth::InterfacePrivate::createPlaintextSignature( const QByteArray &tokenSecret ) -{ - if ( consumerSecret.isEmpty() ) { - qWarning() << __FUNCTION__ << "- consumer secret is empty, make sure that you set it" - "with QOAuth::Interface::setConsumerSecret()"; - error = ConsumerSecretEmpty; - return QByteArray(); - } - - // get percent encoded consumer secret and token secret, join and return - return consumerSecret.toPercentEncoding() + '&' + tokenSecret.toPercentEncoding(); -} - -#include "moc_interface.cpp" diff --git a/libdiscover/backends/ApplicationBackend/qoauth/src/interface.h b/libdiscover/backends/ApplicationBackend/qoauth/src/interface.h deleted file mode 100644 index bddc53d..0000000 --- a/libdiscover/backends/ApplicationBackend/qoauth/src/interface.h +++ /dev/null @@ -1,119 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Dominik Kapusta <d@ayoy.net> * - * * - * This library is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation; either version 2.1 of * - * the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; if not, write to * - * the Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - - -/*! - \file interface.h - - This file is a part of libqoauth. You should not include it directly in your - application. Instead please use <tt>\#include <QtOAuth></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 ¶ms = ParamMap() ); - - ParamMap accessToken( const QString &requestUrl, HttpMethod httpMethod, const QByteArray &token, - const QByteArray &tokenSecret, SignatureMethod signatureMethod = HMAC_SHA1, - const ParamMap ¶ms = ParamMap() ); - - QByteArray createParametersString( const QString &requestUrl, HttpMethod httpMethod, - const QByteArray &token, const QByteArray &tokenSecret, - SignatureMethod signatureMethod, const ParamMap ¶ms, ParsingMode mode ); - - QByteArray inlineParameters( const ParamMap ¶ms, ParsingMode mode = ParseForRequestContent ); - - -protected: - InterfacePrivate * const d_ptr; - -private: - Q_DISABLE_COPY(Interface) - Q_DECLARE_PRIVATE(Interface) - Q_PRIVATE_SLOT(d_func(), void _q_parseReply(QNetworkReply *reply)) - Q_PRIVATE_SLOT(d_func(), void _q_setPassphrase(int id, const QCA::Event &event)) - Q_PRIVATE_SLOT(d_func(), void _q_handleSslErrors( QNetworkReply *reply, - const QList<QSslError> &errors )) - -#ifdef UNIT_TEST - friend class Ut_Interface; - friend class Ft_Interface; -#endif -}; - -} // namespace QOAuth - -#endif // INTERFACE_H diff --git a/libdiscover/backends/ApplicationBackend/qoauth/src/interface_p.h b/libdiscover/backends/ApplicationBackend/qoauth/src/interface_p.h deleted file mode 100644 index 97f3a6e..0000000 --- a/libdiscover/backends/ApplicationBackend/qoauth/src/interface_p.h +++ /dev/null @@ -1,127 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Dominik Kapusta <d@ayoy.net> * - * * - * This library is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation; either version 2.1 of * - * the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; if not, write to * - * the Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - - -/*! - \file interface_p.h - - This file is a part of libqoauth and is considered strictly internal. You should not - include it in your application. Instead please use <tt>\#include <QtOAuth></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 ¶meters, 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 ¶ms ); - - // RSA-SHA1 stuff - void setPrivateKey( const QString &source, const QCA::SecureArray &passphrase, KeySource from ); - void readKeyFromLoader( QCA::KeyLoader *keyLoader ); - - bool privateKeySet; - - QCA::Initializer initializer; - QCA::PrivateKey privateKey; - QCA::SecureArray passphrase; - QCA::EventHandler eventHandler; - // end of RSA-SHA1 stuff - - bool ignoreSslErrors; - QByteArray consumerKey; - QByteArray consumerSecret; - - ParamMap replyParams; - - QPointer<QNetworkAccessManager> manager; - QEventLoop *loop; - - uint requestTimeout; - int error; - -protected: - Interface *q_ptr; - -public: - void _q_parseReply( QNetworkReply *reply ); - void _q_setPassphrase( int id, const QCA::Event &event ); - void _q_handleSslErrors( QNetworkReply *reply, const QList<QSslError> &errors ); -}; - -} // namespace QOAuth - -#endif // INTERFACE_P_H diff --git a/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_global.h b/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_global.h deleted file mode 100644 index 66c0d5b..0000000 --- a/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_global.h +++ /dev/null @@ -1,39 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Dominik Kapusta <d@ayoy.net> * - * * - * This library is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation; either version 2.1 of * - * the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; if not, write to * - * the Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - - -/*! - \file qoauth_global.h - - This file is a part of libqoauth and is considered strictly internal. You should not - include it in your application. Instead please use <tt>\#include <QtOAuth></tt>. -*/ - -#ifndef QOAUTH_GLOBAL_H -#define QOAUTH_GLOBAL_H - -#include <QtCore/qglobal.h> - -#if defined(QOAUTH) -# define QOAUTH_EXPORT Q_DECL_EXPORT -#else -# define QOAUTH_EXPORT Q_DECL_IMPORT -#endif - -#endif // QOAUTH_GLOBAL_H diff --git a/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_namespace.h b/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_namespace.h deleted file mode 100644 index fb2270b..0000000 --- a/libdiscover/backends/ApplicationBackend/qoauth/src/qoauth_namespace.h +++ /dev/null @@ -1,180 +0,0 @@ -/*************************************************************************** - * Copyright (C) 2009 by Dominik Kapusta <d@ayoy.net> * - * * - * This library is free software; you can redistribute it and/or modify * - * it under the terms of the GNU Lesser General Public License as * - * published by the Free Software Foundation; either version 2.1 of * - * the License, or (at your option) any later version. * - * * - * This library is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * - * Lesser General Public License for more details. * - * * - * You should have received a copy of the GNU Lesser General Public * - * License along with this library; if not, write to * - * the Free Software Foundation, Inc., * - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - ***************************************************************************/ - - -/*! - \file qoauth_namespace.h - - This file is a part of libqoauth. You should not include it directly in your - application. Instead please use <tt>\#include <QtOAuth></tt>. -*/ - -#ifndef QOAUTH_NAMESPACE_H -#define QOAUTH_NAMESPACE_H - -#include <QMultiMap> -#include <QByteArray> - -#include "qoauth_global.h" - -/*! - \namespace QOAuth - \brief This namespace encapsulates all classes and definitions provided by libqoauth. -*/ -namespace QOAuth { - - /*! - \typedef ParamMap - \brief A typedef for the data structure for storing request parameters - */ - typedef QMultiMap<QByteArray,QByteArray> ParamMap; - - /*! - \enum SignatureMethod - \brief This enum type describes the signature method used by the request. - - There are 3 different signature methods defined by the - <a href=http://oauth.net/core/1.0/#signing_process>OAuth protocol</a>. This enum - is used to specify the method used by a specific request. Hence, one of its values - must be passed as a parameter in any of the \ref QOAuth::Interface::requestToken(), - \ref QOAuth::Interface::accessToken() or \ref QOAuth::Interface::createParametersString() - method. - */ - enum SignatureMethod { - HMAC_SHA1, //!< Sets the signature method to HMAC-SHA1 - RSA_SHA1, //!< Sets the signature method to RSA-SHA1 (not implemented yet) - PLAINTEXT //!< Sets the signature method to PLAINTEXT (not implemented yet) - }; - - /*! - \enum HttpMethod - \brief This enum type specifies the HTTP method used for creating - a <a href=http://oauth.net/core/1.0/#anchor14>Signature Base String</a> - and/or sending a request. - - The HTTP method has to be specified in QOAuth class for two reasons: - \li to know what type of request should be prepared and sent - (\ref QOAuth::Interface::requestToken() and \ref QOAuth::Interface::accessToken()), - \li to prepare a correct signature, as the Signature Base String contains a parameter - specifying the HTTP method used for request (\ref QOAuth::Interface::createParametersString()). - - \note For \ref QOAuth::Interface::requestToken() and \ref QOAuth::Interface::accessToken() methods - only \ref GET and \ref POST methods are allowed. - */ - enum HttpMethod { - GET, //!< Sets the HTTP method to GET - POST, //!< Sets the HTTP method to POST - HEAD, //!< Sets the HTTP method to HEAD - PUT //!< Sets the HTTP method to PUT -#ifndef Q_WS_WIN - , DELETE //!< Sets the HTTP method to DELETE -#endif - }; - - /*! - \enum ParsingMode - \brief This enum type specifies the method of parsing parameters into - a parameter string. - - When creating a parameters string for a custom request using - \ref QOAuth::Interface::createParametersString() the parsing mode must be defined in order - to prepare the string correctly. - - According to what is stated in <a href=http://oauth.net/core/1.0/#consumer_req_param> - OAuth 1.0 Core specification</a>, parameters can be passed in a request to - the Service Provider in 3 different ways. When using \ref QOAuth::Interface::createParametersString(), - choose the one that suits you by setting \a ParsingMode appropriatelly. - - \sa QOAuth::Interface::createParametersString() - */ - enum ParsingMode { - ParseForRequestContent, //!< Inline query format (<tt>foo=bar&bar=baz&baz=foo ...</tt>), suitable for POST requests - ParseForInlineQuery, /*!< Same as ParseForRequestContent, but prepends the string with a question mark - - suitable for GET requests (appending parameters to the request URL) */ - ParseForHeaderArguments, //!< HTTP request header format (parameters to be put inside a request header) - ParseForSignatureBaseString //!< <a href=http://oauth.net/core/1.0/#anchor14>Signature Base String</a> format, meant for internal use. - }; - - /*! - \enum ErrorCode - \brief This enum type defines error types that are assigned to the - \ref QOAuth::Interface::error property - - This error codes collection contains both network-related errors and those that - can occur when incorrect arguments are provided to any of the class's methods. - - \sa QOAuth::Interface::error - */ - enum ErrorCode { - NoError = 200, //!< No error occured (so far :-) ) - BadRequest = 400, //!< Represents HTTP status code \c 400 (Bad Request) - Unauthorized = 401, //!< Represents HTTP status code \c 401 (Unauthorized) - Forbidden = 403, //!< Represents HTTP status code \c 403 (Forbidden) - Timeout = 1001, //!< Represents a request timeout error - ConsumerKeyEmpty, //!< Consumer key has not been provided - ConsumerSecretEmpty, //!< Consumer secret has not been provided - UnsupportedHttpMethod, /*!< The HTTP method is not supported by the request. - \note \ref QOAuth::Interface::requestToken() and - \ref QOAuth::Interface::accessToken() - accept only HTTP GET and POST requests. */ - - RSAPrivateKeyEmpty = 1101, //!< RSA private key has not been provided - // RSAPassphraseError, //!< RSA passphrase is incorrect (or has not been provided) - RSADecodingError, /*!< There was a problem decoding the RSA private key - (the key is invalid or the provided passphrase is incorrect)*/ - RSAKeyFileError, //!< The provided key file either doesn't exist or is unreadable. - OtherError //!< A network-related error not specified above - }; - - - /*! - \brief Returns the supported OAuth protocol version - */ - QOAUTH_EXPORT QByteArray supportedOAuthVersion(); - - /*! - \brief Returns the name of the Access Token argument parameter (<tt>oauth_token</tt> in - current implementation) - - Useful when reading Service Provider's reply for \ref QOAuth::Interface::accessToken() request, e.g: - \code - QOAuth::Interface qoauth; - QByteArray requestToken = "token"; - QByteArray requestTokenSecret = "secret"; - QOAuth::ParamMap reply = qoauth.accessToken( "http://example.com/access_token", QOAuth::POST, - token, tokenSecret, QOAuth::HMAC_SHA1 ); - - if ( qoauth.error() == QOAuth::NoError ) { - token = reply.value( QOAuth::tokenParameterName() ); - tokenSecret = reply.value( QOAuth::tokenSecretParameterName() ); - } - \endcode - */ - QOAUTH_EXPORT QByteArray tokenParameterName(); - - /*! - \brief Returns the name of the Token Secret argument parameter (<tt>oauth_token_secret</tt> in - current implementation) - \sa QOAuth::tokenParameterName() - */ - QOAUTH_EXPORT QByteArray tokenSecretParameterName(); - -} // namespace QOAuth - -#endif // QOAUTH_NAMESPACE_H diff --git a/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.cpp b/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.cpp deleted file mode 100644 index b17c15e..0000000 --- a/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.cpp +++ /dev/null @@ -1,154 +0,0 @@ -/*************************************************************************** - * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "ApplicationBackendTest.h" -#include <QStringList> -#include <QAction> -#include <QFile> -#include <KProtocolManager> -#include <KActionCollection> -#include <qtest.h> - -#include <tests/modeltest.h> -#include <ApplicationBackend.h> -#include <resources/ResourcesModel.h> -#include <resources/ResourcesProxyModel.h> -#include <resources/AbstractBackendUpdater.h> -#include <Category/Category.h> -#include <Category/CategoryModel.h> -#include <DiscoverBackendsFactory.h> -#include <KXmlGuiWindow> -#include <QAptActions.h> - -QTEST_MAIN( ApplicationBackendTest ) - -QString getCodename(const QString& value) -{ - QString ret; - QFile f(QStringLiteral("/etc/os-release")); - if(f.open(QIODevice::ReadOnly|QIODevice::Text)){ - QRegExp rx(QStringLiteral("%1=(.+)\n").arg(value)); - while(!f.atEnd()) { - QString line = QString::fromUtf8(f.readLine()); - if(rx.exactMatch(line)) { - ret = rx.cap(1); - break; - } - } - } - return ret; -} - -AbstractResourcesBackend* backendByName(ResourcesModel* m, const QString& name) -{ - QVector<AbstractResourcesBackend*> backends = m->backends(); - foreach(AbstractResourcesBackend* backend, backends) { - if(QString::fromLatin1(backend->metaObject()->className())==name) { - return backend; - } - } - return nullptr; -} - -ApplicationBackendTest::ApplicationBackendTest() -{ - QString ratingsDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+QStringLiteral("/libdiscover/ratings.txt"); - QFile testRatings(QStringLiteral("~/.kde-unit-test/share/apps/libdiscover/ratings.txt")); - QFile ratings(ratingsDir); - QString codeName = getCodename(QStringLiteral("ID")); - if(!testRatings.exists()) { - if(ratings.exists()) { - ratings.copy(testRatings.fileName()); - } else { - ratings.close(); - if(codeName.toLower() == QLatin1String("ubuntu")) { - ratingsDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+QStringLiteral("/libdiscover/rnrtestratings.txt"); - } else { - ratingsDir = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation)+QStringLiteral("/libdiscover/popcontestratings.txt"); - } - ratings.setFileName(ratingsDir); - if(ratings.exists()) { - ratings.copy(testRatings.fileName()); - } - } - testRatings.close(); - ratings.close(); - } - ResourcesModel* m = new ResourcesModel(QStringLiteral("qapt-backend"), this); - m_window = new KActionCollection(this, QStringLiteral("ApplicationBackendTest")); - m->integrateActions(m_window); - new ModelTest(m,m); - m_appBackend = backendByName(m, QStringLiteral("ApplicationBackend")); - QVERIFY(m_appBackend); //TODO: test all backends - QSignalSpy s(m, SIGNAL(allInitialized())); - QVERIFY(s.wait()); -} - -ApplicationBackendTest::~ApplicationBackendTest() -{ - delete m_window; -} - -void ApplicationBackendTest::testReload() -{ - ResourcesModel* model = ResourcesModel::global(); - QVector<AbstractResource*> apps = m_appBackend->allResources(); - QCOMPARE(apps.count(), model->rowCount()); - - QVector<QVariant> appNames(apps.size()); - for(int i=0; i<model->rowCount(); ++i) { - AbstractResource* app = apps[i]; - appNames[i]=app->property("packageName"); - } - - bool b = QMetaObject::invokeMethod(m_appBackend, "reload"); - QVERIFY(b); - m_appBackend->updatesCount(); - QCOMPARE(apps, m_appBackend->allResources() ); - - QVERIFY(!apps.isEmpty()); - QCOMPARE(apps.count(), model->rowCount()); - - for(int i=0; i<model->rowCount(); ++i) { - AbstractResource* app = apps[i]; - QCOMPARE(appNames[i], app->property("packageName")); -// QCOMPARE(m_model->data(m_model->index(i), ResourcesModel::NameRole).toString(), app->name()); - } -} - -void ApplicationBackendTest::testCategories() -{ - ResourcesProxyModel* proxy = new ResourcesProxyModel(this); - const auto cats = CategoryModel::rootCategories(); - for(auto cat: cats) { - proxy->setFiltersFromCategory(cat); - } -} - -void ApplicationBackendTest::testRefreshUpdates() -{ - ResourcesModel* m = ResourcesModel::global(); - - QSignalSpy spy(m, SIGNAL(fetchingChanged())); - m_window->action(QStringLiteral("update"))->trigger(); -// QTest::kWaitForSignal(m, SLOT(fetchingChanged())); - QVERIFY(!m->isFetching()); - qDebug() << spy.count(); -} diff --git a/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.h b/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.h deleted file mode 100644 index 420a395..0000000 --- a/libdiscover/backends/ApplicationBackend/tests/ApplicationBackendTest.h +++ /dev/null @@ -1,45 +0,0 @@ -/*************************************************************************** - * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef RESOURCESMODELTEST_H -#define RESOURCESMODELTEST_H - -#include <QtTest/QtTest> - -class KActionCollection; -class AbstractResourcesBackend; -class ApplicationBackendTest : public QObject -{ - Q_OBJECT - public: - ApplicationBackendTest(); - ~ApplicationBackendTest() override; - - private Q_SLOTS: - void testReload(); - void testCategories(); - void testRefreshUpdates(); - - private: - AbstractResourcesBackend* m_appBackend; - KActionCollection* m_window; -}; - -#endif diff --git a/libdiscover/backends/ApplicationBackend/tests/CMakeLists.txt b/libdiscover/backends/ApplicationBackend/tests/CMakeLists.txt deleted file mode 100644 index c60f87f..0000000 --- a/libdiscover/backends/ApplicationBackend/tests/CMakeLists.txt +++ /dev/null @@ -1,13 +0,0 @@ -include_directories(..) - -set(EXTRA_LIBS QApt::Main MuonApt) - -install(FILES rnrtestratings.txt DESTINATION ${DATA_INSTALL_DIR}/libdiscover) -install(FILES popcontestratings.txt DESTINATION ${DATA_INSTALL_DIR}/libdiscover) - -add_unit_test(applicationbackendtest ApplicationBackendTest.cpp) -add_unit_test(reviewstest ReviewsTest.cpp) -add_unit_test(sourcestest SourcesTest.cpp) - -list(APPEND EXTRA_LIBS DiscoverNotifiers MuonApplicationNotifierTestLib) -add_unit_test(notifiertest NotifierTest.cpp) diff --git a/libdiscover/backends/ApplicationBackend/tests/NotifierTest.cpp b/libdiscover/backends/ApplicationBackend/tests/NotifierTest.cpp deleted file mode 100644 index e9bd02d..0000000 --- a/libdiscover/backends/ApplicationBackend/tests/NotifierTest.cpp +++ /dev/null @@ -1,41 +0,0 @@ -/*************************************************************************** - * Copyright © 2015 Harald Sitter <sitter@kde.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "NotifierTest.h" - -#include <QTest> - -#include <ApplicationNotifier.h> - -QTEST_MAIN( NotifierTest ) - -NotifierTest::NotifierTest() -{ -} - -NotifierTest::~NotifierTest() = default; - -void NotifierTest::testInit() -{ - // Ensure init order is correct and we don't run into nullptr exceptions on - // initialization. - ApplicationNotifier app(this); - app.metaObject()->invokeMethod(&app, "recheckSystemUpdateNeeded"); -} diff --git a/libdiscover/backends/ApplicationBackend/tests/NotifierTest.h b/libdiscover/backends/ApplicationBackend/tests/NotifierTest.h deleted file mode 100644 index e225a03..0000000 --- a/libdiscover/backends/ApplicationBackend/tests/NotifierTest.h +++ /dev/null @@ -1,37 +0,0 @@ -/*************************************************************************** - * Copyright © 2015 Harald Sitter <sitter@kde.org> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef NOTIFIERTEST_H -#define NOTIFIERTEST_H - -#include <QtTest/QtTest> - -class NotifierTest : public QObject -{ - Q_OBJECT - public: - NotifierTest(); - ~NotifierTest() override; - - private Q_SLOTS: - void testInit(); -}; - -#endif diff --git a/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.cpp b/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.cpp deleted file mode 100644 index 4d6c2cb..0000000 --- a/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.cpp +++ /dev/null @@ -1,90 +0,0 @@ -/*************************************************************************** - * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "ReviewsTest.h" -#include <tests/modeltest.h> -#include <ReviewsBackend/ReviewsModel.h> -#include <qapt/backend.h> -#include <KProtocolManager> -#include <qtest.h> -#include <ReviewsBackend/AbstractReviewsBackend.h> -#include <DiscoverBackendsFactory.h> -#include <resources/AbstractResourcesBackend.h> -#include <resources/ResourcesModel.h> -#include <QSignalSpy> -#include <KActionCollection> - -QTEST_MAIN( ReviewsTest ) - -AbstractResourcesBackend* backendByName(ResourcesModel* m, const QString& name) -{ - QVector<AbstractResourcesBackend*> backends = m->backends(); - foreach(AbstractResourcesBackend* backend, backends) { - if(QString::fromLatin1(backend->metaObject()->className())==name) { - return backend; - } - } - return nullptr; -} - -ReviewsTest::ReviewsTest(QObject* parent): QObject(parent) -{ - ResourcesModel* m = new ResourcesModel(QStringLiteral("qapt-backend"), this); - m_window = new KActionCollection(this, QStringLiteral("ReviewsTest")); - m->integrateActions(m_window); - m_appBackend = backendByName(m, QStringLiteral("ApplicationBackend")); - QVERIFY(QSignalSpy(m, SIGNAL(allInitialized())).wait()); - m_revBackend = m_appBackend->reviewsBackend(); -} - -void ReviewsTest::testReviewsFetch() -{ - if(m_revBackend->isFetching()) - QSignalSpy(m_revBackend, SIGNAL(ratingsReady())).wait(); - QVERIFY(!m_revBackend->isFetching()); -} - -void ReviewsTest::testReviewsModel_data() -{ - QTest::addColumn<QString>( "application" ); - QTest::newRow( "python" ) << QStringLiteral("python"); - QTest::newRow( "gedit" ) << QStringLiteral("gedit"); -} - -void ReviewsTest::testReviewsModel() -{ - QFETCH(QString, application); - ReviewsModel* model = new ReviewsModel(this); - new ModelTest(model, model); - - AbstractResource* app = m_appBackend->resourceByPackageName(application); - QVERIFY(app); - model->setResource(app); - QSignalSpy(model, SIGNAL(rowsInserted(QModelIndex,int,int))).wait(2000); - - QModelIndex root; - while(model->canFetchMore(root)) { - model->fetchMore(root); - bool arrived = QSignalSpy(model, SIGNAL(rowsInserted(QModelIndex,int,int))).wait(2000); - QCOMPARE(arrived, model->canFetchMore(root)); - } - - delete model; -} diff --git a/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.h b/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.h deleted file mode 100644 index 7c638e5..0000000 --- a/libdiscover/backends/ApplicationBackend/tests/ReviewsTest.h +++ /dev/null @@ -1,52 +0,0 @@ -/*************************************************************************** - * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef REVIEWSTEST_H -#define REVIEWSTEST_H - -#include <QtCore/QObject> - -class KActionCollection; -class AbstractResourcesBackend; -class AbstractReviewsBackend; -namespace QApt { -class Backend; -} - -class ReviewsTest : public QObject -{ - Q_OBJECT - public: - explicit ReviewsTest(QObject* parent = nullptr); - - private Q_SLOTS: - void testReviewsFetch(); - - void testReviewsModel_data(); - void testReviewsModel(); - - private: - AbstractReviewsBackend* m_revBackend; - AbstractResourcesBackend* m_appBackend; - KActionCollection* m_window; - -}; - -#endif // REVIEWSTEST_H diff --git a/libdiscover/backends/ApplicationBackend/tests/SourcesTest.cpp b/libdiscover/backends/ApplicationBackend/tests/SourcesTest.cpp deleted file mode 100644 index f55d049..0000000 --- a/libdiscover/backends/ApplicationBackend/tests/SourcesTest.cpp +++ /dev/null @@ -1,101 +0,0 @@ -/*************************************************************************** - * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#include "SourcesTest.h" -#include <tests/modeltest.h> -#include <ReviewsBackend/ReviewsModel.h> -#include <qapt/backend.h> -#include <KProtocolManager> -#include <KActionCollection> -#include <qtest.h> -#include <ReviewsBackend/AbstractReviewsBackend.h> -#include <DiscoverBackendsFactory.h> -#include <resources/AbstractResourcesBackend.h> -#include <resources/ResourcesModel.h> -#include <resources/SourcesModel.h> -#include <resources/AbstractSourcesBackend.h> -#include <QSignalSpy> - -QTEST_MAIN( SourcesTest ) - -AbstractResourcesBackend* backendByName(ResourcesModel* m, const QString& name) -{ - QVector<AbstractResourcesBackend*> backends = m->backends(); - foreach(AbstractResourcesBackend* backend, backends) { - if(QString::fromLatin1(backend->metaObject()->className()) == name) { - return backend; - } - } - return nullptr; -} - -SourcesTest::SourcesTest(QObject* parent): QObject(parent) -{ - ResourcesModel* m = new ResourcesModel(QStringLiteral("qapt-backend"), this); - m_window = new KActionCollection(this, QStringLiteral("SourcesTest")); - m->integrateActions(m_window); - m_appBackend = backendByName(m, QStringLiteral("ApplicationBackend")); - QVERIFY(QSignalSpy(m, SIGNAL(allInitialized())).wait()); - - SourcesModel* sources = SourcesModel::global(); - QVERIFY(sources->rowCount() == 1); - QVERIFY(!backend()->name().isEmpty()); -} - -AbstractSourcesBackend* SourcesTest::backend() const -{ - SourcesModel* sources = SourcesModel::global(); - QObject* l = sources->data(sources->index(0), SourcesModel::SourceBackend).value<QObject*>(); - return qobject_cast<AbstractSourcesBackend*>(l); -} - - -void SourcesTest::testSourcesFetch() -{ - QAbstractItemModel* aptSources = backend()->sources(); - - for(int i = 0, c=aptSources->rowCount(); i<c; ++i) { - QVERIFY(aptSources); - QModelIndex idx = aptSources->index(i, 0); - QVERIFY(idx.data(Qt::DisplayRole).toString() != QString()); - } -} - -void SourcesTest::testResourcesMatchSources() -{ - QAbstractItemModel* aptSources = backend()->sources(); - QSet<QString> allSources; - for (int i=0, c=aptSources->rowCount(); i<c; ++i) { - QModelIndex idx = aptSources->index(i, 0); - allSources += idx.data(Qt::DisplayRole).toString(); - } - - ResourcesModel* rmodel = ResourcesModel::global(); - for (int i=0, c=rmodel->rowCount(); i<c; ++i) { - QModelIndex idx = rmodel->index(i, 0); - QString origin = idx.data(ResourcesModel::OriginRole).toString(); - bool found = allSources.contains(origin); - if (!found) { - qDebug() << "couldn't find" << origin << "for" << idx.data(ResourcesModel::NameRole).toString() << "@" << i << "/" << c << "in" << allSources; - QEXPECT_FAIL("", "I need to ask the Kubuntu guys, I don't understand", Continue); - } - QVERIFY(found); - } -} diff --git a/libdiscover/backends/ApplicationBackend/tests/SourcesTest.h b/libdiscover/backends/ApplicationBackend/tests/SourcesTest.h deleted file mode 100644 index 10217a0..0000000 --- a/libdiscover/backends/ApplicationBackend/tests/SourcesTest.h +++ /dev/null @@ -1,48 +0,0 @@ -/*************************************************************************** - * Copyright © 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com> * - * * - * This program is free software; you can redistribute it and/or * - * modify it under the terms of the GNU General Public License as * - * published by the Free Software Foundation; either version 2 of * - * the License or (at your option) version 3 or any later version * - * accepted by the membership of KDE e.V. (or its successor approved * - * by the membership of KDE e.V.), which shall act as a proxy * - * defined in Section 14 of version 3 of the license. * - * * - * This program is distributed in the hope that it will be useful, * - * but WITHOUT ANY WARRANTY; without even the implied warranty of * - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * - * GNU General Public License for more details. * - * * - * You should have received a copy of the GNU General Public License * - * along with this program. If not, see <http://www.gnu.org/licenses/>. * - ***************************************************************************/ - -#ifndef SOURCESTEST_H -#define SOURCESTEST_H - -#include <QtCore/QObject> - -class KActionCollection; -class AbstractSourcesBackend; -class AbstractResourcesBackend; - -class SourcesTest : public QObject -{ - Q_OBJECT - public: - explicit SourcesTest(QObject* parent = nullptr); - - private Q_SLOTS: - void testSourcesFetch(); - void testResourcesMatchSources(); - - private: - AbstractSourcesBackend* backend() const; - - AbstractResourcesBackend* m_appBackend; - KActionCollection* m_window; - -}; - -#endif // REVIEWSTEST_H diff --git a/libdiscover/backends/ApplicationBackend/tests/popcontestratings.txt b/libdiscover/backends/ApplicationBackend/tests/popcontestratings.txt Binary files differdeleted file mode 100644 index 4266691..0000000 --- a/libdiscover/backends/ApplicationBackend/tests/popcontestratings.txt +++ /dev/null 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<QString,QString>"/> - </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<QString,QString>"/> - </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<QString,QString>"/> - <arg direction="out" type="a{ss}" /> - <annotation name="com.trolltech.QtDBus.QtTypeName.Out0" value="QMap<QString,QString>"/> - </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<QString,QString>"/> - </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<QString,QString>"/> - </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<QString,QString>"/> - </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<QString,QString>"/> - </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<QString,QString>"/> - </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<QString,QString>"/> - </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() |
