398 lines
11 KiB
C++
398 lines
11 KiB
C++
#ifndef PACKAGEMANAGEMENT_PACKAGESOURCE_H
|
|
#define PACKAGEMANAGEMENT_PACKAGESOURCE_H
|
|
|
|
#include "./package.h"
|
|
#include "./group.h"
|
|
|
|
#include <QObject>
|
|
#include <QFuture>
|
|
#include <QJsonObject>
|
|
|
|
#include <memory>
|
|
#include <functional>
|
|
|
|
QT_FORWARD_DECLARE_CLASS(QNetworkReply)
|
|
|
|
namespace RepoIndex {
|
|
|
|
class UpgradeLookupResults;
|
|
|
|
class Reply : public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
Reply(QNetworkReply *networkReply);
|
|
Reply(const QList<QNetworkReply *> networkReplies);
|
|
const QString &error() const;
|
|
|
|
signals:
|
|
void resultsAvailable();
|
|
|
|
private slots:
|
|
virtual void processData() = 0;
|
|
|
|
protected:
|
|
QList<QNetworkReply *> m_networkReplies;
|
|
QString m_error;
|
|
};
|
|
|
|
inline const QString &Reply::error() const
|
|
{
|
|
return m_error;
|
|
}
|
|
|
|
class PackageReply : public Reply
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
PackageReply(QNetworkReply *networkReply, std::map<QString, std::unique_ptr<Package> > &packages);
|
|
PackageReply(const QList<QNetworkReply *> &networkReplies, std::map<QString, std::unique_ptr<Package> > &packages);
|
|
const std::map<QString, std::unique_ptr<Package> > &packages() const;
|
|
|
|
protected:
|
|
std::map<QString, std::unique_ptr<Package> > &m_packages;
|
|
};
|
|
|
|
inline PackageReply::PackageReply(QNetworkReply *networkReply, std::map<QString, std::unique_ptr<Package> > &packages) :
|
|
Reply(networkReply),
|
|
m_packages(packages)
|
|
{}
|
|
|
|
inline PackageReply::PackageReply(const QList<QNetworkReply *> &networkReplies, std::map<QString, std::unique_ptr<Package> > &packages) :
|
|
Reply(networkReplies),
|
|
m_packages(packages)
|
|
{}
|
|
|
|
inline const std::map<QString, std::unique_ptr<Package> > &PackageReply::packages() const
|
|
{
|
|
return m_packages;
|
|
}
|
|
|
|
class SuggestionsReply : public Reply
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
SuggestionsReply(QNetworkReply *networkReply, const QString &term, Repository *repo);
|
|
QJsonObject suggestions() const;
|
|
|
|
protected:
|
|
QString m_term;
|
|
Repository *m_repo;
|
|
};
|
|
|
|
inline SuggestionsReply::SuggestionsReply(QNetworkReply *networkReply, const QString &term, Repository *repo) :
|
|
Reply(networkReply),
|
|
m_term(term),
|
|
m_repo(repo)
|
|
{}
|
|
|
|
/*!
|
|
* \brief The RepositoryType enum specifies the type of a repository object.
|
|
*/
|
|
enum class RepositoryType
|
|
{
|
|
AlpmDatabase, /*! The repository is an AlpmDataBase instance. */
|
|
UserRepository, /*! The repository is a UserRepository instance. */
|
|
Other /*! The repository type is unknown. */
|
|
};
|
|
|
|
/*!
|
|
* \brief The PackageDetail enum is used to refer to some kind of information about a package.
|
|
*/
|
|
enum class PackageDetail
|
|
{
|
|
Basics, /*! Basic information about the package such as knowing it exists, its name, version and description. */
|
|
Dependencies, /*! The runtime dependencies of the package. */
|
|
SourceInfo, /*! The source info such as make dependencies of the package. */
|
|
PackageInfo, /*! Information related to a specific package (pkg-file). */
|
|
AllAvailable /*! All available package details. */
|
|
};
|
|
|
|
/*!
|
|
* \brief The PackageDetailAvailability enum describes when some kind of information about a package
|
|
* becomes available.
|
|
*/
|
|
enum class PackageDetailAvailability
|
|
{
|
|
Never, /*! The information is not available and can't be requested. */
|
|
Immediately, /*! The information is available immediately after the repository object has been constructed. */
|
|
Request, /*! The information is available after the requestPackageInfo() method has been called for the package. */
|
|
FullRequest /*! The information is available after the requestFullPackageInfo() method has been called for the package. */
|
|
};
|
|
|
|
class Repository : public QObject
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
~Repository();
|
|
|
|
virtual RepositoryType type() const = 0;
|
|
|
|
// general meta data
|
|
uint32 index() const;
|
|
const QString &name() const;
|
|
const QString &description() const;
|
|
const std::map<QString, std::unique_ptr<Package> > &packages() const;
|
|
std::map<QString, std::unique_ptr<Package> > &packages();
|
|
const QStringList packageNames() const;
|
|
alpm_db_usage_t usage() const;
|
|
bool isSourceOnly() const;
|
|
bool isPackageOnly() const;
|
|
std::map<QString, QList<Package *> > &groups();
|
|
const std::map<QString, QList<Package *> > &groups() const;
|
|
const QStringList &serverUrls() const;
|
|
alpm_siglevel_t sigLevel() const;
|
|
|
|
// gathering data
|
|
virtual PackageDetailAvailability requestsRequired(PackageDetail packageDetail = PackageDetail::Basics) const;
|
|
virtual SuggestionsReply *requestSuggestions(const QString &phrase) const;
|
|
virtual PackageReply *requestPackageInfo(const QStringList &packageNames, bool forceUpdate = false) const;
|
|
virtual PackageReply *requestFullPackageInfo(const QStringList &package, bool forceUpdate = false) const;
|
|
|
|
// package search
|
|
const Package *packageByName(const QString &name) const;
|
|
Package *packageByName(const QString &name);
|
|
const Package *packageProviding(const Dependency &dependency) const;
|
|
Package *packageProviding(const Dependency &dependency);
|
|
QList<const Package *> packagesProviding(const Dependency &dependency) const;
|
|
QList<Package *> packageByFilter(std::function<bool (const Package *)> pred);
|
|
QFuture<void> computeRequiredBy(Manager &manager, bool forceUpdate = false);
|
|
QJsonObject suggestions(const QString &term) const;
|
|
|
|
// upgrade lookup
|
|
const QList<const Repository *> &upgradeSources() const;
|
|
QList<const Repository *> &upgradeSources();
|
|
QJsonArray upgradeSourcesJsonArray() const;
|
|
void checkForUpgrades(UpgradeLookupResults &results) const;
|
|
void checkForUpgrades(UpgradeLookupResults &results, const QList<const Repository *> &upgradeSources) const;
|
|
|
|
// build system
|
|
const QString &sourcesDirectory() const;
|
|
void setSourcesDirectory(const QString &dir);
|
|
const QString &packagesDirectory() const;
|
|
void setPackagesDirectory(const QString &dir);
|
|
|
|
// JSON serialization
|
|
QJsonArray packageNamesJsonArray() const;
|
|
QJsonObject packagesObjectSkeleton() const;
|
|
QJsonObject basicInfo(bool includeName = false) const;
|
|
QJsonObject groupInfo() const;
|
|
|
|
// caching
|
|
bool isCachingUseful() const;
|
|
void writeToCacheStream(QDataStream &out);
|
|
void restoreFromCacheStream(QDataStream &in);
|
|
virtual void writeSpecificCacheHeader(QDataStream &out);
|
|
virtual std::unique_ptr<Package> emptyPackage();
|
|
virtual void restoreSpecificCacheHeader(QDataStream &in);
|
|
|
|
// parsing src/pkg info
|
|
void addPackagesFromSrcInfo(const QByteArray &srcInfo);
|
|
|
|
static const uint32 invalidIndex = static_cast<uint32>(-1);
|
|
|
|
protected:
|
|
explicit Repository(const QString &name, uint32 index = invalidIndex, QObject *parent = nullptr);
|
|
|
|
protected:
|
|
uint32 m_index;
|
|
QString m_name;
|
|
QString m_description;
|
|
std::map<QString, std::unique_ptr<Package> > m_packages;
|
|
alpm_db_usage_t m_usage;
|
|
std::map<QString, QList<Package *> > m_groups;
|
|
QStringList m_serverUrls;
|
|
alpm_siglevel_t m_sigLevel;
|
|
QList<const Repository *> m_upgradeSources;
|
|
QString m_srcDir;
|
|
QString m_pkgDir;
|
|
};
|
|
|
|
/*!
|
|
* \brief Returns the suggestions.
|
|
*/
|
|
inline QJsonObject SuggestionsReply::suggestions() const
|
|
{
|
|
return m_repo->suggestions(m_term);
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the index of the repository.
|
|
*
|
|
* The index is used to sort the repositories by their occurance the configuration files.
|
|
*/
|
|
inline uint32 Repository::index() const
|
|
{
|
|
return m_index;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the name.
|
|
*/
|
|
inline const QString &Repository::name() const
|
|
{
|
|
return m_name;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the description.
|
|
*/
|
|
inline const QString &Repository::description() const
|
|
{
|
|
return m_description;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns whether the repository only has sources but no built packages.
|
|
*/
|
|
inline bool Repository::isSourceOnly() const
|
|
{
|
|
return requestsRequired(PackageDetail::PackageInfo) == PackageDetailAvailability::Never;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns whether the repository only has built packages but no sources.
|
|
*/
|
|
inline bool Repository::isPackageOnly() const
|
|
{
|
|
return requestsRequired(PackageDetail::SourceInfo) == PackageDetailAvailability::Never;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the packages.
|
|
*/
|
|
inline const std::map<QString, std::unique_ptr<Package> > &Repository::packages() const
|
|
{
|
|
return m_packages;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the packages.
|
|
*/
|
|
inline std::map<QString, std::unique_ptr<Package> > &Repository::packages()
|
|
{
|
|
return m_packages;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the package with the specified \a name or nullptr if the package can not be found.
|
|
* \remarks Ownership remains by this instance.
|
|
*/
|
|
inline const Package *Repository::packageByName(const QString &name) const
|
|
{
|
|
try {
|
|
return m_packages.at(name).get();
|
|
} catch(const std::out_of_range &) {
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the package with the specified \a name or nullptr if the package can not be found.
|
|
* \remarks Ownership remains by this instance.
|
|
*/
|
|
inline Package *Repository::packageByName(const QString &name)
|
|
{
|
|
try {
|
|
return m_packages.at(name).get();
|
|
} catch(const std::out_of_range &) {
|
|
return nullptr;
|
|
}
|
|
}
|
|
|
|
inline alpm_db_usage_t Repository::usage() const
|
|
{
|
|
return m_usage;
|
|
}
|
|
|
|
inline std::map<QString, QList<Package *> > &Repository::groups()
|
|
{
|
|
return m_groups;
|
|
}
|
|
|
|
inline const std::map<QString, QList<Package *> > &Repository::groups() const
|
|
{
|
|
return m_groups;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the server URLs.
|
|
*/
|
|
inline const QStringList &Repository::serverUrls() const
|
|
{
|
|
return m_serverUrls;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the signature level of the database.
|
|
*/
|
|
inline alpm_siglevel_t Repository::sigLevel() const
|
|
{
|
|
return m_sigLevel;
|
|
}
|
|
|
|
inline const QList<const Repository *> &Repository::upgradeSources() const
|
|
{
|
|
return m_upgradeSources;
|
|
}
|
|
|
|
inline QList<const Repository *> &Repository::upgradeSources()
|
|
{
|
|
return m_upgradeSources;
|
|
}
|
|
|
|
inline void Repository::checkForUpgrades(UpgradeLookupResults &results) const
|
|
{
|
|
checkForUpgrades(results, upgradeSources());
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the path of the local sources directory.
|
|
*/
|
|
inline const QString &Repository::sourcesDirectory() const
|
|
{
|
|
return m_srcDir;
|
|
}
|
|
|
|
/*!
|
|
* \brief Sets the path of the local sources directory.
|
|
*/
|
|
inline void Repository::setSourcesDirectory(const QString &dir)
|
|
{
|
|
m_srcDir = dir;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the path of the local packages directory.
|
|
*/
|
|
inline const QString &Repository::packagesDirectory() const
|
|
{
|
|
return m_pkgDir;
|
|
}
|
|
|
|
/*!
|
|
* \brief Sets the path of the local packages directory.
|
|
*/
|
|
inline void Repository::setPackagesDirectory(const QString &dir)
|
|
{
|
|
m_pkgDir = dir;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns whether caching this repository is useful.
|
|
*/
|
|
inline bool Repository::isCachingUseful() const
|
|
{
|
|
switch(requestsRequired(PackageDetail::AllAvailable)) {
|
|
case PackageDetailAvailability::Request:
|
|
case PackageDetailAvailability::FullRequest:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
} // namespace PackageManagement
|
|
|
|
#endif // PACKAGEMANAGEMENT_PACKAGESOURCE_H
|