1/*
2 SPDX-FileCopyrightText: 2007 Josef Spillner <spillner@kde.org>
3 SPDX-FileCopyrightText: 2007-2010 Frederik Gladhorn <gladhorn@kde.org>
4 SPDX-FileCopyrightText: 2009 Jeremy Whiting <jpwhiting@kde.org>
5
6 SPDX-License-Identifier: LGPL-2.1-or-later
7*/
8
9#ifndef KNEWSTUFF3_ENGINEBASE_H
10#define KNEWSTUFF3_ENGINEBASE_H
11
12#include <QHash>
13#include <QMetaEnum>
14#include <QObject>
15#include <QSharedPointer>
16#include <QString>
17
18#include "entry.h"
19#include "errorcode.h"
20#include "provider.h"
21
22#include "knewstuffcore_export.h"
23
24#include <memory>
25
26class KJob;
27class EnginePrivate;
28class QDomDocument;
29
30namespace Attica
31{
32class Provider;
33}
34
35namespace KNSCore
36{
37class Cache;
38class CommentsModel;
39class ResultsStream;
40class EngineBasePrivate;
41class Installation;
42
43/**
44 * KNewStuff engine.
45 * An engine keeps track of data which is available locally and remote
46 * and offers high-level synchronization calls as well as upload and download
47 * primitives using an underlying GHNS protocol.
48 *
49 * This is a base class for different engine implementations
50 */
51class KNEWSTUFFCORE_EXPORT EngineBase : public QObject
52{
53 Q_OBJECT
54
55 /**
56 * Text that should be displayed for the adoption button, this defaults to "Use"
57 * @since 5.77
58 */
59 Q_PROPERTY(QString useLabel READ useLabel NOTIFY useLabelChanged)
60
61 /**
62 * Whether or not the configuration says that the providers are expected to support uploading.
63 * As it stands, this is used to determine whether or not to show the Upload... action where
64 * that is displayed (primarily NewStuff.Page).
65 * @since 5.85
66 */
67 Q_PROPERTY(bool uploadEnabled READ uploadEnabled NOTIFY uploadEnabledChanged)
68
69 /**
70 * @since 5.85
71 */
72 Q_PROPERTY(QStringList providerIDs READ providerIDs NOTIFY providersChanged)
73
74 /**
75 * @copydoc contentWarningType
76 */
77 Q_PROPERTY(ContentWarningType contentWarningType READ contentWarningType NOTIFY contentWarningTypeChanged)
78
79public:
80 EngineBase(QObject *parent = nullptr);
81 ~EngineBase();
82
83 /**
84 * List of all available config files. This list will contain no duplicated filenames.
85 * The returned file paths are absolute.
86 * @since 5.83
87 */
88 static QStringList availableConfigFiles();
89
90 /**
91 * Initializes the engine. This step is application-specific and relies
92 * on an external configuration file, which determines all the details
93 * about the initialization.
94 *
95 * @param configfile KNewStuff2 configuration file (*.knsrc)
96 * @return \b true if any valid configuration was found, \b false otherwise
97 * @see KNS3::DownloadDialog
98 */
99 virtual bool init(const QString &configfile);
100
101 /**
102 * The name as defined by the knsrc file
103 * @return The name associated with the engine's configuration file
104 * @since 5.63
105 */
106 QString name() const;
107
108 /**
109 * Text that should be displayed for the adoption button, this defaults to i18n("Use")
110 * @since 5.77
111 */
112 QString useLabel() const;
113
114 /**
115 * Signal gets emitted when the useLabel property changes
116 * @since 5.77
117 */
118 Q_SIGNAL void useLabelChanged();
119
120 /**
121 * Whether or not the configuration says that the providers are expected to support uploading.
122 * @return True if the providers are expected to support uploading
123 * @since 5.85
124 */
125 bool uploadEnabled() const;
126
127 /**
128 * Fired when the uploadEnabled property changes
129 * @since 5.85
130 */
131 Q_SIGNAL void uploadEnabledChanged();
132
133 /**
134 * The list of the server-side names of the categories handled by this
135 * engine instance. This corresponds directly to the list of categories
136 * in your knsrc file. This is not supposed to be used as user-facing
137 * strings - @see categoriesMetadata() for that.
138 *
139 * @return The categories which this instance of Engine handles
140 */
141 QStringList categories() const;
142
143 /**
144 * Get the entries cache for this engine (note that it may be null if the engine is
145 * not yet initialized).
146 * @return The cache for this engine (or null if the engine is not initialized)
147 * @since 5.74
148 */
149 QSharedPointer<Cache> cache() const;
150
151 /**
152 * The list of metadata for the categories handled by this engine instance.
153 * If you wish to show the categories to the user, this is the data to use.
154 * The category name is the string used to set categories for the filter,
155 * and also what is returned by both categories() and categoriesFilter().
156 * The human-readable name is displayName, and the only thing which should
157 * be shown to the user.
158 *
159 * @return The metadata for all categories handled by this engine
160 */
161 QList<Provider::CategoryMetadata> categoriesMetadata();
162
163 QList<Provider::SearchPreset> searchPresets();
164
165 /**
166 * @returns the list of attica (OCS) providers this engine is connected to
167 * @since 5.92
168 */
169 QList<Attica::Provider *> atticaProviders() const;
170
171 /**
172 * Set a filter for results, which filters out all entries which do not match
173 * the filter, as applied to the tags for the entry. This filters only on the
174 * tags specified for the entry itself. To filter the downloadlinks, use
175 * setDownloadTagFilter(QStringList).
176 *
177 * @note The default filter if one is not set from your knsrc file will filter
178 * out entries marked as ghns_excluded=1. To retain this when setting a custom
179 * filter, add "ghns_excluded!=1" as one of the filters.
180 *
181 * @note Some tags provided by OCS do not supply a value (and are simply passed
182 * as a key). These will be interpreted as having the value 1 for filtering
183 * purposes. An example of this might be ghns_excluded, which in reality will
184 * generally be passed through ocs as "ghns_excluded" rather than "ghns_excluded=1"
185 *
186 * @note As tags are metadata, they are provided in the form of adjectives. They
187 * are never supplied as action verbs or instructions (as an example, a good tag
188 * to suggest that for example a wallpaper is painted would be "painted" as opposed
189 * to "paint", and another example might be that an item should be "excluded" as
190 * opposed to "exclude").
191 *
192 * == Examples of use ==
193 * Value for tag "tagname" must be exactly "tagdata":
194 * tagname==tagdata
195 *
196 * Value for tag "tagname" must be different from "tagdata":
197 * tagname!=tagdata
198 *
199 * == KNSRC entry ==
200 * A tag filter line in a .knsrc file, which is a comma separated list of
201 * tag/value pairs, might look like:
202 *
203 * TagFilter=ghns_excluded!=1,data##mimetype==application/cbr+zip,data##mimetype==application/cbr+rar
204 * which would honour the exclusion and filter out anything that does not
205 * include a comic book archive in either zip or rar format in one or more
206 * of the download items.
207 * Notice in particular that there are two data##mimetype entries. Use this
208 * for when a tag may have multiple values.
209 *
210 * TagFilter=application##architecture==x86_64
211 * which would not honour the exclusion, and would filter out all entries
212 * which do not mark themselves as having a 64bit application binary in at
213 * least one download item.
214 *
215 * The value does not current support wildcards. The list should be considered
216 * a binary AND operation (that is, all filter entries must match for the data
217 * entry to be included in the return data)
218 *
219 * @param filter The filter in the form of a list of strings
220 * @see setDownloadTagFilter(QStringList)
221 * @since 5.51
222 */
223 void setTagFilter(const QStringList &filter);
224 /**
225 * Gets the current tag filter list
226 * @see setTagFilter(QStringList)
227 * @since 5.51
228 */
229 QStringList tagFilter() const;
230 /**
231 * Add a single filter entry to the entry tag filter. The filter should be in
232 * the same form as the filter lines in the list used by setTagFilter(QStringList)
233 * @param filter The filter in the form of a string
234 * @see setTagFilter(QStringList)
235 * @since 5.51
236 */
237 void addTagFilter(const QString &filter);
238 /**
239 * Sets a filter to be applied to the downloads for an entry. The logic is the
240 * same as used in setTagFilter(QStringList), but vitally, only one downloadlink
241 * is required to match the filter for the list to be valid. If you do not wish
242 * to show the others in your client, you must hide them yourself.
243 *
244 * For an entry to be accepted when a download tag filter is set, it must also
245 * be accepted by the entry filter (so, for example, while a list of downloads
246 * might be accepted, if the entry has ghns_excluded set, and the default entry
247 * filter is set, the entry will still be filtered out).
248 *
249 * In your knsrc file, set DownloadTagFilter to the filter you wish to apply,
250 * using the same logic as described for the entry tagfilter.
251 *
252 * @param filter The filter in the form of a list of strings
253 * @see setTagFilter(QStringList)
254 * @since 5.51
255 */
256 void setDownloadTagFilter(const QStringList &filter);
257 /**
258 * Gets the current downloadlink tag filter list
259 * @see setDownloadTagFilter(QStringList)
260 * @since 5.51
261 */
262 QStringList downloadTagFilter() const;
263 /**
264 * Add a single filter entry to the download tag filter. The filter should be in
265 * the same form as the filter lines in the list used by setDownloadsTagFilter(QStringList)
266 * @param filter The filter in the form of a string
267 * @see setTagFilter(QStringList)
268 * @see setDownloadTagFilter(QStringList)
269 * @since 5.51
270 */
271 void addDownloadTagFilter(const QString &filter);
272
273 /**
274 * Whether or not a user is able to vote on the passed entry.
275 *
276 * @param entry The entry to check votability on
277 * @return True if the user is able to vote on the entry
278 */
279 bool userCanVote(const Entry &entry);
280 /**
281 * Cast a vote on the passed entry.
282 *
283 * @param entry The entry to vote on
284 * @param rating A number from 0 to 100, 50 being neutral, 0 being most negative and 100 being most positive.
285 */
286 void vote(const Entry &entry, uint rating);
287
288 /**
289 * Whether or not the user is allowed to become a fan of
290 * a particular entry.
291 * Not all providers (and consequently entries) support the fan functionality
292 * and you can use this function to determine this ability.
293 * @param entry The entry the user might wish to be a fan of
294 * @return Whether or not it is possible for the user to become a fan of that entry
295 */
296 bool userCanBecomeFan(const Entry &entry);
297 /**
298 * This will mark the user who is currently authenticated as a fan
299 * of the entry passed to the function.
300 * @param entry The entry the user wants to be a fan of
301 */
302 void becomeFan(const Entry &entry);
303 // FIXME There is currently no exposed API to remove the fan status
304
305 /**
306 * The Provider instance with the passed ID
307 *
308 * @param providerId The ID of the Provider to fetch
309 * @return The Provider with the passed ID, or null if non such Provider exists
310 * @since 5.63
311 */
312 QSharedPointer<Provider> provider(const QString &providerId) const;
313
314 /**
315 * Return the first provider in the providers list (usually the default provider)
316 * @return The first Provider (or null if the engine is not initialized)
317 * @since 5.63
318 */
319 QSharedPointer<Provider> defaultProvider() const;
320
321 /**
322 * The IDs of all providers known by this engine. Use this in combination with
323 * provider(const QString&) to iterate over all providers.
324 * @return The string IDs of all known providers
325 * @since 5.85
326 */
327 QStringList providerIDs() const;
328
329 /**
330 * Whether or not an adoption command exists for this engine
331 *
332 * @see adoptionCommand(KNSCore::Entry)
333 * @return True if an adoption command exists
334 */
335 bool hasAdoptionCommand() const;
336
337 /**
338 * Returns a stream object that will fulfill the @p request.
339 *
340 * @since 6.0
341 */
342 ResultsStream *search(const KNSCore::Provider::SearchRequest &request);
343
344 /**
345 * @brief The ContentWarningType enum
346 * @since 6.1
347 */
348 enum class ContentWarningType {
349 /**
350 * Content consists of static assets only
351 * Installation should not pose a security risk
352 */
353 Static,
354 /**
355 * Content may contain scripts or other executable code
356 * Users should be warned to treat it like any other program
357 */
358 Executables
359 };
360 Q_ENUM(ContentWarningType)
361
362 /**
363 * @brief The level of warning that should be presented to the user
364 * @since 6.1
365 * @see ContentWarningType
366 */
367 ContentWarningType contentWarningType() const;
368
369 /**
370 * Emitted after the initial config load
371 * @since 6.1
372 */
373 Q_SIGNAL void contentWarningTypeChanged();
374
375Q_SIGNALS:
376 /**
377 * Indicates a message to be added to the ui's log, or sent to a messagebox
378 */
379 void signalMessage(const QString &message);
380
381 void signalProvidersLoaded();
382
383 /**
384 * Fires in the case of any critical or serious errors, such as network or API problems.
385 * @param errorCode Represents the specific type of error which has occurred
386 * @param message A human-readable message which can be shown to the end user
387 * @param metadata Any additional data which might be hepful to further work out the details of the error (see KNSCore::Entry::ErrorCode for the
388 * metadata details)
389 * @see KNSCore::Entry::ErrorCode
390 * @since 5.53
391 */
392 void signalErrorCode(KNSCore::ErrorCode::ErrorCode errorCode, const QString &message, const QVariant &metadata);
393
394 void signalCategoriesMetadataLoded(const QList<Provider::CategoryMetadata> &categories);
395
396 /**
397 * Fires when the engine has loaded search presets. These represent interesting
398 * searches for the user, such as recommendations.
399 * @since 5.83
400 */
401 void signalSearchPresetsLoaded(const QList<Provider::SearchPreset> &presets);
402
403 /**
404 * Fired whenever the list of providers changes
405 * @since 5.85
406 */
407 void providersChanged();
408
409 void loadingProvider();
410
411private:
412 // the .knsrc file was loaded
413 void slotProviderFileLoaded(const QDomDocument &doc);
414 // instead of getting providers from knsrc, use what was configured in ocs systemsettings
415 void atticaProviderLoaded(const Attica::Provider &provider);
416 // called when a provider is ready to work
417 void providerInitialized(KNSCore::Provider *);
418
419 // loading the .knsrc file failed
420 void slotProvidersFailed();
421
422 /**
423 * load providers from the providersurl in the knsrc file
424 * creates providers based on their type and adds them to the list of providers
425 */
426 void loadProviders();
427
428protected:
429 /**
430 Add a provider and connect it to the right slots
431 */
432 virtual void addProvider(QSharedPointer<KNSCore::Provider> provider);
433 virtual void updateStatus();
434
435 friend class ResultsStream;
436 friend class Transaction;
437 Installation *installation() const; // Needed for quick engine
438 QList<QSharedPointer<Provider>> providers() const;
439 std::unique_ptr<EngineBasePrivate> d;
440};
441
442}
443
444#endif
445

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