This commit is contained in:
Martchus 2015-09-27 19:29:45 +02:00
parent 715633c96e
commit a48a6fd656
20 changed files with 405 additions and 167 deletions

View File

@ -16,25 +16,11 @@ namespace RepoIndex {
/*! /*!
* \brief Creates a new instance from the specified "AurJson value". * \brief Creates a new instance from the specified "AurJson value".
*/ */
AurPackage::AurPackage(const QJsonValue &aurJsonValue, UserRepository *repository) : AurPackage::AurPackage(const QJsonObject &aurJsonObject, UserRepository *repository) :
Package(QString(), repository) Package(QString(), repository)
{ {
m_origin = PackageOrigin::Aur; m_origin = PackageOrigin::Aur;
QJsonObject obj = aurJsonValue.toObject(); putJson(aurJsonObject);
m_name = obj.value(QStringLiteral("Name")).toString();
m_hasGeneralInfo = true;
m_id = obj.value(QStringLiteral("ID")).toInt(-1);
m_categoryId = obj.value(QStringLiteral("CategoryID")).toInt(-1);
m_version = obj.value(QStringLiteral("Version")).toString();
m_description = obj.value(QStringLiteral("Description")).toString();
m_upstreamUrl = obj.value(QStringLiteral("URL")).toString();
m_votes = obj.value(QStringLiteral("NumVotes")).toInt(0);
m_outOfDate = DateTime::fromTimeStamp(obj.value(QStringLiteral("OutOfDate")).toInt());
m_maintainer = obj.value(QStringLiteral("Maintainer")).toString();
m_firstSubmitted = DateTime::fromTimeStamp(obj.value(QStringLiteral("FirstSubmitted")).toInt());
m_lastModified = DateTime::fromTimeStamp(obj.value(QStringLiteral("LastModified")).toInt());
m_licenses << obj.value(QStringLiteral("License")).toString();
m_tarUrl = obj.value(QStringLiteral("URLPath")).toString();
} }
/*! /*!
@ -52,5 +38,24 @@ AurPackage::AurPackage(UserRepository *repository) :
Package(QString(), repository) Package(QString(), repository)
{} {}
void AurPackage::putJson(const QJsonObject &aurJsonObject)
{
m_name = aurJsonObject.value(QStringLiteral("Name")).toString();
m_hasGeneralInfo = true;
m_id = aurJsonObject.value(QStringLiteral("ID")).toInt(-1);
m_categoryId = aurJsonObject.value(QStringLiteral("CategoryID")).toInt(-1);
m_version = aurJsonObject.value(QStringLiteral("Version")).toString();
m_description = aurJsonObject.value(QStringLiteral("Description")).toString();
m_upstreamUrl = aurJsonObject.value(QStringLiteral("URL")).toString();
m_votes = aurJsonObject.value(QStringLiteral("NumVotes")).toInt(0);
m_outOfDate = DateTime::fromTimeStamp(aurJsonObject.value(QStringLiteral("OutOfDate")).toInt());
m_maintainer = aurJsonObject.value(QStringLiteral("Maintainer")).toString();
m_firstSubmitted = DateTime::fromTimeStamp(aurJsonObject.value(QStringLiteral("FirstSubmitted")).toInt());
m_lastModified = DateTime::fromTimeStamp(aurJsonObject.value(QStringLiteral("LastModified")).toInt());
m_licenses.clear();
m_licenses << aurJsonObject.value(QStringLiteral("License")).toString();
m_tarUrl = aurJsonObject.value(QStringLiteral("URLPath")).toString();
}
} // namespace PackageManagement } // namespace PackageManagement

View File

@ -10,9 +10,11 @@ class UserRepository;
class AurPackage : public Package class AurPackage : public Package
{ {
public: public:
explicit AurPackage(const QJsonValue &aurJsonValue, UserRepository *repository); explicit AurPackage(const QJsonObject &aurJsonObject, UserRepository *repository);
explicit AurPackage(const QString &name, UserRepository *repository); explicit AurPackage(const QString &name, UserRepository *repository);
explicit AurPackage(UserRepository *repository); explicit AurPackage(UserRepository *repository);
void putJson(const QJsonObject &aurJsonObject);
}; };
} // namespace PackageManagement } // namespace PackageManagement

View File

@ -594,6 +594,8 @@ const QJsonObject &Manager::basicRepoInfo() const
/*! /*!
* \brief Returns package information for the specified selection of packages. * \brief Returns package information for the specified selection of packages.
* \remarks Does not request any information and hence will only return information
* which does not need to be requested or has been requested yet.
*/ */
const QJsonArray Manager::packageInfo(const QJsonObject &pkgSelection, PackageInfoPart part) const const QJsonArray Manager::packageInfo(const QJsonObject &pkgSelection, PackageInfoPart part) const
{ {

View File

@ -140,13 +140,15 @@ struct RelevantFile
data(file->data()), data(file->data()),
fileType(type), fileType(type),
arch(arch), arch(arch),
subDir(subDir) subDir(subDir),
symlinkTarget(file->symLinkTarget())
{} {}
QString name; QString name;
QByteArray data; QByteArray data;
RelevantFileType fileType; RelevantFileType fileType;
RelevantFileArch arch; RelevantFileArch arch;
QString subDir; QString subDir;
QString symlinkTarget;
}; };
struct PkgFileInfo struct PkgFileInfo
@ -341,30 +343,43 @@ void makeArchive(const list<PkgFileInfo> &pkgFiles, const QByteArray &pkgList, c
for(const auto &pkgFile : pkgFiles) { for(const auto &pkgFile : pkgFiles) {
for(const RelevantFile &relevantFile : pkgFile.relevantFiles) { for(const RelevantFile &relevantFile : pkgFile.relevantFiles) {
if(relevantFile.arch == RelevantFileArch::Any || relevantFile.arch == arch) { if(relevantFile.arch == RelevantFileArch::Any || relevantFile.arch == arch) {
QString path;
mode_t mode;
switch(relevantFile.fileType) { switch(relevantFile.fileType) {
case RelevantFileType::Binary: case RelevantFileType::Binary:
targetArchive->writeFile(root % QStringLiteral("/bin/") % relevantFile.name, relevantFile.data, 0100755); path = root % QStringLiteral("/bin/") % relevantFile.name;
mode = 0100755;
break; break;
case RelevantFileType::Translation: case RelevantFileType::Translation:
targetArchive->writeFile(root % QStringLiteral("/share/") % pkgFile.name % QStringLiteral("/translations/") % relevantFile.name, relevantFile.data, 0100644); path = root % QStringLiteral("/share/") % pkgFile.name % QStringLiteral("/translations/") % relevantFile.name;
mode = 0100644;
break; break;
case RelevantFileType::QtTranslation: case RelevantFileType::QtTranslation:
targetArchive->writeFile(root % QStringLiteral("/share/qt/translations/") % relevantFile.name, relevantFile.data, 0100644); path = root % QStringLiteral("/share/qt/translations/") % relevantFile.name;
mode = 0100644;
break; break;
case RelevantFileType::QtPlugin: case RelevantFileType::QtPlugin:
targetArchive->writeFile(root % QStringLiteral("/bin/") % relevantFile.subDir % QChar('/') % relevantFile.name, relevantFile.data, 0100755); path = root % QStringLiteral("/bin/") % relevantFile.subDir % QChar('/') % relevantFile.name;
mode = 0100755;
break; break;
case RelevantFileType::IconTheme: case RelevantFileType::IconTheme:
targetArchive->writeFile(root % QStringLiteral("/share/icons/") % relevantFile.subDir % QChar('/') % relevantFile.name, relevantFile.data, 0100644); path = root % QStringLiteral("/share/icons/") % relevantFile.subDir % QChar('/') % relevantFile.name;
mode = 0100644;
break; break;
case RelevantFileType::ConfigFile: case RelevantFileType::ConfigFile:
if(relevantFile.subDir.isEmpty()) { if(relevantFile.subDir.isEmpty()) {
targetArchive->writeFile(root % QStringLiteral("/share/") % pkgFile.name % QChar('/') % relevantFile.name, relevantFile.data, 0100644); path = root % QStringLiteral("/share/") % pkgFile.name % QChar('/') % relevantFile.name;
} else { } else {
targetArchive->writeFile(root % QStringLiteral("/share/") % pkgFile.name % QChar('/') % relevantFile.subDir % QChar('/') % relevantFile.name, relevantFile.data, 0100644); path = root % QStringLiteral("/share/") % pkgFile.name % QChar('/') % relevantFile.subDir % QChar('/') % relevantFile.name;
} }
mode = 0100644;
break; break;
} }
if(relevantFile.symlinkTarget.isEmpty()) {
targetArchive->writeFile(path, relevantFile.data, mode);
} else {
targetArchive->writeSymLink(path, relevantFile.symlinkTarget, QString(), QString(), mode);
}
} }
} }
} }

View File

@ -175,31 +175,8 @@ inline void put(QJsonObject &obj, const QString &key, const QStringList &values)
void put(QJsonObject &obj, const QString &key, const QList<Dependency> &dependencies) void put(QJsonObject &obj, const QString &key, const QList<Dependency> &dependencies)
{ {
QJsonArray jsonArray; QJsonArray jsonArray;
for(const auto &dep : dependencies) { for(const auto &dependency : dependencies) {
QJsonObject depObj; jsonArray << dependency.toJson();
depObj.insert(QStringLiteral("name"), dep.name);
depObj.insert(QStringLiteral("ver"), dep.version);
switch(dep.mode) {
case ALPM_DEP_MOD_ANY:
depObj.insert(QStringLiteral("mod"), QStringLiteral("any"));
break;
case ALPM_DEP_MOD_EQ:
depObj.insert(QStringLiteral("mod"), QStringLiteral("eq"));
break;
case ALPM_DEP_MOD_GE:
depObj.insert(QStringLiteral("mod"), QStringLiteral("ge"));
break;
case ALPM_DEP_MOD_LE:
depObj.insert(QStringLiteral("mod"), QStringLiteral("le"));
break;
case ALPM_DEP_MOD_GT:
depObj.insert(QStringLiteral("mod"), QStringLiteral("gt"));
break;
case ALPM_DEP_MOD_LT:
depObj.insert(QStringLiteral("mod"), QStringLiteral("lt"));
break;
}
jsonArray << depObj;
} }
put(obj, key, jsonArray); put(obj, key, jsonArray);
} }
@ -560,8 +537,8 @@ PackageVersionPartComparsion PackageVersion::compareParts(const QString &part1,
// determine current segments // determine current segments
part1End = part1.indexOf(nonAlphanumericPattern, part1Pos); part1End = part1.indexOf(nonAlphanumericPattern, part1Pos);
part2End = part2.indexOf(nonAlphanumericPattern, part2Pos); part2End = part2.indexOf(nonAlphanumericPattern, part2Pos);
auto segment1 = part1.midRef(part1Pos, part1End); auto segment1 = part1.midRef(part1Pos, part1End >= 0 ? part1End - part1Pos : -1);
auto segment2 = part2.midRef(part2Pos, part2End); auto segment2 = part2.midRef(part2Pos, part2End >= 0 ? part2End - part2Pos : -1);
// compare current segments // compare current segments
int digit1 = segment1.size(); int digit1 = segment1.size();
int digit2 = segment2.size(); int digit2 = segment2.size();
@ -638,39 +615,81 @@ PackageVersionComparsion PackageVersion::compare(const PackageVersion &other) co
*/ */
Dependency::Dependency(const QString &dependency) Dependency::Dependency(const QString &dependency)
{ {
int descrBeg = dependency.lastIndexOf(QChar(':'));
QStringRef actualDependency;
if(descrBeg > 0) {
description = dependency.midRef(descrBeg + 1).trimmed().toString();
actualDependency = dependency.midRef(0, descrBeg);
} else {
actualDependency = QStringRef(&dependency);
}
int suffixBeg; int suffixBeg;
if((suffixBeg = dependency.lastIndexOf(QLatin1String(">="))) > 0) { if((suffixBeg = actualDependency.lastIndexOf(QLatin1String(">="))) > 0) {
mode = ALPM_DEP_MOD_GE; mode = ALPM_DEP_MOD_GE;
} else if((suffixBeg = dependency.lastIndexOf(QLatin1String("<="))) > 0) { } else if((suffixBeg = actualDependency.lastIndexOf(QLatin1String("<="))) > 0) {
mode = ALPM_DEP_MOD_LE; mode = ALPM_DEP_MOD_LE;
} else if((suffixBeg = dependency.lastIndexOf(QChar('='))) > 0) { } else if((suffixBeg = actualDependency.lastIndexOf(QChar('='))) > 0) {
mode = ALPM_DEP_MOD_EQ; mode = ALPM_DEP_MOD_EQ;
} else if((suffixBeg = dependency.lastIndexOf(QChar('<'))) > 0) { } else if((suffixBeg = actualDependency.lastIndexOf(QChar('<'))) > 0) {
mode = ALPM_DEP_MOD_LT; mode = ALPM_DEP_MOD_LT;
} else if((suffixBeg = dependency.lastIndexOf(QChar('>'))) > 0) { } else if((suffixBeg = actualDependency.lastIndexOf(QChar('>'))) > 0) {
mode = ALPM_DEP_MOD_GT; mode = ALPM_DEP_MOD_GT;
} else { } else {
mode = ALPM_DEP_MOD_ANY; mode = ALPM_DEP_MOD_ANY;
} }
switch(mode) { switch(mode) {
case ALPM_DEP_MOD_ANY: case ALPM_DEP_MOD_ANY:
name = dependency; name = actualDependency.toString();
break; break;
case ALPM_DEP_MOD_GE: case ALPM_DEP_MOD_GE:
case ALPM_DEP_MOD_LE: case ALPM_DEP_MOD_LE:
name = dependency.mid(0, suffixBeg); name = actualDependency.mid(0, suffixBeg).toString();
version = dependency.mid(suffixBeg + 2); version = actualDependency.mid(suffixBeg + 2).toString();
break; break;
case ALPM_DEP_MOD_EQ: case ALPM_DEP_MOD_EQ:
case ALPM_DEP_MOD_LT: case ALPM_DEP_MOD_LT:
case ALPM_DEP_MOD_GT: case ALPM_DEP_MOD_GT:
name = dependency.mid(0, suffixBeg); name = actualDependency.mid(0, suffixBeg).toString();
version = dependency.mid(suffixBeg + 1); version = actualDependency.mid(suffixBeg + 1).toString();
break; break;
default: default:
; ;
} }
} }
/*!
* \brief Returns a JSON object for the current instance.
*/
QJsonObject Dependency::toJson() const
{
QJsonObject obj;
obj.insert(QStringLiteral("name"), name);
obj.insert(QStringLiteral("ver"), version);
switch(mode) {
case ALPM_DEP_MOD_ANY:
obj.insert(QStringLiteral("mod"), QStringLiteral("any"));
break;
case ALPM_DEP_MOD_EQ:
obj.insert(QStringLiteral("mod"), QStringLiteral("eq"));
break;
case ALPM_DEP_MOD_GE:
obj.insert(QStringLiteral("mod"), QStringLiteral("ge"));
break;
case ALPM_DEP_MOD_LE:
obj.insert(QStringLiteral("mod"), QStringLiteral("le"));
break;
case ALPM_DEP_MOD_GT:
obj.insert(QStringLiteral("mod"), QStringLiteral("gt"));
break;
case ALPM_DEP_MOD_LT:
obj.insert(QStringLiteral("mod"), QStringLiteral("lt"));
break;
}
if(!description.isEmpty()) {
obj.insert(QStringLiteral("desc"), description);
}
return obj;
}
} }

View File

@ -78,17 +78,22 @@ public:
class Dependency class Dependency
{ {
public: public:
explicit Dependency(const QString &name, const QString &version, _alpm_depmod_t mode = ALPM_DEP_MOD_ANY); explicit Dependency(const QString &name, const QString &version, _alpm_depmod_t mode = ALPM_DEP_MOD_ANY, const QString &description = QString());
explicit Dependency(const QString &dependency); explicit Dependency(const QString &dependency);
QJsonObject toJson() const;
QString name; QString name;
QString version; QString version;
_alpm_depmod_t mode; _alpm_depmod_t mode;
QString description;
}; };
inline Dependency::Dependency(const QString &name, const QString &version, _alpm_depmod_t mode) : inline Dependency::Dependency(const QString &name, const QString &version, _alpm_depmod_t mode, const QString &description) :
name(name), name(name),
version(version), version(version),
mode(mode) mode(mode),
description(description)
{} {}
class Manager; class Manager;

View File

@ -0,0 +1,52 @@
#include "./packageinfolookup.h"
#include "./repository.h"
namespace RepoIndex {
PackageInfoLookup::PackageInfoLookup(Manager &manager, const QJsonObject &packageSelection, Manager::PackageInfoPart part, QObject *parent) :
PackageLookup(parent)
{
if(part != Manager::None) {
for(auto i = packageSelection.constBegin(), end = packageSelection.constEnd(); i != end; ++i) {
if(auto *repo = manager.repositoryByName(i.key())) {
QStringList packagesToBeRequested;
for(const auto &entry : i.value().toArray()) {
const auto entryObj = entry.toObject();
const auto pkgName = entryObj.value(QStringLiteral("name")).toString();
if(!pkgName.isEmpty()) {
packagesToBeRequested << pkgName;
}
}
if(!packagesToBeRequested.isEmpty()) {
if(const auto *reply = (part & Manager::Details ? repo->requestFullPackageInfo(packagesToBeRequested) : repo->requestPackageInfo(packagesToBeRequested))) {
connect(reply, &PackageReply::resultsAvailable, this, &PackageInfoLookup::addResults);
++m_remainingReplies;
} else {
// no need to request any of the packages
}
}
} else {
// specified repository can not be found
QJsonObject errorObj;
errorObj.insert(QStringLiteral("repo"), i.key());
errorObj.insert(QStringLiteral("error"), QStringLiteral("na"));
m_results << errorObj;
}
}
}
}
void PackageInfoLookup::addResults()
{
assert(m_remainingReplies);
auto *reply = static_cast<PackageReply *>(sender());
m_results << reply->;
reply->deleteLater();
if(!--m_remainingReplies) {
emit resultsAvailable(QStringLiteral("pkginfo"), m_id, m_results);
deleteLater();
}
}
} // namespace RepoIndex

24
alpm/packageinfolookup.h Normal file
View File

@ -0,0 +1,24 @@
#ifndef REPOINDEX_PACKAGEINFOLOOKUP_H
#define REPOINDEX_PACKAGEINFOLOOKUP_H
#include "./packagelookup.h"
#include "./manager.h"
namespace RepoIndex {
class PackageInfoLookup : public PackageLookup
{
Q_OBJECT
public:
explicit PackageInfoLookup(Manager &manager, const QJsonObject &packageSelection, Manager::PackageInfoPart part, QObject *parent = nullptr);
private:
void addResults();
QList<Package *> m_packages;
};
} // namespace RepoIndex
#endif // REPOINDEX_PACKAGEINFOLOOKUP_H

4
alpm/packagelookup.cpp Normal file
View File

@ -0,0 +1,4 @@
#include "./packagelookup.h"

48
alpm/packagelookup.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef PACKAGELOOKUP_H
#define PACKAGELOOKUP_H
#include <QObject>
#include <QJsonArray>
#include <QJsonValue>
class PackageLookup : public QObject
{
Q_OBJECT
public:
explicit PackageLookup(QObject *parent = nullptr);
const QJsonArray &errors() const;
const QJsonArray &results() const;
bool finished() const;
signals:
void resultsAvailable(const QJsonValue &what, const QJsonValue &id, const QJsonValue &value);
protected:
unsigned int m_remainingReplies;
QJsonValue m_id;
QJsonArray m_errors;
QJsonArray m_results;
};
inline PackageLookup::PackageLookup(QObject *parent) :
QObject(parent),
m_remainingReplies(0)
{}
inline const QJsonArray &PackageLookup::errors() const
{
return m_errors;
}
inline const QJsonArray &PackageLookup::results() const
{
return m_results;
}
inline bool PackageLookup::finished() const
{
return !m_remainingReplies && m_errors.isEmpty();
}
#endif // PACKAGELOOKUP_H

View File

@ -60,7 +60,7 @@ const QStringList RepoIndex::Repository::packageNames() const
* \returns Returns a reply object used for the request. The reply must be destroyed by the caller * \returns Returns a reply object used for the request. The reply must be destroyed by the caller
* using destroyLater() after resultsAvailable() has been emitted. * using destroyLater() after resultsAvailable() has been emitted.
*/ */
SuggestionsReply *Repository::requestSuggestions(const QString &) const SuggestionsReply *Repository::requestSuggestions(const QString &)
{ {
return nullptr; return nullptr;
} }
@ -114,7 +114,7 @@ PackageDetailAvailability Repository::requestsRequired(PackageDetail ) const
* requested again. If it turns out, that all packages are already cached, nullptr * requested again. If it turns out, that all packages are already cached, nullptr
* is returned in this case. * is returned in this case.
*/ */
PackageReply *Repository::requestPackageInfo(const QStringList &, bool ) const PackageReply *Repository::requestPackageInfo(const QStringList &, bool )
{ {
return nullptr; return nullptr;
} }
@ -129,7 +129,7 @@ PackageReply *Repository::requestPackageInfo(const QStringList &, bool ) const
* requested again. If it turns out, that all packages are already cached, nullptr * requested again. If it turns out, that all packages are already cached, nullptr
* is returned in this case. * is returned in this case.
*/ */
PackageReply *Repository::requestFullPackageInfo(const QStringList &, bool ) const PackageReply *Repository::requestFullPackageInfo(const QStringList &, bool )
{ {
return nullptr; return nullptr;
} }
@ -258,12 +258,17 @@ QFuture<void> Repository::computeRequiredBy(Manager &manager, bool forceUpdate)
QJsonObject Repository::suggestions(const QString &term) const QJsonObject Repository::suggestions(const QString &term) const
{ {
QJsonArray suggestions; QJsonArray suggestions;
size_t remainingSuggestions = 20; // size_t remainingSuggestions = 20;
for(auto i = packages().lower_bound(term), end = packages().cend(); i != end && remainingSuggestions; ++i, --remainingSuggestions) { // for(auto i = packages().lower_bound(term), end = packages().cend(); i != end && remainingSuggestions; ++i, --remainingSuggestions) {
if(i->first.startsWith(term, Qt::CaseInsensitive)) { // if(i->first.startsWith(term, Qt::CaseInsensitive)) {
suggestions << i->first; // suggestions << i->first;
} else { // } else {
break; // break;
// }
// }
for(const auto &pkgEntry : packages()) {
if(pkgEntry.first.compare(term, Qt::CaseInsensitive) == 0) {
suggestions << pkgEntry.first;
} }
} }
QJsonObject res; QJsonObject res;
@ -281,7 +286,7 @@ QJsonArray Repository::upgradeSourcesJsonArray() const
return sources; return sources;
} }
void Repository::checkForUpgrades(UpgradeLookupResults &results, const QList<const Repository *> &upgradeSources) const void Repository::checkForUpgrades(UpgradeLookupResults &results, const QList<Repository *> &upgradeSources) const
{ {
if(upgradeSources.isEmpty()) { if(upgradeSources.isEmpty()) {
results.noSources = true; results.noSources = true;
@ -450,7 +455,7 @@ void Repository::restoreFromCacheStream(QDataStream &in)
in >> packageCount; in >> packageCount;
bool good = true; bool good = true;
for(quint32 i = 0; i < packageCount && good && in.status() == QDataStream::Ok; ++i) { for(quint32 i = 0; i < packageCount && good && in.status() == QDataStream::Ok; ++i) {
if(unique_ptr<Package> package = emptyPackage()) { if(auto package = emptyPackage()) {
package->restoreFromCacheStream(in); package->restoreFromCacheStream(in);
if(!package->name().isEmpty()) { if(!package->name().isEmpty()) {
m_packages[package->name()] = move(package); m_packages[package->name()] = move(package);
@ -514,8 +519,9 @@ void Repository::restoreSpecificCacheHeader(QDataStream &in)
/*! /*!
* \brief Adds a package parsed from the specified \a srcInfo. * \brief Adds a package parsed from the specified \a srcInfo.
* \returns Returns the packages.
*/ */
void Repository::addPackagesFromSrcInfo(const QByteArray &srcInfo) QList<Package *> Repository::addPackagesFromSrcInfo(const QByteArray &srcInfo)
{ {
enum { enum {
FieldName, FieldName,
@ -528,6 +534,7 @@ void Repository::addPackagesFromSrcInfo(const QByteArray &srcInfo)
QString packageBase; QString packageBase;
QList<QPair<QString, QString> > baseInfo; QList<QPair<QString, QString> > baseInfo;
QList<QPair<QString, QString> > packageInfo; QList<QPair<QString, QString> > packageInfo;
QList<Package *> packages;
Package *currentPackage = nullptr; Package *currentPackage = nullptr;
for(char c : srcInfo) { for(char c : srcInfo) {
switch(state) { switch(state) {
@ -538,9 +545,9 @@ void Repository::addPackagesFromSrcInfo(const QByteArray &srcInfo)
state = EquationSign; state = EquationSign;
} }
break; break;
case '\n': case '\r': case '\n': case '\r': case '\t':
if(!currentFieldName.isEmpty()) { if(!currentFieldName.isEmpty()) {
// TODO: handle error - field name contains newline character // TODO: handle error - field name contains invalid char character
} }
break; break;
default: default:
@ -579,6 +586,7 @@ void Repository::addPackagesFromSrcInfo(const QByteArray &srcInfo)
} else { } else {
if(currentPackage) { if(currentPackage) {
currentPackage->putInfo(baseInfo, packageInfo); currentPackage->putInfo(baseInfo, packageInfo);
packages << currentPackage;
} }
auto &pkg = m_packages[currentFieldValue]; auto &pkg = m_packages[currentFieldValue];
if(!pkg) { if(!pkg) {
@ -604,7 +612,9 @@ void Repository::addPackagesFromSrcInfo(const QByteArray &srcInfo)
} }
if(currentPackage) { if(currentPackage) {
currentPackage->putInfo(baseInfo, packageInfo); currentPackage->putInfo(baseInfo, packageInfo);
packages << currentPackage;
} }
return packages;
} }

View File

@ -145,9 +145,9 @@ public:
// gathering data // gathering data
virtual PackageDetailAvailability requestsRequired(PackageDetail packageDetail = PackageDetail::Basics) const; virtual PackageDetailAvailability requestsRequired(PackageDetail packageDetail = PackageDetail::Basics) const;
virtual SuggestionsReply *requestSuggestions(const QString &phrase) const; virtual SuggestionsReply *requestSuggestions(const QString &phrase);
virtual PackageReply *requestPackageInfo(const QStringList &packageNames, bool forceUpdate = false) const; virtual PackageReply *requestPackageInfo(const QStringList &packageNames, bool forceUpdate = false);
virtual PackageReply *requestFullPackageInfo(const QStringList &package, bool forceUpdate = false) const; virtual PackageReply *requestFullPackageInfo(const QStringList &packageNames, bool forceUpdate = false);
// package search // package search
const Package *packageByName(const QString &name) const; const Package *packageByName(const QString &name) const;
@ -160,11 +160,11 @@ public:
QJsonObject suggestions(const QString &term) const; QJsonObject suggestions(const QString &term) const;
// upgrade lookup // upgrade lookup
const QList<const Repository *> &upgradeSources() const; const QList<Repository *> &upgradeSources() const;
QList<const Repository *> &upgradeSources(); QList<Repository *> &upgradeSources();
QJsonArray upgradeSourcesJsonArray() const; QJsonArray upgradeSourcesJsonArray() const;
void checkForUpgrades(UpgradeLookupResults &results) const; void checkForUpgrades(UpgradeLookupResults &results) const;
void checkForUpgrades(UpgradeLookupResults &results, const QList<const Repository *> &upgradeSources) const; void checkForUpgrades(UpgradeLookupResults &results, const QList<Repository *> &upgradeSources) const;
// build system // build system
const QString &sourcesDirectory() const; const QString &sourcesDirectory() const;
@ -187,7 +187,7 @@ public:
virtual void restoreSpecificCacheHeader(QDataStream &in); virtual void restoreSpecificCacheHeader(QDataStream &in);
// parsing src/pkg info // parsing src/pkg info
void addPackagesFromSrcInfo(const QByteArray &srcInfo); QList<Package *> addPackagesFromSrcInfo(const QByteArray &srcInfo);
static const uint32 invalidIndex = static_cast<uint32>(-1); static const uint32 invalidIndex = static_cast<uint32>(-1);
@ -203,7 +203,7 @@ protected:
std::map<QString, QList<Package *> > m_groups; std::map<QString, QList<Package *> > m_groups;
QStringList m_serverUrls; QStringList m_serverUrls;
alpm_siglevel_t m_sigLevel; alpm_siglevel_t m_sigLevel;
QList<const Repository *> m_upgradeSources; QList<Repository *> m_upgradeSources;
QString m_srcDir; QString m_srcDir;
QString m_pkgDir; QString m_pkgDir;
}; };
@ -331,12 +331,12 @@ inline alpm_siglevel_t Repository::sigLevel() const
return m_sigLevel; return m_sigLevel;
} }
inline const QList<const Repository *> &Repository::upgradeSources() const inline const QList<Repository *> &Repository::upgradeSources() const
{ {
return m_upgradeSources; return m_upgradeSources;
} }
inline QList<const Repository *> &Repository::upgradeSources() inline QList<Repository *> &Repository::upgradeSources()
{ {
return m_upgradeSources; return m_upgradeSources;
} }

View File

@ -9,8 +9,8 @@
namespace RepoIndex { namespace RepoIndex {
SuggestionsLookup::SuggestionsLookup(Manager &manager, const QJsonObject &request) : SuggestionsLookup::SuggestionsLookup(Manager &manager, const QJsonObject &request, QObject *parent) :
m_remainingReplies(0) PackageLookup(parent)
{ {
m_id = request.value(QStringLiteral("id")); m_id = request.value(QStringLiteral("id"));
const auto searchTerm = request.value(QStringLiteral("term")).toString(); const auto searchTerm = request.value(QStringLiteral("term")).toString();
@ -23,7 +23,7 @@ SuggestionsLookup::SuggestionsLookup(Manager &manager, const QJsonObject &reques
} }
if(m_errors.isEmpty()) { if(m_errors.isEmpty()) {
for(const auto &repoName : repos) { for(const auto &repoName : repos) {
if(const Repository *repo = manager.repositoryByName(repoName.toString())) { if(auto *repo = manager.repositoryByName(repoName.toString())) {
if(const auto *reply = repo->requestSuggestions(searchTerm)) { if(const auto *reply = repo->requestSuggestions(searchTerm)) {
connect(reply, &SuggestionsReply::resultsAvailable, this, &SuggestionsLookup::addResults); connect(reply, &SuggestionsReply::resultsAvailable, this, &SuggestionsLookup::addResults);
++m_remainingReplies; ++m_remainingReplies;

View File

@ -1,51 +1,22 @@
#ifndef REPOINDEX_SUGGESTIONSLOOKUP_H #ifndef REPOINDEX_SUGGESTIONSLOOKUP_H
#define REPOINDEX_SUGGESTIONSLOOKUP_H #define REPOINDEX_SUGGESTIONSLOOKUP_H
#include <QObject> #include "./packagelookup.h"
#include <QJsonArray>
#include <QJsonValue>
namespace RepoIndex { namespace RepoIndex {
class Manager; class Manager;
class SuggestionsLookup : public QObject class SuggestionsLookup : public PackageLookup
{ {
Q_OBJECT Q_OBJECT
public: public:
SuggestionsLookup(Manager &manager, const QJsonObject &request); SuggestionsLookup(Manager &manager, const QJsonObject &request, QObject *parent = nullptr);
const QJsonArray &errors() const;
const QJsonArray &results() const;
bool finished() const;
signals:
void resultsAvailable(const QJsonValue &what, const QJsonValue &id, const QJsonValue &value);
private slots: private slots:
void addResults(); void addResults();
private:
unsigned int m_remainingReplies;
QJsonValue m_id;
QJsonArray m_errors;
QJsonArray m_results;
}; };
inline const QJsonArray &SuggestionsLookup::errors() const
{
return m_errors;
}
inline const QJsonArray &SuggestionsLookup::results() const
{
return m_results;
}
inline bool SuggestionsLookup::finished() const
{
return !m_remainingReplies && m_errors.isEmpty();
}
} // namespace RepoIndex } // namespace RepoIndex
#endif // REPOINDEX_SUGGESTIONSLOOKUP_H #endif // REPOINDEX_SUGGESTIONSLOOKUP_H

View File

@ -23,7 +23,7 @@ using namespace Utilities;
/*! /*!
* \brief Returns a JSON object for the current instance. * \brief Returns a JSON object for the current instance.
*/ */
QJsonObject UpgradeResult::json() const QJsonObject UpgradeResult::toJson() const
{ {
QJsonObject obj; QJsonObject obj;
obj.insert(QStringLiteral("name"), package->name()); obj.insert(QStringLiteral("name"), package->name());
@ -43,7 +43,7 @@ QJsonObject UpgradeResult::json() const
/*! /*!
* \brief Constructs a new upgrade lookup process. The upgrade lookup process is started immediately. * \brief Constructs a new upgrade lookup process. The upgrade lookup process is started immediately.
*/ */
UpgradeLookupProcess::UpgradeLookupProcess(UpgradeLookup *upgradeLookup, const Repository *upgradeSource) : UpgradeLookupProcess::UpgradeLookupProcess(UpgradeLookup *upgradeLookup, Repository *upgradeSource) :
QObject(upgradeLookup), QObject(upgradeLookup),
m_toCheck(upgradeLookup->toCheck()), m_toCheck(upgradeLookup->toCheck()),
m_upgradeSource(upgradeSource), m_upgradeSource(upgradeSource),
@ -101,7 +101,7 @@ void UpgradeLookupProcess::sourceReady()
*/ */
void UpgradeLookupProcess::checkUpgrades() void UpgradeLookupProcess::checkUpgrades()
{ {
m_toCheck->checkForUpgrades(m_results, QList<const Repository *>() << m_upgradeSource); m_toCheck->checkForUpgrades(m_results, QList<Repository *>() << m_upgradeSource);
} }
/*! /*!
@ -165,7 +165,7 @@ UpgradeLookup::UpgradeLookup(QObject *parent) :
/*! /*!
* \brief Constructs a new upgrade lookup for the specified \a request using the specified \a manager. * \brief Constructs a new upgrade lookup for the specified \a request using the specified \a manager.
*/ */
UpgradeLookupJson::UpgradeLookupJson(const Manager &manager, const QJsonObject &request, QObject *parent) : UpgradeLookupJson::UpgradeLookupJson(Manager &manager, const QJsonObject &request, QObject *parent) :
UpgradeLookup(parent), UpgradeLookup(parent),
m_request(request) m_request(request)
{ {
@ -174,14 +174,14 @@ UpgradeLookupJson::UpgradeLookupJson(const Manager &manager, const QJsonObject &
// construct upgrade lookup processes // construct upgrade lookup processes
const auto syncDbsArray = request.value(QStringLiteral("syncdbs")).toArray(); const auto syncDbsArray = request.value(QStringLiteral("syncdbs")).toArray();
if(syncDbsArray.isEmpty()) { if(syncDbsArray.isEmpty()) {
for(const auto *src : m_toCheck->upgradeSources()) { for(auto *src : m_toCheck->upgradeSources()) {
new UpgradeLookupProcess(this, src); new UpgradeLookupProcess(this, src);
++m_remainingProcesses; ++m_remainingProcesses;
} }
} else { } else {
for(const auto &syncDbValue : syncDbsArray) { for(const auto &syncDbValue : syncDbsArray) {
const auto syncDbName = syncDbValue.toString(); const auto syncDbName = syncDbValue.toString();
if(const auto *src = manager.repositoryByName(syncDbName)) { if(auto *src = manager.repositoryByName(syncDbName)) {
new UpgradeLookupProcess(this, src); new UpgradeLookupProcess(this, src);
++m_remainingProcesses; ++m_remainingProcesses;
} else { } else {
@ -207,13 +207,13 @@ void UpgradeLookupJson::processFinished()
// add results // add results
const auto &results = static_cast<UpgradeLookupProcess *>(sender())->results(); const auto &results = static_cast<UpgradeLookupProcess *>(sender())->results();
for(const auto &res : results.newVersions) { for(const auto &res : results.newVersions) {
m_softwareUpgradesArray << res.json(); m_softwareUpgradesArray << res.toJson();
} }
for(const auto &res : results.newReleases) { for(const auto &res : results.newReleases) {
m_packageOnlyUpgradesArray << res.json(); m_packageOnlyUpgradesArray << res.toJson();
} }
for(const auto &res : results.downgrades) { for(const auto &res : results.downgrades) {
m_downgradesArray << res.json(); m_downgradesArray << res.toJson();
} }
for(const auto &warning : results.warnings) { for(const auto &warning : results.warnings) {
m_warningsArray << warning; m_warningsArray << warning;
@ -267,14 +267,14 @@ void UpgradeLookupJson::processFinished()
/*! /*!
* \brief Constructs a new upgrade lookup for the specified \a db using the specified \a manager. * \brief Constructs a new upgrade lookup for the specified \a db using the specified \a manager.
*/ */
UpgradeLookupCli::UpgradeLookupCli(const Manager &manager, const string &repo, QObject *parent) : UpgradeLookupCli::UpgradeLookupCli(Manager &manager, const string &repo, QObject *parent) :
UpgradeLookup(parent) UpgradeLookup(parent)
{ {
cerr << shchar << "Checking upgrades for \"" << repo << "\" ..." << endl; cerr << shchar << "Checking upgrades for \"" << repo << "\" ..." << endl;
const auto toCheckName = qstr(repo); const auto toCheckName = qstr(repo);
if((m_toCheck = manager.repositoryByName(toCheckName))) { if((m_toCheck = manager.repositoryByName(toCheckName))) {
// construct upgrade lookup processes // construct upgrade lookup processes
for(const auto *src : m_toCheck->upgradeSources()) { for(auto *src : m_toCheck->upgradeSources()) {
new UpgradeLookupProcess(this, src); new UpgradeLookupProcess(this, src);
++m_remainingProcesses; ++m_remainingProcesses;
} }

View File

@ -21,7 +21,7 @@ public:
UpgradeResult(const Package *package, const QString &currentVersion); UpgradeResult(const Package *package, const QString &currentVersion);
const Package *package; const Package *package;
QString currentVersion; QString currentVersion;
QJsonObject json() const; QJsonObject toJson() const;
}; };
/*! /*!
@ -84,7 +84,7 @@ class UpgradeLookupProcess : public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit UpgradeLookupProcess(UpgradeLookup *upgradeLookup, const Repository *upgradeSource); explicit UpgradeLookupProcess(UpgradeLookup *upgradeLookup, Repository *upgradeSource);
const UpgradeLookupResults &results() const; const UpgradeLookupResults &results() const;
signals: signals:
@ -96,7 +96,7 @@ private slots:
private: private:
const Repository *m_toCheck; const Repository *m_toCheck;
const Repository *m_upgradeSource; Repository *m_upgradeSource;
PackageReply *m_reply; PackageReply *m_reply;
QFutureWatcher<void> *m_watcher; QFutureWatcher<void> *m_watcher;
UpgradeLookupResults m_results; UpgradeLookupResults m_results;
@ -116,7 +116,7 @@ private slots:
protected: protected:
explicit UpgradeLookup(QObject *parent = nullptr); explicit UpgradeLookup(QObject *parent = nullptr);
const Repository *m_toCheck; Repository *m_toCheck;
unsigned int m_remainingProcesses; unsigned int m_remainingProcesses;
bool m_firstFinished; bool m_firstFinished;
QSet<const Package *> m_orphanedPackages; QSet<const Package *> m_orphanedPackages;
@ -134,7 +134,7 @@ class UpgradeLookupJson : public UpgradeLookup
{ {
Q_OBJECT Q_OBJECT
public: public:
explicit UpgradeLookupJson(const Manager &manager, const QJsonObject &request, QObject *parent = nullptr); explicit UpgradeLookupJson(Manager &manager, const QJsonObject &request, QObject *parent = nullptr);
const QJsonArray &errors() const; const QJsonArray &errors() const;
signals: signals:
@ -163,7 +163,7 @@ class UpgradeLookupCli : public UpgradeLookup
Q_OBJECT Q_OBJECT
friend class UpgradeLookupProcess; friend class UpgradeLookupProcess;
public: public:
explicit UpgradeLookupCli(const Manager &manager, const std::string &repo, QObject *parent = nullptr); explicit UpgradeLookupCli(Manager &manager, const std::string &repo, QObject *parent = nullptr);
const Repository *toCheck() const; const Repository *toCheck() const;
private slots: private slots:

View File

@ -15,6 +15,11 @@
#include <iostream> #include <iostream>
#include <algorithm> #include <algorithm>
// testing
#include "./alpm/aurpackage.h"
#include "./network/userrepository.h"
#include <QFile>
using namespace std; using namespace std;
using namespace ApplicationUtilities; using namespace ApplicationUtilities;
using namespace RepoIndex; using namespace RepoIndex;
@ -58,6 +63,13 @@ int main(int argc, char *argv[])
manager.initAlpmDataBases(configArgs.serverArg.isPresent()); manager.initAlpmDataBases(configArgs.serverArg.isPresent());
cerr << shchar << "Restoring cache ..." << endl; cerr << shchar << "Restoring cache ..." << endl;
manager.restoreCache(); manager.restoreCache();
//QFile file(QStringLiteral("/run/media/devel/dist/arch/dolphin-emu-git/.SRCINFO"));
//file.open(QFile::ReadOnly);
//manager.userRepository()->addPackagesFromSrcInfo(file.readAll());
//PackageVersion version(manager.databaseByName("ownstuff")->packageByName(QStringLiteral("ffmpeg-libfdk_aac"))->version());
//auto res = version.compare(PackageVersion(QStringLiteral("1:2.8-1")));
if(configArgs.serverArg.isPresent()) { if(configArgs.serverArg.isPresent()) {
// setup the server // setup the server
Server server(manager, manager.config()); Server server(manager, manager.config());

View File

@ -5,6 +5,7 @@
#include <c++utilities/misc/memory.h> #include <c++utilities/misc/memory.h>
#include <KTar> #include <KTar>
#include <KArchiveFile>
#include <QStringBuilder> #include <QStringBuilder>
#include <QUrlQuery> #include <QUrlQuery>
@ -21,6 +22,7 @@ namespace RepoIndex {
const char *requestTypeProp = "type"; const char *requestTypeProp = "type";
const QString rpcRequestTypeKey(QStringLiteral("type")); const QString rpcRequestTypeKey(QStringLiteral("type"));
const QString rpcRequestTypeSearch(QStringLiteral("search"));
const QString rpcRequestTypeSuggest(QStringLiteral("suggest")); const QString rpcRequestTypeSuggest(QStringLiteral("suggest"));
const QString rpcRequestTypeMultiInfo(QStringLiteral("multiinfo")); const QString rpcRequestTypeMultiInfo(QStringLiteral("multiinfo"));
const QString rpcArgKey(QStringLiteral("arg")); const QString rpcArgKey(QStringLiteral("arg"));
@ -47,16 +49,22 @@ void AurPackageReply::processData()
const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &error); const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &error);
if(error.error == QJsonParseError::NoError) { if(error.error == QJsonParseError::NoError) {
for(const auto &result : doc.object().value(QStringLiteral("results")).toArray()) { for(const auto &result : doc.object().value(QStringLiteral("results")).toArray()) {
auto package = make_unique<AurPackage>(result, m_userRepo); QJsonObject obj = result.toObject();
if(!package->name().isEmpty()) { QString packageName = obj.value(QStringLiteral("Name")).toString();
m_packages[package->name()] = move(package); if(!packageName.isEmpty()) {
auto &package = m_packages[packageName];
if(package) {
static_cast<AurPackage *>(package.get())->putJson(obj);
} else {
package = make_unique<AurPackage>(obj, static_cast<UserRepository *>(m_userRepo));
}
} }
} }
} else { } else {
m_error = QStringLiteral("Error: Unable to parse JSON received from AUR: ") % error.errorString() % QStringLiteral(" at character ") % QString::number(error.offset); m_error = QStringLiteral("Error: Unable to parse JSON received from AUR: ") % error.errorString() % QStringLiteral(" at character ") % QString::number(error.offset);
} }
} else { } else {
m_error = QStringLiteral("Error: Unable to request data from AUR: ") + reply->errorString(); m_error = QStringLiteral("Error: Unable to request data from AUR via AurJson: ") + reply->errorString();
} }
emit resultsAvailable(); emit resultsAvailable();
} }
@ -68,8 +76,38 @@ AurFullPackageReply::AurFullPackageReply(const QList<QNetworkReply *> &networkRe
void AurFullPackageReply::processData() void AurFullPackageReply::processData()
{ {
//auto *reply = static_cast<QNetworkReply *>(sender()); auto *reply = static_cast<QNetworkReply *>(sender());
// TODO if(reply->error() == QNetworkReply::NoError) {
KTar tar(reply);
if(tar.open(QIODevice::ReadOnly)) {
const auto *baseDir = tar.directory();
//const auto packageBase = baseDir->name();
const auto *srcInfoEntry = baseDir->entry(QStringLiteral(".SRCINFO"));
if(srcInfoEntry && srcInfoEntry->isFile()) {
const QByteArray srcInfo = static_cast<const KArchiveFile *>(srcInfoEntry)->data();
const auto packages = m_userRepo->addPackagesFromSrcInfo(srcInfo);
// TODO: error handling
for(const auto &entryName : baseDir->entries()) {
if(entryName != QLatin1String(".SRCINFO")) {
const auto *entry = baseDir->entry(entryName);
if(entry->isFile()) {
for(const auto *package : packages) {
// TODO: add source files
}
} else {
// don't think it is required to read sub directories recursively
}
}
}
} else {
m_error = QStringLiteral("Error: Aur tarball does not contain \".SRCINFO\".");
}
} else {
m_error = QStringLiteral("Error: Unable to open tarball reply.");
}
} else {
m_error = QStringLiteral("Error: Unable to request tarball from AUR: ") + reply->errorString();
}
} }
AurSuggestionsReply::AurSuggestionsReply(QNetworkReply *networkReply, const QString &term, UserRepository *repo) : AurSuggestionsReply::AurSuggestionsReply(QNetworkReply *networkReply, const QString &term, UserRepository *repo) :
@ -87,12 +125,27 @@ void AurSuggestionsReply::processData()
const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &error); const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &error);
if(error.error == QJsonParseError::NoError) { if(error.error == QJsonParseError::NoError) {
auto &packages = m_repo->packages(); auto &packages = m_repo->packages();
for(const auto &suggestion : doc.array()) { if(doc.isObject()) {
const auto suggestionString = suggestion.toString(); for(const auto &result : doc.object().value(QStringLiteral("results")).toArray()) {
if(!suggestionString.isEmpty()) { QJsonObject obj = result.toObject();
auto &package = packages[suggestionString]; QString packageName = obj.value(QStringLiteral("Name")).toString();
if(!package) { if(!packageName.isEmpty()) {
package = make_unique<AurPackage>(suggestionString, static_cast<UserRepository *>(m_repo)); auto &package = packages[packageName];
if(package) {
static_cast<AurPackage *>(package.get())->putJson(obj);
} else {
package = make_unique<AurPackage>(obj, static_cast<UserRepository *>(m_repo));
}
}
}
} else if(doc.isArray()) {
for(const auto &suggestion : doc.array()) {
const auto suggestionString = suggestion.toString();
if(!suggestionString.isEmpty()) {
auto &package = packages[suggestionString];
if(!package) {
package = make_unique<AurPackage>(suggestionString, static_cast<UserRepository *>(m_repo));
}
} }
} }
} }
@ -131,27 +184,39 @@ PackageDetailAvailability UserRepository::requestsRequired(PackageDetail package
} }
} }
AurSuggestionsReply *UserRepository::requestSuggestions(const QString &term) const AurSuggestionsReply *UserRepository::requestSuggestions(const QString &term)
{ {
size_t remainingSuggestions = 20; size_t remainingSuggestions = 20;
for(auto i = packages().lower_bound(term), end = packages().cend(); i != end && remainingSuggestions && i->first.startsWith(term, Qt::CaseInsensitive); ++i, --remainingSuggestions); //for(auto i = packages().lower_bound(term), end = packages().cend(); i != end && remainingSuggestions && i->first.startsWith(term, Qt::CaseInsensitive); ++i, --remainingSuggestions);
for(const auto &pkgEntry : packages()) {
if(pkgEntry.first.compare(term, Qt::CaseInsensitive) == 0) {
if(!(--remainingSuggestions)) {
break;
}
}
}
if(remainingSuggestions) { if(remainingSuggestions) {
auto url = m_aurRpcUrl; auto url = m_aurRpcUrl;
QUrlQuery query; QUrlQuery query;
query.addQueryItem(rpcRequestTypeKey, rpcRequestTypeSuggest); query.addQueryItem(rpcRequestTypeKey, term.size() < 3 ? rpcRequestTypeSuggest : rpcRequestTypeSearch);
query.addQueryItem(rpcArgKey, term); query.addQueryItem(rpcArgKey, term);
url.setQuery(query); url.setQuery(query);
return new AurSuggestionsReply(m_networkAccessManager.get(QNetworkRequest(url)), term, const_cast<UserRepository *>(this)); return new AurSuggestionsReply(m_networkAccessManager.get(QNetworkRequest(url)), term, this);
} else { } else {
return nullptr; return nullptr;
} }
} }
AurPackageReply *UserRepository::requestPackageInfo(const QStringList &packageNames, bool forceUpdate) const AurPackageReply *UserRepository::requestPackageInfo(const QStringList &packageNames, bool forceUpdate)
{ {
QUrlQuery query; QUrlQuery query;
for(const auto &packageName : packageNames) { for(const auto &packageName : packageNames) {
if(forceUpdate || !m_packages.count(packageName)) { try {
const auto &pkg = m_packages.at(packageName);
if(!pkg->hasGeneralInfo() || forceUpdate) {
query.addQueryItem(rpcArgArray, packageName);
}
} catch(const out_of_range &) {
query.addQueryItem(rpcArgArray, packageName); query.addQueryItem(rpcArgArray, packageName);
} }
} }
@ -161,11 +226,11 @@ AurPackageReply *UserRepository::requestPackageInfo(const QStringList &packageNa
auto url = m_aurRpcUrl; auto url = m_aurRpcUrl;
query.addQueryItem(rpcRequestTypeKey, rpcRequestTypeMultiInfo); query.addQueryItem(rpcRequestTypeKey, rpcRequestTypeMultiInfo);
url.setQuery(query); url.setQuery(query);
return new AurPackageReply(m_networkAccessManager.get(QNetworkRequest(url)), const_cast<UserRepository *>(this)); return new AurPackageReply(m_networkAccessManager.get(QNetworkRequest(url)), this);
} }
} }
AurFullPackageReply *UserRepository::requestFullPackageInfo(const QStringList &packageNames, bool forceUpdate) const AurFullPackageReply *UserRepository::requestFullPackageInfo(const QStringList &packageNames, bool forceUpdate)
{ {
QList<QNetworkReply *> replies; QList<QNetworkReply *> replies;
for(const auto &packageName : packageNames) { for(const auto &packageName : packageNames) {
@ -187,7 +252,7 @@ AurFullPackageReply *UserRepository::requestFullPackageInfo(const QStringList &p
if(replies.isEmpty()) { if(replies.isEmpty()) {
return nullptr; return nullptr;
} else { } else {
return new AurFullPackageReply(replies, const_cast<UserRepository *>(this)); return new AurFullPackageReply(replies, this);
} }
} }

View File

@ -65,9 +65,9 @@ public:
static void setAurRpcUrl(const QUrl &aurRpcUrl); static void setAurRpcUrl(const QUrl &aurRpcUrl);
PackageDetailAvailability requestsRequired(PackageDetail packageDetail) const; PackageDetailAvailability requestsRequired(PackageDetail packageDetail) const;
AurSuggestionsReply *requestSuggestions(const QString &term) const; AurSuggestionsReply *requestSuggestions(const QString &term);
AurPackageReply *requestPackageInfo(const QStringList &packageNames, bool forceUpdate = false) const; AurPackageReply *requestPackageInfo(const QStringList &packageNames, bool forceUpdate = false);
AurFullPackageReply *requestFullPackageInfo(const QStringList &packageNames, bool forceUpdate = false) const; AurFullPackageReply *requestFullPackageInfo(const QStringList &packageNames, bool forceUpdate = false);
protected: protected:
std::unique_ptr<Package> emptyPackage(); std::unique_ptr<Package> emptyPackage();

View File

@ -34,7 +34,9 @@ SOURCES += main.cpp \
alpm/alpmdatabase.cpp \ alpm/alpmdatabase.cpp \
alpm/repository.cpp \ alpm/repository.cpp \
alpm/upgradelookup.cpp \ alpm/upgradelookup.cpp \
alpm/suggestionslookup.cpp alpm/suggestionslookup.cpp \
alpm/packageinfolookup.cpp \
alpm/packagelookup.cpp
HEADERS += \ HEADERS += \
alpm/manager.h \ alpm/manager.h \
@ -53,7 +55,9 @@ HEADERS += \
alpm/alpmdatabase.h \ alpm/alpmdatabase.h \
alpm/repository.h \ alpm/repository.h \
alpm/upgradelookup.h \ alpm/upgradelookup.h \
alpm/suggestionslookup.h alpm/suggestionslookup.h \
alpm/packageinfolookup.h \
alpm/packagelookup.h
DISTFILES += \ DISTFILES += \
README.md \ README.md \