1 /*
2  *   SPDX-FileCopyrightText: 2012 Aleix Pol Gonzalez <aleixpol@blue-systems.com>
3  *
4  *   SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
5  */
6 
7 #ifndef ABSTRACTRESOURCE_H
8 #define ABSTRACTRESOURCE_H
9 
10 #include <QCollatorSortKey>
11 #include <QDate>
12 #include <QJsonArray>
13 #include <QJsonObject>
14 #include <QObject>
15 #include <QScopedPointer>
16 #include <QSet>
17 #include <QStringList>
18 #include <QUrl>
19 #include <QVector>
20 
21 #include "PackageState.h"
22 #include "discovercommon_export.h"
23 
24 class Category;
25 class Rating;
26 class AbstractResourcesBackend;
27 
28 /**
29  * \class AbstractResource  AbstractResource.h "AbstractResource.h"
30  *
31  * \brief This is the base class of all resources.
32  *
33  * Each backend must reimplement its own resource class which needs to derive from this one.
34  */
35 class DISCOVERCOMMON_EXPORT AbstractResource : public QObject
36 {
37     Q_OBJECT
38     Q_PROPERTY(QString name READ name CONSTANT)
39     Q_PROPERTY(QString packageName READ packageName CONSTANT)
40     Q_PROPERTY(QString comment READ comment CONSTANT)
41     Q_PROPERTY(QVariant icon READ icon NOTIFY iconChanged)
42     Q_PROPERTY(bool canExecute READ canExecute CONSTANT)
43     Q_PROPERTY(State state READ state NOTIFY stateChanged)
44     Q_PROPERTY(QString status READ status NOTIFY stateChanged)
45     Q_PROPERTY(QStringList category READ categories CONSTANT)
46     Q_PROPERTY(QUrl homepage READ homepage CONSTANT)
47     Q_PROPERTY(QUrl helpURL READ helpURL CONSTANT)
48     Q_PROPERTY(QUrl bugURL READ bugURL CONSTANT)
49     Q_PROPERTY(QUrl donationURL READ donationURL CONSTANT)
50     Q_PROPERTY(bool canUpgrade READ canUpgrade NOTIFY stateChanged)
51     Q_PROPERTY(bool isInstalled READ isInstalled NOTIFY stateChanged)
52     Q_PROPERTY(QJsonArray licenses READ licenses CONSTANT)
53     Q_PROPERTY(QString longDescription READ longDescription NOTIFY longDescriptionChanged)
54     Q_PROPERTY(QString origin READ origin CONSTANT)
55     Q_PROPERTY(QString displayOrigin READ displayOrigin CONSTANT)
56     Q_PROPERTY(int size READ size NOTIFY sizeChanged)
57     Q_PROPERTY(QString sizeDescription READ sizeDescription NOTIFY sizeChanged)
58     Q_PROPERTY(QString installedVersion READ installedVersion NOTIFY versionsChanged)
59     Q_PROPERTY(QString availableVersion READ availableVersion NOTIFY versionsChanged)
60     Q_PROPERTY(QString section READ section CONSTANT)
61     Q_PROPERTY(QStringList mimetypes READ mimetypes CONSTANT)
62     Q_PROPERTY(AbstractResourcesBackend *backend READ backend CONSTANT)
63     Q_PROPERTY(QVariant rating READ ratingVariant NOTIFY ratingFetched)
64     Q_PROPERTY(QString appstreamId READ appstreamId CONSTANT)
65     Q_PROPERTY(QString categoryDisplay READ categoryDisplay CONSTANT)
66     Q_PROPERTY(QUrl url READ url CONSTANT)
67     Q_PROPERTY(QString executeLabel READ executeLabel CONSTANT)
68     Q_PROPERTY(QString sourceIcon READ sourceIcon CONSTANT)
69     Q_PROPERTY(QString author READ author CONSTANT)
70     Q_PROPERTY(QDate releaseDate READ releaseDate NOTIFY versionsChanged)
71     Q_PROPERTY(QString upgradeText READ upgradeText NOTIFY versionsChanged)
72     Q_PROPERTY(bool isRemovable READ isRemovable CONSTANT)
73     Q_PROPERTY(QString versionString READ versionString NOTIFY versionsChanged)
74 public:
75     /**
76      * This describes the state of the resource
77      */
78     enum State {
79         /**
80          * When the resource is somehow broken
81          */
82         Broken,
83         /**
84          * This means that the resource is neither installed nor broken
85          */
86         None,
87         /**
88          * The resource is installed and up-to-date
89          */
90         Installed,
91         /**
92          * The resource is installed and an update is available
93          */
94         Upgradeable,
95     };
96     Q_ENUM(State)
97 
98     /**
99      * Constructs the AbstractResource with its corresponding backend
100      */
101     explicit AbstractResource(AbstractResourcesBackend *parent);
102     ~AbstractResource() override;
103 
104     /// used as internal identification of a resource
105     virtual QString packageName() const = 0;
106 
107     /// resource name to be displayed
108     virtual QString name() const = 0;
109 
110     /// short description of the resource
111     virtual QString comment() = 0;
112 
113     /// xdg-compatible icon name to represent the resource, url or QIcon
114     virtual QVariant icon() const = 0;
115 
116     ///@returns whether invokeApplication makes something
117     /// false if not overridden
118     virtual bool canExecute() const = 0;
119 
120     /// executes the resource, if applies.
121     Q_SCRIPTABLE virtual void invokeApplication() const = 0;
122 
123     virtual State state() = 0;
124 
125     virtual QStringList categories() = 0;
126     ///@returns a URL that points to the app's website
127     virtual QUrl homepage();
128     ///@returns a URL that points to the app's online documentation
129     virtual QUrl helpURL();
130     ///@returns a URL that points to the place where you can file a bug
131     virtual QUrl bugURL();
132     ///@returns a URL that points to the place where you can donate money to the app developer
133     virtual QUrl donationURL();
134 
135     enum Type {
136         Application,
137         Addon,
138         Technical,
139     };
140     Q_ENUM(Type);
141     virtual Type type() const = 0;
142 
143     virtual int size() = 0;
144     virtual QString sizeDescription();
145 
146     ///@returns a list of pairs with the name of the license and a URL pointing at it
147     virtual QJsonArray licenses() = 0;
148 
149     virtual QString installedVersion() const = 0;
150     virtual QString availableVersion() const = 0;
151     virtual QString longDescription() = 0;
152 
153     virtual QString origin() const = 0;
154     virtual QString displayOrigin() const;
155     virtual QString section() = 0;
156     virtual QString author() const = 0;
157 
158     ///@returns what kind of mime types the resource can consume
159     virtual QStringList mimetypes() const;
160 
161     virtual QList<PackageState> addonsInformation() = 0;
162 
163     virtual QStringList extends() const;
164 
165     virtual QString appstreamId() const;
166 
167     void addMetadata(const QString &key, const QJsonValue &value);
168     QJsonValue getMetadata(const QString &key);
169 
170     bool canUpgrade();
171     bool isInstalled();
172 
173     ///@returns a user-readable explanation of the resource status
174     /// by default, it will specify what state() is returning
175     virtual QString status();
176 
177     AbstractResourcesBackend *backend() const;
178 
179     /**
180      * @returns a name sort key for faster sorting
181      */
182     QCollatorSortKey nameSortKey();
183 
184     /**
185      * Convenience method to fetch the resource's rating
186      *
187      * @returns the rating for the resource or null if not available
188      */
189     Rating *rating() const;
190     QVariant ratingVariant() const;
191 
192     /**
193      * @returns a string defining the categories the resource belongs to
194      */
195     QString categoryDisplay() const;
196 
197     bool categoryMatches(Category *cat);
198 
199     QSet<Category *> categoryObjects(const QVector<Category *> &cats) const;
200 
201     /**
202      * @returns a url that uniquely identifies the application
203      */
204     virtual QUrl url() const;
205 
206     virtual QString executeLabel() const;
207     virtual QString sourceIcon() const = 0;
208     /**
209      * @returns the date of the resource's most recent release
210      */
211     virtual QDate releaseDate() const = 0;
212 
alternativeAppstreamIds()213     virtual QSet<QString> alternativeAppstreamIds() const
214     {
215         return {};
216     }
217 
218     virtual QString upgradeText() const;
219 
220     /**
221      * @returns whether the package can ever be removed
222      */
isRemovable()223     virtual bool isRemovable() const
224     {
225         return true;
226     }
227 
228     virtual QString versionString();
229 
230 public Q_SLOTS:
231     virtual void fetchScreenshots();
232     virtual void fetchChangelog() = 0;
fetchUpdateDetails()233     virtual void fetchUpdateDetails()
234     {
235         fetchChangelog();
236     }
237 
238 Q_SIGNALS:
239     void iconChanged();
240     void sizeChanged();
241     void stateChanged();
242     void ratingFetched();
243     void longDescriptionChanged();
244     void versionsChanged();
245 
246     /// response to the fetchScreenshots method
247     ///@p thumbnails and @p screenshots should have the same number of elements
248     void screenshotsFetched(const QList<QUrl> &thumbnails, const QList<QUrl> &screenshots);
249     void changelogFetched(const QString &changelog);
250 
251 private:
252     void reportNewState();
253 
254     //     TODO: make it std::optional or make QCollatorSortKey()
255     QScopedPointer<QCollatorSortKey> m_collatorKey;
256     QJsonObject m_metadata;
257 };
258 
259 Q_DECLARE_METATYPE(QVector<AbstractResource *>)
260 
261 #endif // ABSTRACTRESOURCE_H
262