186 lines
7.3 KiB
C++
186 lines
7.3 KiB
C++
#include "updatelookup.h"
|
|
#include "manager.h"
|
|
#include "database.h"
|
|
#include "config.h"
|
|
|
|
#include <QNetworkReply>
|
|
#include <QtConcurrent/QtConcurrent>
|
|
|
|
#include <initializer_list>
|
|
|
|
using namespace std;
|
|
|
|
namespace PackageManagement {
|
|
|
|
UpdateLookup::UpdateLookup(const Manager &manager, const QJsonObject &request, const UpdateLookupCallback callback, QObject *parent) :
|
|
QObject(parent),
|
|
m_manager(manager),
|
|
m_request(request),
|
|
m_callback(callback),
|
|
m_db(nullptr),
|
|
m_syncDbsWatcher(new QFutureWatcher<UpdateLookupResults<AlpmPackage> >(this)),
|
|
m_aurWatcher(new QFutureWatcher<UpdateLookupResults<AurPackage> >(this)),
|
|
m_aurReply(nullptr),
|
|
m_sourcesAvailable(false)
|
|
{
|
|
QJsonArray errors;
|
|
const auto dbName = request.value(QStringLiteral("db")).toString();
|
|
try {
|
|
m_db = &manager.dataBaseByName(dbName);
|
|
} catch (const out_of_range &) {
|
|
errors << QStringLiteral("Database \"%1\" can not be found.").arg(dbName);
|
|
}
|
|
if(errors.isEmpty()) {
|
|
// invoke syncdb lookup
|
|
connect(m_syncDbsWatcher, &QFutureWatcher<UpdateLookupResults<AlpmPackage> >::finished, this, &UpdateLookup::lookupDone);
|
|
m_syncDbsWatcher->setFuture(QtConcurrent::run(this, &UpdateLookup::checkSyncDbs, request.value(QStringLiteral("syncdbs"))));
|
|
// invoke AUR lookup
|
|
if(m_db->upgradeSources().contains(QStringLiteral("aur"), Qt::CaseInsensitive) || request.value(QStringLiteral("aur")).toBool(false)) {
|
|
if(manager.config().isAurEnabled()) {
|
|
connect(&m_manager.aurQuery(), &AurQuery::packageInfoAvailable, this, &UpdateLookup::aurPackageInfoAvailable);
|
|
connect(m_aurWatcher, &QFutureWatcher<UpdateLookupResults<AurPackage> >::finished, this, &UpdateLookup::lookupDone);
|
|
if(!(m_aurReply = m_manager.aurQuery().requestPackageInfo(m_db->packageNames()))) {
|
|
aurPackageInfoAvailable(nullptr);
|
|
}
|
|
} else {
|
|
errors << QStringLiteral("The AUR is configured as upgrade source for the database \"%1\" but AUR queries are not enabled.").arg(dbName);
|
|
}
|
|
}
|
|
} else {
|
|
QJsonObject results;
|
|
results.insert(QStringLiteral("errors"), errors);
|
|
callback(move(results));
|
|
deleteLater();
|
|
}
|
|
}
|
|
|
|
UpdateLookupResults<AlpmPackage> UpdateLookup::checkSyncDbs(const QJsonValue &syncDbsValue)
|
|
{
|
|
UpdateLookupResults<AlpmPackage> results;
|
|
const auto &syncDbs = m_manager.syncDataBases();
|
|
QList<const AlpmDataBase *> syncDbSel;
|
|
if(syncDbsValue.type() == QJsonValue::Array) {
|
|
for(const auto &syncDbVal : syncDbsValue.toArray()) {
|
|
const auto syncDbName = syncDbVal.toString();
|
|
if(syncDbName == QLatin1String("local")) {
|
|
syncDbSel << &(m_manager.localDataBase());
|
|
} else if(syncDbName == QLatin1String("aur")) {
|
|
continue; // the AUR is checked separately
|
|
} else {
|
|
try {
|
|
syncDbSel << &(syncDbs.at(syncDbName));
|
|
} catch(out_of_range &) {
|
|
results.warnings << QStringLiteral("The specified sync database \"%1\" can not be found.").arg(syncDbName);
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
for(const auto &syncDbName : m_db->upgradeSources()) {
|
|
if(syncDbName == QLatin1String("local")) {
|
|
syncDbSel << &(m_manager.localDataBase());
|
|
} else if(syncDbName == QLatin1String("aur")) {
|
|
continue; // the AUR is checked separately
|
|
} else {
|
|
try {
|
|
syncDbSel << &(syncDbs.at(syncDbName));
|
|
} catch(out_of_range &) {
|
|
results.warnings << QStringLiteral("The associated upgrade database \"%1\" can not be found.").arg(syncDbName);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
m_db->checkForUpgrades(syncDbSel, results);
|
|
return results;
|
|
}
|
|
|
|
void UpdateLookup::aurPackageInfoAvailable(const QNetworkReply *reply)
|
|
{
|
|
// check whether the package info requested by THIS INSTANCE is available
|
|
if(m_aurReply == reply) {
|
|
m_aurWatcher->setFuture(QtConcurrent::run(this, &UpdateLookup::checkAur));
|
|
}
|
|
}
|
|
|
|
UpdateLookupResults<AurPackage> UpdateLookup::checkAur()
|
|
{
|
|
UpdateLookupResults<AurPackage> results;
|
|
m_db->checkForUpgrades(m_manager.aurQuery().packages(), results);
|
|
return results;
|
|
}
|
|
|
|
void UpdateLookup::lookupDone()
|
|
{
|
|
const auto *sender = this->sender();
|
|
if(sender == static_cast<QObject *>(m_syncDbsWatcher)) {
|
|
// add results from syncdb lookup
|
|
m_syncDbsResults = m_syncDbsWatcher->result();
|
|
if(!m_syncDbsResults.noSources) {
|
|
m_sourcesAvailable = true;
|
|
for(const auto pkg : m_syncDbsResults.newVersions) {
|
|
m_softwareUpdates << pkg.json();
|
|
}
|
|
for(const auto pkg : m_syncDbsResults.newReleases) {
|
|
m_packageOnlyUpdates << pkg.json();
|
|
}
|
|
for(const auto pkg : m_syncDbsResults.downgrades) {
|
|
m_downgrades << pkg.json();
|
|
}
|
|
for(const auto &warning : m_syncDbsResults.warnings) {
|
|
m_warnings << warning;
|
|
}
|
|
for(const auto &error : m_syncDbsResults.errors) {
|
|
m_errors << error;
|
|
}
|
|
}
|
|
} else if(sender == static_cast<QObject *>(m_aurWatcher)) {
|
|
// add results from AUR lookup
|
|
m_aurResults = m_aurWatcher->result();
|
|
if(!m_aurResults.noSources) {
|
|
m_sourcesAvailable = true;
|
|
for(const auto pkg : m_aurResults.newVersions) {
|
|
m_softwareUpdates << pkg.json();
|
|
}
|
|
for(const auto pkg : m_aurResults.newReleases) {
|
|
m_packageOnlyUpdates << pkg.json();
|
|
}
|
|
for(const auto pkg : m_aurResults.downgrades) {
|
|
m_downgrades << pkg.json();
|
|
}
|
|
for(const auto &warning : m_aurResults.warnings) {
|
|
m_warnings << warning;
|
|
}
|
|
for(const auto &error : m_aurResults.errors) {
|
|
m_errors << error;
|
|
}
|
|
}
|
|
}
|
|
// check whether everything is done
|
|
if(m_syncDbsWatcher->isFinished() && (!m_aurReply || m_aurWatcher->isFinished())) {
|
|
QJsonObject results;
|
|
// determine orphaned packages
|
|
for(const auto pkg : m_aurReply ? m_aurResults.orphaned.intersect(m_syncDbsResults.orphaned) : m_syncDbsResults.orphaned) {
|
|
m_orphanedPackages << pkg.basicInfo(true);
|
|
}
|
|
// add results to results QJsonObject
|
|
results.insert(QStringLiteral("softwareUpdates"), m_softwareUpdates);
|
|
results.insert(QStringLiteral("packageOnlyUpdates"), m_packageOnlyUpdates);
|
|
results.insert(QStringLiteral("downgrades"), m_downgrades);
|
|
results.insert(QStringLiteral("orphanedPackages"), m_orphanedPackages);
|
|
if(!m_sourcesAvailable) {
|
|
m_errors << QStringLiteral("No update sources associated for database \"%1\".").arg(QString::fromLocal8Bit(m_db->name()));
|
|
}
|
|
if(!m_warnings.isEmpty()) {
|
|
results.insert(QStringLiteral("warnings"), m_warnings);
|
|
}
|
|
if(!m_errors.isEmpty()) {
|
|
results.insert(QStringLiteral("errors"), m_errors);
|
|
}
|
|
m_callback(move(results));
|
|
// lookup done, delete this helper object
|
|
deleteLater();
|
|
}
|
|
}
|
|
|
|
} // namespace PackageManagement
|
|
|