#include "userrepository.h" #include "alpm/aurpackage.h" #include #include #include #include #include #include #include #include #include #include using namespace std; namespace RepoIndex { const char *requestTypeProp = "type"; const QString rpcRequestTypeKey(QStringLiteral("type")); const QString rpcRequestTypeSuggest(QStringLiteral("suggest")); const QString rpcRequestTypeMultiInfo(QStringLiteral("multiinfo")); const QString rpcArgKey(QStringLiteral("arg")); const QString rpcArgArray(QStringLiteral("arg[]")); const QString pkgbuildRequestType(QString("pkgbuild")); QUrl UserRepository::m_aurRpcUrl = QUrl(QStringLiteral("https://aur.archlinux.org/rpc.php")); QUrl UserRepository::m_aurPkgbuildUrl = QUrl(QStringLiteral("https://aur.archlinux.org/cgit/aur.git/plain/PKGBUILD")); QUrl UserRepository::m_aurSrcInfoUrl = QUrl(QStringLiteral("https://aur.archlinux.org/cgit/aur.git/plain/.SRCINFO")); QString UserRepository::m_aurSnapshotPath = QStringLiteral("https://aur.archlinux.org/cgit/aur.git/snapshot/%1.tar.gz"); AurPackageReply::AurPackageReply(QNetworkReply *networkReply, UserRepository *userRepo) : PackageReply(networkReply, userRepo->packages()), m_userRepo(userRepo) {} void AurPackageReply::processData() { auto *reply = m_networkReplies.front(); if(reply->error() == QNetworkReply::NoError) { QJsonParseError error; //QByteArray data = m_networkReply->readAll(); //cerr << shchar << "AUR reply: " << data.data() << endl; //const QJsonDocument doc = QJsonDocument::fromJson(data, &error); const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &error); if(error.error == QJsonParseError::NoError) { for(const auto &result : doc.object().value(QStringLiteral("results")).toArray()) { auto package = make_unique(result, m_userRepo); if(!package->name().isEmpty()) { m_packages[package->name()] = move(package); } } } else { m_error = QStringLiteral("Error: Unable to parse JSON received from AUR: ") % error.errorString() % QStringLiteral(" at character ") % QString::number(error.offset); } } else { m_error = QStringLiteral("Error: Unable to request data from AUR: ") + reply->errorString(); } emit resultsAvailable(); } AurFullPackageReply::AurFullPackageReply(const QList &networkReplies, UserRepository *userRepo) : PackageReply(networkReplies, userRepo->packages()), m_userRepo(userRepo) {} void AurFullPackageReply::processData() { //auto *reply = static_cast(sender()); // TODO } AurSuggestionsReply::AurSuggestionsReply(QNetworkReply *networkReply) : SuggestionsReply(networkReply) {} void AurSuggestionsReply::processData() { auto *reply = m_networkReplies.front(); if(reply->error() == QNetworkReply::NoError) { QJsonParseError error; //QByteArray data = m_networkReply->readAll(); //cerr << shchar << "AUR reply: " << data.data() << endl; //const QJsonDocument doc = QJsonDocument::fromJson(data, &error); const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &error); if(error.error == QJsonParseError::NoError) { m_suggestions = doc.array(); } else { m_error = QStringLiteral("Error: Unable to parse JSON received from AUR: ") % error.errorString() % QStringLiteral(" at character ") % QString::number(error.offset); } } else { m_error = QStringLiteral("Error: Unable to request data from AUR: ") + reply->errorString(); } emit resultsAvailable(); } UserRepository::UserRepository(QNetworkAccessManager &networkAccessManager, QObject *parent) : Repository(QStringLiteral("AUR"), parent), m_networkAccessManager(networkAccessManager) { m_description = QStringLiteral("Arch User Repository"); } RepositoryType UserRepository::type() const { return RepositoryType::UserRepository; } PackageDetailAvailability UserRepository::requestsRequired(PackageDetail packageDetail) const { switch(packageDetail) { case PackageDetail::Basics: return PackageDetailAvailability::Request; case PackageDetail::Dependencies: case PackageDetail::SourceInfo: return PackageDetailAvailability::FullRequest; case PackageDetail::PackageInfo: return PackageDetailAvailability::Never; } } AurSuggestionsReply *UserRepository::requestSuggestions(const QString &phrase) const { auto url = m_aurRpcUrl; QUrlQuery query; query.addQueryItem(rpcRequestTypeKey, rpcRequestTypeSuggest); query.addQueryItem(rpcArgKey, phrase); url.setQuery(query); return new AurSuggestionsReply(m_networkAccessManager.get(QNetworkRequest(url))); } AurPackageReply *UserRepository::requestPackageInfo(const QStringList &packageNames, bool forceUpdate) const { QUrlQuery query; for(const auto &packageName : packageNames) { if(forceUpdate || !m_packages.count(packageName)) { query.addQueryItem(rpcArgArray, packageName); } } if(query.isEmpty()) { return nullptr; } else { auto url = m_aurRpcUrl; query.addQueryItem(rpcRequestTypeKey, rpcRequestTypeMultiInfo); url.setQuery(query); return new AurPackageReply(m_networkAccessManager.get(QNetworkRequest(url)), const_cast(this)); } } AurFullPackageReply *UserRepository::requestFullPackageInfo(const QStringList &packageNames, bool forceUpdate) const { QList replies; for(const auto &packageName : packageNames) { try { const auto &pkg = m_packages.at(packageName); if(!pkg->hasGeneralInfo() || !pkg->hasSourceRelatedMetaData() || forceUpdate) { if(pkg->tarUrl().isEmpty()) { replies << m_networkAccessManager.get(QNetworkRequest(m_aurSnapshotPath.arg(pkg->name()))); } else { replies << m_networkAccessManager.get(QNetworkRequest(pkg->tarUrl())); } } } catch(const out_of_range &) { replies << m_networkAccessManager.get(QNetworkRequest(m_aurSnapshotPath.arg(packageName))); } } return new AurFullPackageReply(replies, const_cast(this)); } } // namespace Alpm