File indexing completed on 2025-01-05 03:53:32

0001 /* ============================================================
0002  *
0003  * This file is a part of digiKam project
0004  * https://www.digikam.org
0005  *
0006  * Date        : 2016-05-27
0007  * Description : Implementation of v3 of the Imgur API
0008  *
0009  * SPDX-FileCopyrightText: 2016      by Fabian Vogt <fabian at ritter dash vogt dot de>
0010  * SPDX-FileCopyrightText: 2016-2020 by Caulier Gilles <caulier dot gilles at gmail dot com>
0011  *
0012  * SPDX-License-Identifier: GPL-2.0-or-later
0013  *
0014  * ============================================================ */
0015 
0016 #ifndef DIGIKAM_IMGUR_TALKER_H
0017 #define DIGIKAM_IMGUR_TALKER_H
0018 
0019 // C++ includes
0020 
0021 #include <atomic>
0022 #include <queue>
0023 
0024 // Qt includes
0025 
0026 #include <QString>
0027 #include <QFile>
0028 #include <QUrl>
0029 
0030 // Local includes
0031 
0032 #include "o2.h"
0033 
0034 namespace DigikamGenericImgUrPlugin
0035 {
0036 
0037 enum class ImgurTalkerActionType
0038 {
0039     ACCT_INFO,       ///< Action: account Result : account
0040     IMG_UPLOAD,      ///< Action: upload Result  : image
0041     ANON_IMG_UPLOAD, ///< Action: upload Result  : image
0042 };
0043 
0044 struct ImgurTalkerAction
0045 {
0046     ImgurTalkerActionType type;
0047 
0048     struct
0049     {
0050         QString imgpath;
0051         QString title;
0052         QString description;
0053     }
0054     upload;
0055 
0056     struct
0057     {
0058         QString username;
0059     }
0060     account;
0061 };
0062 
0063 struct ImgurTalkerResult
0064 {
0065     const ImgurTalkerAction* action;
0066 
0067     struct ImgurImage
0068     {
0069         QString    name;
0070         QString    title;
0071         QString    hash;
0072         QString    deletehash;
0073         QString    url;
0074         QString    description;
0075         qulonglong datetime;
0076         QString    type;
0077         bool       animated;
0078         uint       width;
0079         uint       height;
0080         uint       size;
0081         uint       views;
0082         qulonglong bandwidth;
0083     }
0084     image;
0085 
0086     struct ImgurAccount
0087     {
0088         QString username;
0089     }
0090     account;
0091 };
0092 
0093 // ----------------------------------------------------------------
0094 
0095 /**
0096  * Main class, handles the client side of the Imgur API v3.
0097  */
0098 class ImgurTalker : public QObject
0099 {
0100 Q_OBJECT
0101 
0102 public:
0103 
0104     explicit ImgurTalker(QObject* const parent = nullptr);
0105     ~ImgurTalker() override;
0106 
0107 public:
0108 
0109     /**
0110      * Use this method to read/write the access and refresh tokens.
0111      */
0112     O2& getAuth();
0113 
0114     unsigned int workQueueLength();
0115     void         queueWork(const ImgurTalkerAction& action);
0116     void         cancelAllWork();
0117 
0118     static QUrl  urlForDeletehash(const QString& deletehash);
0119 
0120 Q_SIGNALS:
0121 
0122     /**
0123      * Called if authentication state changes.
0124      */
0125     void signalAuthorized(bool success, const QString& username);
0126     void signalAuthError(const QString& msg);
0127 
0128     /**
0129      * Open url in a browser and let the user copy the pin.
0130      * Call setPin(pin) to authorize.
0131      */
0132     void signalRequestPin(const QUrl& url);
0133 
0134     /**
0135      * Emitted on progress changes.
0136      */
0137     void signalProgress(unsigned int percent, const ImgurTalkerAction& action);
0138     void signalSuccess(const ImgurTalkerResult& result);
0139     void signalError(const QString& msg, const ImgurTalkerAction& action);
0140 
0141     /**
0142      * Emitted when the status changes.
0143      */
0144     void signalBusy(bool b);
0145 
0146 public Q_SLOTS:
0147 
0148     /**
0149      * Connected to O2 linkedChanged().
0150      */
0151     void slotOauthAuthorized();
0152 
0153     /**
0154      * Connected to O2 openBrowser(QUrl).
0155      */
0156     void slotOauthRequestPin(const QUrl& url);
0157 
0158     /**
0159      * Connected to O2 linkingFailed().
0160      */
0161     void slotOauthFailed();
0162 
0163     /**
0164      * Connected to the current QNetworkReply.
0165      */
0166     void slotUploadProgress(qint64 sent, qint64 total);
0167     void slotReplyFinished();
0168 
0169 protected:
0170 
0171     void timerEvent(QTimerEvent* event) override;
0172 
0173 private:
0174 
0175     /**
0176      * Starts timer if queue not empty.
0177      */
0178     void startWorkTimer();
0179 
0180     /**
0181      * Stops timer if running.
0182      */
0183     void stopWorkTimer();
0184 
0185     /**
0186      * Adds the user authorization info to the request.
0187      */
0188     void addAuthToken(QNetworkRequest* request);
0189 
0190     /**
0191      * Adds the client authorization info to the request.
0192      */
0193     void addAnonToken(QNetworkRequest* request);
0194 
0195     /**
0196      * Start working on the first item of m_work_queue
0197      * by sending a request.
0198      */
0199     void doWork();
0200 
0201 private:
0202 
0203     class Private;
0204     Private* const d;
0205 };
0206 
0207 } // namespace DigikamGenericImgUrPlugin
0208 
0209 #endif // DIGIKAM_IMGUR_TALKER_H