repoindex/network/userrepository.cpp

186 lines
6.7 KiB
C++
Raw Normal View History

2015-09-04 14:37:01 +02:00
#include "userrepository.h"
#include "../alpm/aurpackage.h"
2015-09-04 14:37:01 +02:00
#include <c++utilities/misc/memory.h>
2015-09-06 15:34:39 +02:00
#include <KTar>
2015-09-04 14:37:01 +02:00
#include <QStringBuilder>
#include <QUrlQuery>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QJsonDocument>
#include <QJsonObject>
#include <QJsonArray>
using namespace std;
namespace RepoIndex {
2015-09-04 14:37:01 +02:00
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");
2015-09-04 14:37:01 +02:00
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) {
2015-09-04 14:37:01 +02:00
QJsonParseError error;
//QByteArray data = m_networkReply->readAll();
//cerr << shchar << "AUR reply: " << data.data() << endl;
2015-09-04 14:37:01 +02:00
//const QJsonDocument doc = QJsonDocument::fromJson(data, &error);
const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &error);
2015-09-04 14:37:01 +02:00
if(error.error == QJsonParseError::NoError) {
for(const auto &result : doc.object().value(QStringLiteral("results")).toArray()) {
auto package = make_unique<AurPackage>(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();
2015-09-04 14:37:01 +02:00
}
emit resultsAvailable();
}
AurFullPackageReply::AurFullPackageReply(const QList<QNetworkReply *> &networkReplies, UserRepository *userRepo) :
PackageReply(networkReplies, userRepo->packages()),
m_userRepo(userRepo)
{}
void AurFullPackageReply::processData()
{
//auto *reply = static_cast<QNetworkReply *>(sender());
// TODO
}
2015-09-04 14:37:01 +02:00
AurSuggestionsReply::AurSuggestionsReply(QNetworkReply *networkReply) :
SuggestionsReply(networkReply)
{}
void AurSuggestionsReply::processData()
{
auto *reply = m_networkReplies.front();
if(reply->error() == QNetworkReply::NoError) {
2015-09-04 14:37:01 +02:00
QJsonParseError error;
//QByteArray data = m_networkReply->readAll();
//cerr << shchar << "AUR reply: " << data.data() << endl;
2015-09-04 14:37:01 +02:00
//const QJsonDocument doc = QJsonDocument::fromJson(data, &error);
const QJsonDocument doc = QJsonDocument::fromJson(reply->readAll(), &error);
2015-09-04 14:37:01 +02:00
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();
2015-09-04 14:37:01 +02:00
}
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
2015-09-04 14:37:01 +02:00
{
switch(packageDetail) {
case PackageDetail::Basics:
return PackageDetailAvailability::Request;
case PackageDetail::Dependencies:
case PackageDetail::SourceInfo:
case PackageDetail::AllAvailable:
return PackageDetailAvailability::FullRequest;
default:
return PackageDetailAvailability::Never;
}
2015-09-04 14:37:01 +02:00
}
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<UserRepository *>(this));
}
}
AurFullPackageReply *UserRepository::requestFullPackageInfo(const QStringList &packageNames, bool forceUpdate) const
2015-09-04 14:37:01 +02:00
{
QList<QNetworkReply *> 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 &) {
if(forceUpdate) {
replies << m_networkAccessManager.get(QNetworkRequest(m_aurSnapshotPath.arg(packageName)));
}
2015-09-04 14:37:01 +02:00
}
}
if(replies.isEmpty()) {
return nullptr;
} else {
return new AurFullPackageReply(replies, const_cast<UserRepository *>(this));
}
}
unique_ptr<Package> UserRepository::emptyPackage()
{
return make_unique<AurPackage>(this);
2015-09-04 14:37:01 +02:00
}
} // namespace Alpm