File indexing completed on 2024-05-12 05:29:03

0001 /*
0002  *   SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005  */
0006 
0007 #pragma once
0008 
0009 #include <QCollatorSortKey>
0010 #include <QColor>
0011 #include <QDate>
0012 #include <QJsonArray>
0013 #include <QJsonObject>
0014 #include <QObject>
0015 #include <QScopedPointer>
0016 #include <QSet>
0017 #include <QStringList>
0018 #include <QUrl>
0019 #include <QVector>
0020 
0021 #include "PackageState.h"
0022 #include "discovercommon_export.h"
0023 
0024 class Category;
0025 class Rating;
0026 class AbstractResourcesBackend;
0027 
0028 struct Screenshot {
0029     Screenshot(const QUrl &screenshot)
0030         : thumbnail(screenshot)
0031         , screenshot(screenshot)
0032     {
0033     }
0034 
0035     Screenshot(const QUrl &thumbnail, const QUrl &screenshot, bool isAnimated)
0036         : thumbnail(thumbnail)
0037         , screenshot(screenshot)
0038         , isAnimated(isAnimated)
0039     {
0040     }
0041 
0042     QUrl thumbnail;
0043     QUrl screenshot;
0044     bool isAnimated = false;
0045 };
0046 
0047 using Screenshots = QVector<Screenshot>;
0048 
0049 /**
0050  * \class AbstractResource  AbstractResource.h "AbstractResource.h"
0051  *
0052  * \brief This is the base class of all resources.
0053  *
0054  * Each backend must reimplement its own resource class which needs to derive from this one.
0055  */
0056 class DISCOVERCOMMON_EXPORT AbstractResource : public QObject
0057 {
0058     Q_OBJECT
0059     Q_PROPERTY(QString name READ name CONSTANT)
0060     Q_PROPERTY(QString packageName READ packageName CONSTANT)
0061     Q_PROPERTY(QString comment READ comment CONSTANT)
0062     Q_PROPERTY(QVariant icon READ icon NOTIFY iconChanged)
0063     Q_PROPERTY(bool canExecute READ canExecute CONSTANT)
0064     Q_PROPERTY(State state READ state NOTIFY stateChanged)
0065     Q_PROPERTY(QString status READ status NOTIFY stateChanged)
0066     Q_PROPERTY(QStringList category READ categories CONSTANT)
0067     Q_PROPERTY(QUrl homepage READ homepage CONSTANT)
0068     Q_PROPERTY(QUrl helpURL READ helpURL CONSTANT)
0069     Q_PROPERTY(QUrl bugURL READ bugURL CONSTANT)
0070     Q_PROPERTY(QUrl donationURL READ donationURL CONSTANT)
0071     Q_PROPERTY(QUrl contributeURL READ contributeURL CONSTANT)
0072     Q_PROPERTY(bool canUpgrade READ canUpgrade NOTIFY stateChanged)
0073     Q_PROPERTY(bool isInstalled READ isInstalled NOTIFY stateChanged)
0074     Q_PROPERTY(QJsonArray licenses READ licenses NOTIFY licensesChanged)
0075     Q_PROPERTY(QString longDescription READ longDescription NOTIFY longDescriptionChanged)
0076     Q_PROPERTY(QString origin READ origin CONSTANT)
0077     Q_PROPERTY(QString displayOrigin READ displayOrigin CONSTANT)
0078     Q_PROPERTY(quint64 size READ size NOTIFY sizeChanged)
0079     Q_PROPERTY(QString sizeDescription READ sizeDescription NOTIFY sizeChanged)
0080     Q_PROPERTY(QString installedVersion READ installedVersion NOTIFY versionsChanged)
0081     Q_PROPERTY(QString availableVersion READ availableVersion NOTIFY versionsChanged)
0082     Q_PROPERTY(QString section READ section CONSTANT)
0083     Q_PROPERTY(QStringList mimetypes READ mimetypes CONSTANT)
0084     Q_PROPERTY(QObject *backend READ backendObject CONSTANT)
0085     Q_PROPERTY(QVariant rating READ ratingVariant NOTIFY ratingFetched)
0086     Q_PROPERTY(QString appstreamId READ appstreamId CONSTANT)
0087     Q_PROPERTY(QUrl url READ url CONSTANT)
0088     Q_PROPERTY(QString executeLabel READ executeLabel CONSTANT)
0089     Q_PROPERTY(QString sourceIcon READ sourceIcon CONSTANT)
0090     Q_PROPERTY(QString author READ author CONSTANT)
0091     Q_PROPERTY(QDate releaseDate READ releaseDate NOTIFY versionsChanged)
0092     Q_PROPERTY(QString upgradeText READ upgradeText NOTIFY versionsChanged)
0093     Q_PROPERTY(bool isRemovable READ isRemovable CONSTANT)
0094     Q_PROPERTY(QString versionString READ versionString NOTIFY versionsChanged)
0095     Q_PROPERTY(QString contentRatingText READ contentRatingText CONSTANT)
0096     Q_PROPERTY(QString contentRatingDescription READ contentRatingDescription CONSTANT)
0097     Q_PROPERTY(ContentIntensity contentRatingIntensity READ contentRatingIntensity CONSTANT)
0098     Q_PROPERTY(uint contentRatingMinimumAge READ contentRatingMinimumAge CONSTANT)
0099     Q_PROPERTY(QStringList topObjects READ topObjects CONSTANT)
0100     Q_PROPERTY(QStringList bottomObjects READ bottomObjects CONSTANT)
0101 
0102 public:
0103     /**
0104      * This describes the state of the resource
0105      */
0106     enum State {
0107         /**
0108          * When the resource is somehow broken
0109          */
0110         Broken,
0111         /**
0112          * This means that the resource is neither installed nor broken
0113          */
0114         None,
0115         /**
0116          * The resource is installed and up-to-date
0117          */
0118         Installed,
0119         /**
0120          * The resource is installed and an update is available
0121          */
0122         Upgradeable,
0123     };
0124     Q_ENUM(State)
0125 
0126     enum ContentIntensity {
0127         Mild,
0128         Intense,
0129     };
0130     Q_ENUM(ContentIntensity)
0131 
0132     /**
0133      * Constructs the AbstractResource with its corresponding backend
0134      */
0135     explicit AbstractResource(AbstractResourcesBackend *parent);
0136     ~AbstractResource() override;
0137 
0138     /// used as internal identification of a resource
0139     virtual QString packageName() const = 0;
0140 
0141     /// resource name to be displayed
0142     virtual QString name() const = 0;
0143 
0144     /// short description of the resource
0145     virtual QString comment() = 0;
0146 
0147     /// xdg-compatible icon name to represent the resource, url or QIcon
0148     virtual QVariant icon() const = 0;
0149 
0150     ///@returns whether invokeApplication makes something
0151     /// false if not overridden
0152     virtual bool canExecute() const = 0;
0153 
0154     /// executes the resource, if applies.
0155     Q_SCRIPTABLE virtual void invokeApplication() const = 0;
0156 
0157     virtual State state() = 0;
0158 
0159     virtual QStringList categories() = 0;
0160     ///@returns a URL that points to the app's website
0161     virtual QUrl homepage();
0162     ///@returns a URL that points to the app's online documentation
0163     virtual QUrl helpURL();
0164     ///@returns a URL that points to the place where you can file a bug
0165     virtual QUrl bugURL();
0166     ///@returns a URL that points to the place where you can donate money to the app developer
0167     virtual QUrl donationURL();
0168     ///@returns a URL that points to the place where you can contribute to develop the app
0169     virtual QUrl contributeURL();
0170 
0171     enum Type {
0172         Application,
0173         Addon,
0174         Technical,
0175     };
0176     Q_ENUM(Type)
0177     virtual Type type() const = 0;
0178 
0179     virtual quint64 size() = 0;
0180     virtual QString sizeDescription();
0181 
0182     ///@returns a list of pairs with the name of the license and a URL pointing at it
0183     virtual QJsonArray licenses() = 0;
0184 
0185     virtual QString installedVersion() const = 0;
0186     virtual QString availableVersion() const = 0;
0187     virtual QString longDescription() = 0;
0188 
0189     virtual QString origin() const = 0;
0190     virtual QString displayOrigin() const;
0191     virtual QString section() = 0;
0192     virtual QString author() const = 0;
0193 
0194     ///@returns what kind of mime types the resource can consume
0195     virtual QStringList mimetypes() const;
0196 
0197     virtual QList<PackageState> addonsInformation() = 0;
0198 
0199     virtual QStringList extends() const;
0200 
0201     virtual QString appstreamId() const;
0202 
0203     void addMetadata(const QString &key, const QJsonValue &value);
0204     QJsonValue getMetadata(const QString &key);
0205 
0206     bool canUpgrade();
0207     bool isInstalled();
0208 
0209     ///@returns a user-readable explanation of the resource status
0210     /// by default, it will specify what state() is returning
0211     virtual QString status();
0212 
0213     AbstractResourcesBackend *backend() const;
0214     QObject *backendObject() const;
0215 
0216     /**
0217      * @returns a name sort key for faster sorting
0218      */
0219     QCollatorSortKey nameSortKey();
0220 
0221     /**
0222      * Convenience method to fetch the resource's rating
0223      *
0224      * @returns the rating for the resource or null if not available
0225      */
0226     Rating *rating() const;
0227     QVariant ratingVariant() const;
0228 
0229     bool categoryMatches(Category *cat);
0230 
0231     QSet<Category *> categoryObjects(const QVector<Category *> &cats) const;
0232 
0233     /**
0234      * @returns a url that uniquely identifies the application
0235      */
0236     virtual QUrl url() const;
0237 
0238     virtual QString executeLabel() const;
0239     virtual QString sourceIcon() const = 0;
0240     /**
0241      * @returns the date of the resource's most recent release
0242      */
0243     virtual QDate releaseDate() const = 0;
0244 
0245     virtual QSet<QString> alternativeAppstreamIds() const
0246     {
0247         return {};
0248     }
0249 
0250     virtual QString upgradeText() const;
0251 
0252     /**
0253      * @returns whether the package can ever be removed
0254      */
0255     virtual bool isRemovable() const
0256     {
0257         return true;
0258     }
0259 
0260     virtual QString versionString();
0261 
0262     virtual QString contentRatingText() const;
0263     virtual ContentIntensity contentRatingIntensity() const;
0264     virtual QString contentRatingDescription() const;
0265     virtual uint contentRatingMinimumAge() const;
0266 
0267     /**
0268      * @returns List of component URLs to display at the top of application page.
0269      */
0270     virtual QStringList topObjects() const;
0271     /**
0272      * @returns List of component URLs to display at the bottom of application page.
0273      */
0274     virtual QStringList bottomObjects() const;
0275 
0276 public Q_SLOTS:
0277     virtual void fetchScreenshots();
0278     virtual void fetchChangelog() = 0;
0279     virtual void fetchUpdateDetails()
0280     {
0281         fetchChangelog();
0282     }
0283 
0284 Q_SIGNALS:
0285     void iconChanged();
0286     void sizeChanged();
0287     void stateChanged();
0288     void licensesChanged();
0289     void ratingFetched();
0290     void longDescriptionChanged();
0291     void versionsChanged();
0292 
0293     /// response to the fetchScreenshots method
0294     void screenshotsFetched(const Screenshots &screenshots);
0295     void changelogFetched(const QString &changelog);
0296 
0297 private:
0298     void reportNewState();
0299 
0300     //     TODO: make it std::optional or make QCollatorSortKey()
0301     QScopedPointer<QCollatorSortKey> m_collatorKey;
0302     QJsonObject m_metadata;
0303 };
0304 
0305 Q_DECLARE_METATYPE(QVector<AbstractResource *>)