File indexing completed on 2024-04-28 03:56:25
0001 /* 0002 SPDX-FileCopyrightText: 2007 Josef Spillner <spillner@kde.org> 0003 SPDX-FileCopyrightText: 2007-2010 Frederik Gladhorn <gladhorn@kde.org> 0004 SPDX-FileCopyrightText: 2009 Jeremy Whiting <jpwhiting@kde.org> 0005 0006 SPDX-License-Identifier: LGPL-2.1-or-later 0007 */ 0008 0009 #ifndef KNEWSTUFF3_ENGINEBASE_H 0010 #define KNEWSTUFF3_ENGINEBASE_H 0011 0012 #include <QHash> 0013 #include <QObject> 0014 #include <QSharedPointer> 0015 #include <QString> 0016 0017 #include "entry.h" 0018 #include "errorcode.h" 0019 #include "provider.h" 0020 0021 #include "knewstuffcore_export.h" 0022 0023 #include <memory> 0024 0025 class KJob; 0026 class EnginePrivate; 0027 class QDomDocument; 0028 0029 namespace Attica 0030 { 0031 class Provider; 0032 } 0033 0034 namespace KNSCore 0035 { 0036 class Cache; 0037 class CommentsModel; 0038 class ResultsStream; 0039 class EngineBasePrivate; 0040 class Installation; 0041 0042 /** 0043 * KNewStuff engine. 0044 * An engine keeps track of data which is available locally and remote 0045 * and offers high-level synchronization calls as well as upload and download 0046 * primitives using an underlying GHNS protocol. 0047 * 0048 * This is a base class for different engine implementations 0049 */ 0050 class KNEWSTUFFCORE_EXPORT EngineBase : public QObject 0051 { 0052 Q_OBJECT 0053 0054 /** 0055 * Text that should be displayed for the adoption button, this defaults to "Use" 0056 * @since 5.77 0057 */ 0058 Q_PROPERTY(QString useLabel READ useLabel NOTIFY useLabelChanged) 0059 0060 /** 0061 * Whether or not the configuration says that the providers are expected to support uploading. 0062 * As it stands, this is used to determine whether or not to show the Upload... action where 0063 * that is displayed (primarily NewStuff.Page). 0064 * @since 5.85 0065 */ 0066 Q_PROPERTY(bool uploadEnabled READ uploadEnabled NOTIFY uploadEnabledChanged) 0067 0068 /** 0069 * @since 5.85 0070 */ 0071 Q_PROPERTY(QStringList providerIDs READ providerIDs NOTIFY providersChanged) 0072 0073 public: 0074 EngineBase(QObject *parent = nullptr); 0075 ~EngineBase(); 0076 0077 /** 0078 * List of all available config files. This list will contain no duplicated filenames. 0079 * The returned file paths are absolute. 0080 * @since 5.83 0081 */ 0082 static QStringList availableConfigFiles(); 0083 0084 /** 0085 * Initializes the engine. This step is application-specific and relies 0086 * on an external configuration file, which determines all the details 0087 * about the initialization. 0088 * 0089 * @param configfile KNewStuff2 configuration file (*.knsrc) 0090 * @return \b true if any valid configuration was found, \b false otherwise 0091 * @see KNS3::DownloadDialog 0092 */ 0093 virtual bool init(const QString &configfile); 0094 0095 /** 0096 * The name as defined by the knsrc file 0097 * @return The name associated with the engine's configuration file 0098 * @since 5.63 0099 */ 0100 QString name() const; 0101 0102 /** 0103 * Text that should be displayed for the adoption button, this defaults to i18n("Use") 0104 * @since 5.77 0105 */ 0106 QString useLabel() const; 0107 0108 /** 0109 * Signal gets emitted when the useLabel property changes 0110 * @since 5.77 0111 */ 0112 Q_SIGNAL void useLabelChanged(); 0113 0114 /** 0115 * Whether or not the configuration says that the providers are expected to support uploading. 0116 * @return True if the providers are expected to support uploading 0117 * @since 5.85 0118 */ 0119 bool uploadEnabled() const; 0120 0121 /** 0122 * Fired when the uploadEnabled property changes 0123 * @since 5.85 0124 */ 0125 Q_SIGNAL void uploadEnabledChanged(); 0126 0127 /** 0128 * The list of the server-side names of the categories handled by this 0129 * engine instance. This corresponds directly to the list of categories 0130 * in your knsrc file. This is not supposed to be used as user-facing 0131 * strings - @see categoriesMetadata() for that. 0132 * 0133 * @return The categories which this instance of Engine handles 0134 */ 0135 QStringList categories() const; 0136 0137 /** 0138 * Get the entries cache for this engine (note that it may be null if the engine is 0139 * not yet initialized). 0140 * @return The cache for this engine (or null if the engine is not initialized) 0141 * @since 5.74 0142 */ 0143 QSharedPointer<Cache> cache() const; 0144 0145 /** 0146 * The list of metadata for the categories handled by this engine instance. 0147 * If you wish to show the categories to the user, this is the data to use. 0148 * The category name is the string used to set categories for the filter, 0149 * and also what is returned by both categories() and categoriesFilter(). 0150 * The human-readable name is displayName, and the only thing which should 0151 * be shown to the user. 0152 * 0153 * @return The metadata for all categories handled by this engine 0154 */ 0155 QList<Provider::CategoryMetadata> categoriesMetadata(); 0156 0157 QList<Provider::SearchPreset> searchPresets(); 0158 0159 /** 0160 * @returns the list of attica (OCS) providers this engine is connected to 0161 * @since 5.92 0162 */ 0163 QList<Attica::Provider *> atticaProviders() const; 0164 0165 /** 0166 * Set a filter for results, which filters out all entries which do not match 0167 * the filter, as applied to the tags for the entry. This filters only on the 0168 * tags specified for the entry itself. To filter the downloadlinks, use 0169 * setDownloadTagFilter(QStringList). 0170 * 0171 * @note The default filter if one is not set from your knsrc file will filter 0172 * out entries marked as ghns_excluded=1. To retain this when setting a custom 0173 * filter, add "ghns_excluded!=1" as one of the filters. 0174 * 0175 * @note Some tags provided by OCS do not supply a value (and are simply passed 0176 * as a key). These will be interpreted as having the value 1 for filtering 0177 * purposes. An example of this might be ghns_excluded, which in reality will 0178 * generally be passed through ocs as "ghns_excluded" rather than "ghns_excluded=1" 0179 * 0180 * @note As tags are metadata, they are provided in the form of adjectives. They 0181 * are never supplied as action verbs or instructions (as an example, a good tag 0182 * to suggest that for example a wallpaper is painted would be "painted" as opposed 0183 * to "paint", and another example might be that an item should be "excluded" as 0184 * opposed to "exclude"). 0185 * 0186 * == Examples of use == 0187 * Value for tag "tagname" must be exactly "tagdata": 0188 * tagname==tagdata 0189 * 0190 * Value for tag "tagname" must be different from "tagdata": 0191 * tagname!=tagdata 0192 * 0193 * == KNSRC entry == 0194 * A tag filter line in a .knsrc file, which is a comma separated list of 0195 * tag/value pairs, might look like: 0196 * 0197 * TagFilter=ghns_excluded!=1,data##mimetype==application/cbr+zip,data##mimetype==application/cbr+rar 0198 * which would honour the exclusion and filter out anything that does not 0199 * include a comic book archive in either zip or rar format in one or more 0200 * of the download items. 0201 * Notice in particular that there are two data##mimetype entries. Use this 0202 * for when a tag may have multiple values. 0203 * 0204 * TagFilter=application##architecture==x86_64 0205 * which would not honour the exclusion, and would filter out all entries 0206 * which do not mark themselves as having a 64bit application binary in at 0207 * least one download item. 0208 * 0209 * The value does not current support wildcards. The list should be considered 0210 * a binary AND operation (that is, all filter entries must match for the data 0211 * entry to be included in the return data) 0212 * 0213 * @param filter The filter in the form of a list of strings 0214 * @see setDownloadTagFilter(QStringList) 0215 * @since 5.51 0216 */ 0217 void setTagFilter(const QStringList &filter); 0218 /** 0219 * Gets the current tag filter list 0220 * @see setTagFilter(QStringList) 0221 * @since 5.51 0222 */ 0223 QStringList tagFilter() const; 0224 /** 0225 * Add a single filter entry to the entry tag filter. The filter should be in 0226 * the same form as the filter lines in the list used by setTagFilter(QStringList) 0227 * @param filter The filter in the form of a string 0228 * @see setTagFilter(QStringList) 0229 * @since 5.51 0230 */ 0231 void addTagFilter(const QString &filter); 0232 /** 0233 * Sets a filter to be applied to the downloads for an entry. The logic is the 0234 * same as used in setTagFilter(QStringList), but vitally, only one downloadlink 0235 * is required to match the filter for the list to be valid. If you do not wish 0236 * to show the others in your client, you must hide them yourself. 0237 * 0238 * For an entry to be accepted when a download tag filter is set, it must also 0239 * be accepted by the entry filter (so, for example, while a list of downloads 0240 * might be accepted, if the entry has ghns_excluded set, and the default entry 0241 * filter is set, the entry will still be filtered out). 0242 * 0243 * In your knsrc file, set DownloadTagFilter to the filter you wish to apply, 0244 * using the same logic as described for the entry tagfilter. 0245 * 0246 * @param filter The filter in the form of a list of strings 0247 * @see setTagFilter(QStringList) 0248 * @since 5.51 0249 */ 0250 void setDownloadTagFilter(const QStringList &filter); 0251 /** 0252 * Gets the current downloadlink tag filter list 0253 * @see setDownloadTagFilter(QStringList) 0254 * @since 5.51 0255 */ 0256 QStringList downloadTagFilter() const; 0257 /** 0258 * Add a single filter entry to the download tag filter. The filter should be in 0259 * the same form as the filter lines in the list used by setDownloadsTagFilter(QStringList) 0260 * @param filter The filter in the form of a string 0261 * @see setTagFilter(QStringList) 0262 * @see setDownloadTagFilter(QStringList) 0263 * @since 5.51 0264 */ 0265 void addDownloadTagFilter(const QString &filter); 0266 0267 /** 0268 * Whether or not a user is able to vote on the passed entry. 0269 * 0270 * @param entry The entry to check votability on 0271 * @return True if the user is able to vote on the entry 0272 */ 0273 bool userCanVote(const Entry &entry); 0274 /** 0275 * Cast a vote on the passed entry. 0276 * 0277 * @param entry The entry to vote on 0278 * @param rating A number from 0 to 100, 50 being neutral, 0 being most negative and 100 being most positive. 0279 */ 0280 void vote(const Entry &entry, uint rating); 0281 0282 /** 0283 * Whether or not the user is allowed to become a fan of 0284 * a particular entry. 0285 * Not all providers (and consequently entries) support the fan functionality 0286 * and you can use this function to determine this ability. 0287 * @param entry The entry the user might wish to be a fan of 0288 * @return Whether or not it is possible for the user to become a fan of that entry 0289 */ 0290 bool userCanBecomeFan(const Entry &entry); 0291 /** 0292 * This will mark the user who is currently authenticated as a fan 0293 * of the entry passed to the function. 0294 * @param entry The entry the user wants to be a fan of 0295 */ 0296 void becomeFan(const Entry &entry); 0297 // FIXME There is currently no exposed API to remove the fan status 0298 0299 /** 0300 * The Provider instance with the passed ID 0301 * 0302 * @param providerId The ID of the Provider to fetch 0303 * @return The Provider with the passed ID, or null if non such Provider exists 0304 * @since 5.63 0305 */ 0306 QSharedPointer<Provider> provider(const QString &providerId) const; 0307 0308 /** 0309 * Return the first provider in the providers list (usually the default provider) 0310 * @return The first Provider (or null if the engine is not initialized) 0311 * @since 5.63 0312 */ 0313 QSharedPointer<Provider> defaultProvider() const; 0314 0315 /** 0316 * The IDs of all providers known by this engine. Use this in combination with 0317 * provider(const QString&) to iterate over all providers. 0318 * @return The string IDs of all known providers 0319 * @since 5.85 0320 */ 0321 QStringList providerIDs() const; 0322 0323 /** 0324 * Whether or not an adoption command exists for this engine 0325 * 0326 * @see adoptionCommand(KNSCore::Entry) 0327 * @return True if an adoption command exists 0328 */ 0329 bool hasAdoptionCommand() const; 0330 0331 /** 0332 * Returns a stream object that will fulfill the @p request. 0333 * 0334 * @since 6.0 0335 */ 0336 ResultsStream *search(const KNSCore::Provider::SearchRequest &request); 0337 0338 Q_SIGNALS: 0339 /** 0340 * Indicates a message to be added to the ui's log, or sent to a messagebox 0341 */ 0342 void signalMessage(const QString &message); 0343 0344 void signalProvidersLoaded(); 0345 0346 /** 0347 * Fires in the case of any critical or serious errors, such as network or API problems. 0348 * @param errorCode Represents the specific type of error which has occurred 0349 * @param message A human-readable message which can be shown to the end user 0350 * @param metadata Any additional data which might be hepful to further work out the details of the error (see KNSCore::Entry::ErrorCode for the 0351 * metadata details) 0352 * @see KNSCore::Entry::ErrorCode 0353 * @since 5.53 0354 */ 0355 void signalErrorCode(KNSCore::ErrorCode::ErrorCode errorCode, const QString &message, const QVariant &metadata); 0356 0357 void signalCategoriesMetadataLoded(const QList<Provider::CategoryMetadata> &categories); 0358 0359 /** 0360 * Fires when the engine has loaded search presets. These represent interesting 0361 * searches for the user, such as recommendations. 0362 * @since 5.83 0363 */ 0364 void signalSearchPresetsLoaded(const QList<Provider::SearchPreset> &presets); 0365 0366 /** 0367 * Fired whenever the list of providers changes 0368 * @since 5.85 0369 */ 0370 void providersChanged(); 0371 0372 void loadingProvider(); 0373 0374 private: 0375 // the .knsrc file was loaded 0376 void slotProviderFileLoaded(const QDomDocument &doc); 0377 // instead of getting providers from knsrc, use what was configured in ocs systemsettings 0378 void atticaProviderLoaded(const Attica::Provider &provider); 0379 // called when a provider is ready to work 0380 void providerInitialized(KNSCore::Provider *); 0381 0382 // loading the .knsrc file failed 0383 void slotProvidersFailed(); 0384 0385 /** 0386 * load providers from the providersurl in the knsrc file 0387 * creates providers based on their type and adds them to the list of providers 0388 */ 0389 void loadProviders(); 0390 0391 protected: 0392 /** 0393 Add a provider and connect it to the right slots 0394 */ 0395 virtual void addProvider(QSharedPointer<KNSCore::Provider> provider); 0396 virtual void updateStatus(); 0397 0398 friend class ResultsStream; 0399 friend class Transaction; 0400 Installation *installation() const; // Needed for quick engine 0401 QList<QSharedPointer<Provider>> providers() const; 0402 std::unique_ptr<EngineBasePrivate> d; 0403 }; 0404 0405 } 0406 0407 #endif