1/*
2 knewstuff3/provider.h
3 This file is part of KNewStuff2.
4 SPDX-FileCopyrightText: 2009 Jeremy Whiting <jpwhiting@kde.org>
5 SPDX-FileCopyrightText: 2009 Frederik Gladhorn <gladhorn@kde.org>
6 SPDX-FileCopyrightText: 2021 Dan Leinir Turthra Jensen <admin@leinir.dk>
7
8 SPDX-License-Identifier: LGPL-2.1-or-later
9*/
10
11#ifndef KNEWSTUFF3_PROVIDER_P_H
12#define KNEWSTUFF3_PROVIDER_P_H
13
14#include <QDebug>
15#include <QList>
16#include <QString>
17#include <QUrl>
18
19#include <memory>
20
21#include "entry.h"
22#include "errorcode.h"
23
24#include "knewstuffcore_export.h"
25
26namespace KNSCore
27{
28class ProviderPrivate;
29struct Comment;
30/**
31 * @short KNewStuff Base Provider class.
32 *
33 * This class provides accessors for the provider object.
34 * It should not be used directly by the application.
35 * This class is the base class and will be instantiated for
36 * static website providers.
37 *
38 * @author Jeremy Whiting <jpwhiting@kde.org>
39 */
40class KNEWSTUFFCORE_EXPORT Provider : public QObject
41{
42 Q_OBJECT
43 Q_PROPERTY(QString version READ version WRITE setVersion NOTIFY basicsLoaded)
44 Q_PROPERTY(QUrl website READ website WRITE setWebsite NOTIFY basicsLoaded)
45 Q_PROPERTY(QUrl host READ host WRITE setHost NOTIFY basicsLoaded)
46 Q_PROPERTY(QString contactEmail READ contactEmail WRITE setContactEmail NOTIFY basicsLoaded)
47 Q_PROPERTY(bool supportsSsl READ supportsSsl WRITE setSupportsSsl NOTIFY basicsLoaded)
48public:
49 typedef QList<Provider *> List;
50
51 enum SortMode {
52 Newest,
53 Alphabetical,
54 Rating,
55 Downloads,
56 };
57 Q_ENUM(SortMode)
58
59 enum Filter {
60 None,
61 Installed,
62 Updates,
63 ExactEntryId,
64 };
65 Q_ENUM(Filter)
66
67 /**
68 * used to keep track of a search
69 */
70 struct SearchRequest {
71 SortMode sortMode;
72 Filter filter;
73 QString searchTerm;
74 QStringList categories;
75 int page;
76 int pageSize;
77
78 SearchRequest(SortMode sortMode_ = Downloads,
79 Filter filter_ = None,
80 const QString &searchTerm_ = QString(),
81 const QStringList &categories_ = QStringList(),
82 int page_ = -1,
83 int pageSize_ = 20)
84 : sortMode(sortMode_)
85 , filter(filter_)
86 , searchTerm(searchTerm_)
87 , categories(categories_)
88 , page(page_)
89 , pageSize(pageSize_)
90 {
91 }
92
93 QString hashForRequest() const;
94 bool operator==(const SearchRequest &other) const
95 {
96 return sortMode == other.sortMode && filter == other.filter && searchTerm == other.searchTerm && categories == other.categories
97 && page == other.page && pageSize == other.pageSize;
98 }
99 };
100
101 /**
102 * Describes a category: id/name/disaplayName
103 */
104 struct CategoryMetadata {
105 QString id;
106 QString name;
107 QString displayName;
108 };
109
110 /**
111 * @brief The SearchPresetTypes enum
112 * the preset type enum is a helper to identify the kind of label and icon
113 * the search preset should have if none are found.
114 * @since 5.83
115 */
116 enum SearchPresetTypes {
117 NoPresetType = 0,
118 GoBack, ///< preset representing the previous search.
119 Root, ///< preset indicating a root directory.
120 Start, ///< preset indicating the first entry.
121 Popular, ///< preset indicating popular items.
122 Featured, ///< preset for featured items.
123 Recommended, ///< preset for recommended. This may be customized by the server per user.
124 Shelf, ///< preset indicating previously acquired items.
125 Subscription, ///< preset indicating items that the user is subscribed to.
126 New, ///< preset indicating new items.
127 FolderUp, ///< preset indicating going up in the search result hierarchy.
128 AllEntries, ///< preset indicating all possible entries, such as a crawlable list. Might be intense to load.
129 };
130 /**
131 * Describes a search request that may come from the provider.
132 * This is used by the OPDS provider to handle the different urls.
133 * @since 5.83
134 */
135 struct SearchPreset {
136 SearchRequest request;
137 QString displayName;
138 QString iconName;
139 SearchPresetTypes type;
140 QString providerId; // not all providers can handle all search requests.
141 };
142
143 /**
144 * Constructor.
145 */
146 Provider();
147
148 /**
149 * Destructor.
150 */
151 ~Provider() override;
152
153 /**
154 * A unique Id for this provider (the url in most cases)
155 */
156 virtual QString id() const = 0;
157
158 /**
159 * Set the provider data xml, to initialize the provider.
160 * The Provider needs to have it's ID set in this function and cannot change it from there on.
161 */
162 virtual bool setProviderXML(const QDomElement &xmldata) = 0;
163
164 virtual bool isInitialized() const = 0;
165
166 virtual void setCachedEntries(const KNSCore::Entry::List &cachedEntries) = 0;
167
168 /**
169 * Retrieves the common name of the provider.
170 *
171 * @return provider name
172 */
173 virtual QString name() const;
174
175 /**
176 * Retrieves the icon URL for this provider.
177 *
178 * @return icon URL
179 */
180 virtual QUrl icon() const; // FIXME use QIcon::fromTheme or pixmap?
181
182 /**
183 * load the given search and return given page
184 * @param sortMode string to select the order in which the results are presented
185 * @param searchstring string to search with
186 * @param page page number to load
187 *
188 * Note: the engine connects to loadingFinished() signal to get the result
189 */
190 virtual void loadEntries(const KNSCore::Provider::SearchRequest &request) = 0;
191 virtual void loadEntryDetails(const KNSCore::Entry &)
192 {
193 }
194 virtual void loadPayloadLink(const Entry &entry, int linkId) = 0;
195 /**
196 * Request a loading of comments from this provider. The engine listens to the
197 * commentsLoaded() signal for the result
198 *
199 * @note Implementation detail: All subclasses should connect to this signal
200 * and point it at a slot which does the actual work, if they support comments.
201 *
202 * @see commentsLoaded(const QList<shared_ptr<KNSCore::Comment>> comments)
203 * @since 5.63
204 */
205 virtual void loadComments(const KNSCore::Entry &, int /*commentsPerPage*/, int /*page*/)
206 {
207 }
208
209 /**
210 * Request loading of the details for a specific person with the given username.
211 * The engine listens to the personLoaded() for the result
212 *
213 * @note Implementation detail: All subclasses should connect to this signal
214 * and point it at a slot which does the actual work, if they support comments.
215 *
216 * @since 5.63
217 */
218 virtual void loadPerson(const QString & /*username*/)
219 {
220 }
221
222 /**
223 * Request loading of the basic information for this provider. The engine listens
224 * to the basicsLoaded() signal for the result, which is also the signal the respective
225 * properties listen to.
226 *
227 * This is fired automatically on the first attempt to read one of the properties
228 * which contain this basic information, and you will not need to call it as a user
229 * of the class (just listen to the properties, which will update when the information
230 * has been fetched).
231 *
232 * @note Implementation detail: All subclasses should connect to this signal
233 * and point it at a slot which does the actual work, if they support fetching
234 * this basic information (if the information is set during construction, you will
235 * not need to worry about this).
236 *
237 * @see version()
238 * @see website()
239 * @see host();
240 * @see contactEmail()
241 * @see supportsSsl()
242 * @since 5.85
243 */
244 virtual void loadBasics()
245 {
246 }
247
248 /**
249 * @since 5.85
250 */
251 QString version() const;
252 /**
253 * @since 5.85
254 */
255 void setVersion(const QString &version);
256 /**
257 * @since 5.85
258 */
259 QUrl website() const;
260 /**
261 * @since 5.85
262 */
263 void setWebsite(const QUrl &website);
264 /**
265 * @since 5.85
266 */
267 QUrl host() const;
268 /**
269 * @param host The host used for this provider
270 * @since 5.85
271 */
272 void setHost(const QUrl &host);
273 /**
274 * The general contact email for this provider
275 * @return The general contact email for this provider
276 * @since 5.85
277 */
278 QString contactEmail() const;
279 /**
280 * Sets the general contact email address for this provider
281 * @param contactEmail The general contact email for this provider
282 * @since 5.85
283 */
284 void setContactEmail(const QString &contactEmail);
285 /**
286 * Whether or not the provider supports SSL connections
287 * @return True if the server supports SSL connections, false if not
288 * @since 5.85
289 */
290 bool supportsSsl() const;
291 /**
292 * Set whether or not the provider supports SSL connections
293 * @param supportsSsl True if the server supports SSL connections, false if not
294 * @since 5.85
295 */
296 void setSupportsSsl(bool supportsSsl);
297
298 virtual bool userCanVote()
299 {
300 return false;
301 }
302 virtual void vote(const Entry & /*entry*/, uint /*rating*/)
303 {
304 }
305
306 virtual bool userCanBecomeFan()
307 {
308 return false;
309 }
310 virtual void becomeFan(const Entry & /*entry*/)
311 {
312 }
313
314 /**
315 * Set the tag filter used for entries by this provider
316 * @param tagFilter The new list of filters
317 * @see Engine::setTagFilter(QStringList)
318 * @since 5.51
319 */
320 void setTagFilter(const QStringList &tagFilter);
321 /**
322 * The tag filter used for downloads by this provider
323 * @return The list of filters
324 * @see Engine::setTagFilter(QStringList)
325 * @since 5.51
326 */
327 QStringList tagFilter() const;
328 /**
329 * Set the tag filter used for download items by this provider
330 * @param downloadTagFilter The new list of filters
331 * @see Engine::setDownloadTagFilter(QStringList)
332 * @since 5.51
333 */
334 void setDownloadTagFilter(const QStringList &downloadTagFilter);
335 /**
336 * The tag filter used for downloads by this provider
337 * @return The list of filters
338 * @see Engine::setDownloadTagFilter(QStringList)
339 * @since 5.51
340 */
341 QStringList downloadTagFilter() const;
342
343Q_SIGNALS:
344 void providerInitialized(KNSCore::Provider *);
345
346 void loadingFinished(const KNSCore::Provider::SearchRequest &, const KNSCore::Entry::List &);
347 void loadingFailed(const KNSCore::Provider::SearchRequest &);
348
349 void entryDetailsLoaded(const KNSCore::Entry &);
350 void payloadLinkLoaded(const KNSCore::Entry &);
351 /**
352 * Fired when new comments have been loaded
353 * @param comments The list of newly loaded comments, in a depth-first order
354 * @since 5.63
355 */
356 void commentsLoaded(const QList<std::shared_ptr<KNSCore::Comment>> comments);
357 /**
358 * Fired when the details of a person have been loaded
359 * @param author The person we've just loaded data for
360 * @since 5.63
361 */
362 void personLoaded(const std::shared_ptr<KNSCore::Author> author);
363 /**
364 * Fired when the provider's basic information has been fetched and updated
365 * @since 5.85
366 */
367 void basicsLoaded();
368
369 /**
370 * Fires when the provider has loaded search presets. These represent interesting
371 * searches for the user, such as recommendations.
372 * @since 5.83
373 */
374 void searchPresetsLoaded(const QList<KNSCore::Provider::SearchPreset> &presets);
375
376 void signalInformation(const QString &);
377 void signalError(const QString &);
378 void signalErrorCode(KNSCore::ErrorCode::ErrorCode errorCode, const QString &message, const QVariant &metadata);
379
380 void categoriesMetadataLoded(const QList<KNSCore::Provider::CategoryMetadata> &categories);
381
382protected:
383 void setName(const QString &name);
384 void setIcon(const QUrl &icon);
385
386private:
387 const std::unique_ptr<ProviderPrivate> d;
388 Q_DISABLE_COPY(Provider)
389};
390
391KNEWSTUFFCORE_EXPORT QDebug operator<<(QDebug, const Provider::SearchRequest &);
392}
393
394#endif
395

source code of knewstuff/src/core/provider.h