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 | |
26 | namespace KNSCore |
27 | { |
28 | class ProviderPrivate; |
29 | struct ; |
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 | */ |
40 | class 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) |
48 | public: |
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 (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 | |
343 | Q_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 (const QList<std::shared_ptr<KNSCore::Comment>> ); |
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 | |
382 | protected: |
383 | void setName(const QString &name); |
384 | void setIcon(const QUrl &icon); |
385 | |
386 | private: |
387 | const std::unique_ptr<ProviderPrivate> d; |
388 | Q_DISABLE_COPY(Provider) |
389 | }; |
390 | |
391 | KNEWSTUFFCORE_EXPORT QDebug operator<<(QDebug, const Provider::SearchRequest &); |
392 | } |
393 | |
394 | #endif |
395 | |