File indexing completed on 2024-04-28 15:28:58

0001 /*
0002     knewstuff3/provider.h
0003     This file is part of KNewStuff2.
0004     SPDX-FileCopyrightText: 2009 Jeremy Whiting <jpwhiting@kde.org>
0005     SPDX-FileCopyrightText: 2009 Frederik Gladhorn <gladhorn@kde.org>
0006     SPDX-FileCopyrightText: 2021 Dan Leinir Turthra Jensen <admin@leinir.dk>
0007 
0008     SPDX-License-Identifier: LGPL-2.1-or-later
0009 */
0010 
0011 #ifndef KNEWSTUFF3_PROVIDER_P_H
0012 #define KNEWSTUFF3_PROVIDER_P_H
0013 
0014 #include <QDebug>
0015 #include <QList>
0016 #include <QString>
0017 #include <QUrl>
0018 
0019 #include <memory>
0020 
0021 #include "entryinternal.h"
0022 #include "errorcode.h"
0023 
0024 #include "knewstuffcore_export.h"
0025 
0026 
0027 namespace KNSCore
0028 {
0029 struct Comment;
0030 /**
0031  * @short KNewStuff Base Provider class.
0032  *
0033  * This class provides accessors for the provider object.
0034  * It should not be used directly by the application.
0035  * This class is the base class and will be instantiated for
0036  * static website providers.
0037  *
0038  * @author Jeremy Whiting <jpwhiting@kde.org>
0039  *
0040  * @internal
0041  */
0042 class KNEWSTUFFCORE_EXPORT Provider : public QObject
0043 {
0044     Q_OBJECT
0045     Q_PROPERTY(QString version READ version WRITE setVersion NOTIFY basicsLoaded)
0046     Q_PROPERTY(QUrl website READ website WRITE setWebsite NOTIFY basicsLoaded)
0047     Q_PROPERTY(QUrl host READ host WRITE setHost NOTIFY basicsLoaded)
0048     Q_PROPERTY(QString contactEmail READ contactEmail WRITE setContactEmail NOTIFY basicsLoaded)
0049     Q_PROPERTY(bool supportsSsl READ supportsSsl WRITE setSupportsSsl NOTIFY basicsLoaded)
0050 public:
0051     typedef QList<Provider *> List;
0052 
0053     enum SortMode {
0054         Newest,
0055         Alphabetical,
0056         Rating,
0057         Downloads,
0058     };
0059     Q_ENUM(SortMode)
0060 
0061     enum Filter {
0062         None,
0063         Installed,
0064         Updates,
0065         ExactEntryId,
0066     };
0067     Q_ENUM(Filter)
0068 
0069     /**
0070      * used to keep track of a search
0071      */
0072     struct SearchRequest {
0073         SortMode sortMode;
0074         Filter filter;
0075         QString searchTerm;
0076         QStringList categories;
0077         int page;
0078         int pageSize;
0079 
0080         SearchRequest(SortMode sortMode_ = Newest,
0081                       Filter filter_ = None,
0082                       const QString &searchTerm_ = QString(),
0083                       const QStringList &categories_ = QStringList(),
0084                       int page_ = -1,
0085                       int pageSize_ = 20)
0086             : sortMode(sortMode_)
0087             , filter(filter_)
0088             , searchTerm(searchTerm_)
0089             , categories(categories_)
0090             , page(page_)
0091             , pageSize(pageSize_)
0092         {
0093         }
0094 
0095         QString hashForRequest() const;
0096     };
0097 
0098     /**
0099      * Describes a category: id/name/disaplayName
0100      */
0101     struct CategoryMetadata {
0102         QString id;
0103         QString name;
0104         QString displayName;
0105     };
0106 
0107     /**
0108      * @brief The SearchPresetTypes enum
0109      * the preset type enum is a helper to identify the kind of label and icon
0110      * the search preset should have if none are found.
0111      * @since 5.83
0112      */
0113     enum SearchPresetTypes {
0114         NoPresetType = 0,
0115         GoBack, ///< preset representing the previous search.
0116         Root, ///< preset indicating a root directory.
0117         Start, ///< preset indicating the first entry.
0118         Popular, ///< preset indicating popular items.
0119         Featured, ///< preset for featured items.
0120         Recommended, ///< preset for recommended. This may be customized by the server per user.
0121         Shelf, ///< preset indicating previously acquired items.
0122         Subscription, ///< preset indicating items that the user is subscribed to.
0123         New, ///< preset indicating new items.
0124         FolderUp, ///< preset indicating going up in the search result hierarchy.
0125         AllEntries, ///< preset indicating all possible entries, such as a crawlable list. Might be intense to load.
0126     };
0127     /**
0128      * Describes a search request that may come from the provider.
0129      * This is used by the OPDS provider to handle the different urls.
0130      * @since 5.83
0131      */
0132     struct SearchPreset {
0133         SearchRequest request;
0134         QString displayName;
0135         QString iconName;
0136         SearchPresetTypes type;
0137         QString providerId; // not all providers can handle all search requests.
0138     };
0139 
0140     /**
0141      * Constructor.
0142      */
0143     Provider();
0144 
0145     /**
0146      * Destructor.
0147      */
0148     ~Provider() override;
0149 
0150     /**
0151      * A unique Id for this provider (the url in most cases)
0152      */
0153     virtual QString id() const = 0;
0154 
0155     /**
0156      * Set the provider data xml, to initialize the provider.
0157      * The Provider needs to have it's ID set in this function and cannot change it from there on.
0158      */
0159     virtual bool setProviderXML(const QDomElement &xmldata) = 0;
0160 
0161     virtual bool isInitialized() const = 0;
0162 
0163     virtual void setCachedEntries(const KNSCore::EntryInternal::List &cachedEntries) = 0;
0164 
0165     /**
0166      * Retrieves the common name of the provider.
0167      *
0168      * @return provider name
0169      */
0170     virtual QString name() const;
0171 
0172     /**
0173      * Retrieves the icon URL for this provider.
0174      *
0175      * @return icon URL
0176      */
0177     virtual QUrl icon() const; // FIXME use QIcon::fromTheme or pixmap?
0178 
0179     /**
0180      * load the given search and return given page
0181      * @param sortMode string to select the order in which the results are presented
0182      * @param searchstring string to search with
0183      * @param page         page number to load
0184      *
0185      * Note: the engine connects to loadingFinished() signal to get the result
0186      */
0187     virtual void loadEntries(const KNSCore::Provider::SearchRequest &request) = 0;
0188     virtual void loadEntryDetails(const KNSCore::EntryInternal &)
0189     {
0190     }
0191     virtual void loadPayloadLink(const EntryInternal &entry, int linkId) = 0;
0192     /**
0193      * Request a loading of comments from this provider. The engine listens to the
0194      * commentsLoaded() signal for the result
0195      *
0196      * @note Implementation detail: All subclasses should connect to this signal
0197      * and point it at a slot which does the actual work, if they support comments.
0198      *
0199      * TODO: KF6 This should be a virtual function, but can't do it now because BIC
0200      * @see commentsLoaded(const QList<shared_ptr<KNSCore::Comment>> comments)
0201      * @since 5.63
0202      */
0203     Q_SIGNAL void loadComments(const EntryInternal &entry, int commentsPerPage, int page);
0204     /**
0205      * Request loading of the details for a specific person with the given username.
0206      * The engine listens to the personLoaded() for the result
0207      *
0208      * @note Implementation detail: All subclasses should connect to this signal
0209      * and point it at a slot which does the actual work, if they support comments.
0210      *
0211      * TODO: KF6 This should be a virtual function, but can't do it now because BIC
0212      * @since 5.63
0213      */
0214     Q_SIGNAL void loadPerson(const QString &username);
0215     /**
0216      * Request loading of the basic information for this provider. The engine listens
0217      * to the basicsLoaded() signal for the result, which is also the signal the respective
0218      * properties listen to.
0219      *
0220      * This is fired automatically on the first attempt to read one of the properties
0221      * which contain this basic information, and you will not need to call it as a user
0222      * of the class (just listen to the properties, which will update when the information
0223      * has been fetched).
0224      *
0225      * @note Implementation detail: All subclasses should connect to this signal
0226      * and point it at a slot which does the actual work, if they support fetching
0227      * this basic information (if the information is set during construction, you will
0228      * not need to worry about this).
0229      *
0230      * TODO: KF6 This should be a virtual function, but can't do it now because BIC
0231      * @see version()
0232      * @see website()
0233      * @see host();
0234      * @see contactEmail()
0235      * @see supportsSsl()
0236      * @since 5.85
0237      */
0238     Q_SIGNAL void loadBasics();
0239     /**
0240      * @since 5.85
0241      */
0242     QString version() const;
0243     /**
0244      * @since 5.85
0245      */
0246     void setVersion(const QString &version);
0247     /**
0248      * @since 5.85
0249      */
0250     QUrl website() const;
0251     /**
0252      * @since 5.85
0253      */
0254     void setWebsite(const QUrl &website);
0255     /**
0256      * @since 5.85
0257      */
0258     QUrl host() const;
0259     /**
0260      * @param host The host used for this provider
0261      * @since 5.85
0262      */
0263     void setHost(const QUrl &host);
0264     /**
0265      * The general contact email for this provider
0266      * @return The general contact email for this provider
0267      * @since 5.85
0268      */
0269     QString contactEmail() const;
0270     /**
0271      * Sets the general contact email address for this provider
0272      * @param contactEmail The general contact email for this provider
0273      * @since 5.85
0274      */
0275     void setContactEmail(const QString &contactEmail);
0276     /**
0277      * Whether or not the provider supports SSL connections
0278      * @return True if the server supports SSL connections, false if not
0279      * @since 5.85
0280      */
0281     bool supportsSsl() const;
0282     /**
0283      * Set whether or not the provider supports SSL connections
0284      * @param supportsSsl True if the server supports SSL connections, false if not
0285      * @since 5.85
0286      */
0287     void setSupportsSsl(bool supportsSsl);
0288 
0289     virtual bool userCanVote()
0290     {
0291         return false;
0292     }
0293     virtual void vote(const EntryInternal &entry, uint rating)
0294     {
0295         Q_UNUSED(entry)
0296         Q_UNUSED(rating)
0297     }
0298 
0299     virtual bool userCanBecomeFan()
0300     {
0301         return false;
0302     }
0303     virtual void becomeFan(const EntryInternal &entry)
0304     {
0305         Q_UNUSED(entry)
0306     }
0307 
0308     /**
0309      * Set the tag filter used for entries by this provider
0310      * @param tagFilter The new list of filters
0311      * @see Engine::setTagFilter(QStringList)
0312      * @since 5.51
0313      */
0314     void setTagFilter(const QStringList &tagFilter);
0315     /**
0316      * The tag filter used for downloads by this provider
0317      * @return The list of filters
0318      * @see Engine::setTagFilter(QStringList)
0319      * @since 5.51
0320      */
0321     QStringList tagFilter() const;
0322     /**
0323      * Set the tag filter used for download items by this provider
0324      * @param downloadTagFilter The new list of filters
0325      * @see Engine::setDownloadTagFilter(QStringList)
0326      * @since 5.51
0327      */
0328     void setDownloadTagFilter(const QStringList &downloadTagFilter);
0329     /**
0330      * The tag filter used for downloads by this provider
0331      * @return The list of filters
0332      * @see Engine::setDownloadTagFilter(QStringList)
0333      * @since 5.51
0334      */
0335     QStringList downloadTagFilter() const;
0336 
0337 Q_SIGNALS:
0338     void providerInitialized(KNSCore::Provider *);
0339 
0340     void loadingFinished(const KNSCore::Provider::SearchRequest &, const KNSCore::EntryInternal::List &) const;
0341     void loadingFailed(const KNSCore::Provider::SearchRequest &);
0342 
0343     void entryDetailsLoaded(const KNSCore::EntryInternal &);
0344     void payloadLinkLoaded(const KNSCore::EntryInternal &);
0345     /**
0346      * Fired when new comments have been loaded
0347      * @param comments The list of newly loaded comments, in a depth-first order
0348      * @since 5.63
0349      */
0350     void commentsLoaded(const QList<std::shared_ptr<KNSCore::Comment>> comments);
0351     /**
0352      * Fired when the details of a person have been loaded
0353      * @param author The person we've just loaded data for
0354      * @since 5.63
0355      */
0356     void personLoaded(const std::shared_ptr<KNSCore::Author> author);
0357     /**
0358      * Fired when the provider's basic information has been fetched and updated
0359      * @since 5.85
0360      */
0361     void basicsLoaded();
0362 
0363     /**
0364      * Fires when the provider has loaded search presets. These represent interesting
0365      * searches for the user, such as recommendations.
0366      * @since 5.83
0367      */
0368     void searchPresetsLoaded(const QList<SearchPreset> &presets);
0369 
0370     void signalInformation(const QString &) const;
0371     void signalError(const QString &) const;
0372     void signalErrorCode(const KNSCore::ErrorCode &errorCode, const QString &message, const QVariant &metadata) const;
0373 
0374     void categoriesMetadataLoded(const QList<CategoryMetadata> &categories);
0375 
0376 protected:
0377     QString mName;
0378     QUrl mIcon;
0379 
0380 private:
0381     Q_DISABLE_COPY(Provider)
0382 };
0383 
0384 KNEWSTUFFCORE_EXPORT QDebug operator<<(QDebug, const Provider::SearchRequest &);
0385 }
0386 
0387 #endif