File indexing completed on 2024-04-14 03:54:08

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