File indexing completed on 2024-05-12 16:59:42

0001 /*
0002     SPDX-FileCopyrightText: 2022 Fushan Wen <qydwhotmail@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #pragma once
0008 
0009 #include "config-NetworkManagerQt.h"
0010 
0011 #include <unordered_map>
0012 
0013 #include <QDate>
0014 #include <QObject>
0015 #include <QTimer>
0016 #if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
0017 #include <QNetworkInformation>
0018 #elif HAVE_NetworkManagerQt
0019 #include <NetworkManagerQt/Manager>
0020 #endif
0021 #include <KPluginMetaData>
0022 
0023 #include "potdprovider.h"
0024 
0025 /**
0026  * This class provides data for the specific identifier and arguments
0027  */
0028 class PotdClient : public QObject
0029 {
0030     Q_OBJECT
0031 
0032 public:
0033     PotdClient(const KPluginMetaData &metadata, const QVariantList &args, QObject *parent = nullptr);
0034 
0035     void updateSource(bool refresh = false);
0036 #if SUPPORT_METERED_DETECTION
0037     void setUpdateOverMeteredConnection(int value);
0038 #endif
0039 
0040     KPluginMetaData m_metadata;
0041     PotdProviderData m_data;
0042     bool m_loading = false;
0043 
0044 Q_SIGNALS:
0045     /**
0046      * Emitted only when the image content has been updated
0047      */
0048     void imageChanged();
0049     void loadingChanged();
0050     void localUrlChanged();
0051     void infoUrlChanged();
0052     void remoteUrlChanged();
0053     void titleChanged();
0054     void authorChanged();
0055     void done(PotdClient *client, bool success);
0056 
0057 private Q_SLOTS:
0058     void slotFinished(PotdProvider *provider);
0059     void slotError(PotdProvider *provider);
0060     void slotCachingFinished(const QString &source, const PotdProviderData &data);
0061 
0062 private:
0063     void setLoading(bool status);
0064     void setLocalUrl(const QString &urlString);
0065     void setInfoUrl(const QUrl &url);
0066     void setRemoteUrl(const QUrl &url);
0067     void setTitle(const QString &title);
0068     void setAuthor(const QString &author);
0069 
0070     QString m_identifier;
0071     QVariantList m_args;
0072     bool m_imageChanged = false;
0073 #if SUPPORT_METERED_DETECTION
0074     int m_doesUpdateOverMeteredConnection = 0;
0075 #endif
0076 
0077     friend class PotdEngine;
0078 };
0079 
0080 /**
0081  * This class manages the clients for the Pictures of The Day plugin
0082  */
0083 class PotdEngine : public QObject
0084 {
0085     Q_OBJECT
0086 
0087 public:
0088     explicit PotdEngine(QObject *parent = nullptr);
0089 
0090     /**
0091      * Registers the @p identifier in the engine
0092      *
0093      * A client will be created, and will be automatically destroyed when no backend has
0094      * the identifier.
0095      *
0096      * @return the client that relays signals for the specific identifier
0097      */
0098     PotdClient *registerClient(const QString &identifier, const QVariantList &args);
0099     void unregisterClient(const QString &identifier, const QVariantList &args);
0100 
0101     void updateSource(bool refresh);
0102 
0103 private Q_SLOTS:
0104     void forceUpdateSource();
0105     void slotDone(PotdClient *client, bool success);
0106     void slotPrepareForSleep(bool sleep);
0107 #if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
0108     void slotReachabilityChanged(QNetworkInformation::Reachability newReachability);
0109     void slotIsMeteredChanged(bool isMetered);
0110 #elif HAVE_NetworkManagerQt
0111     void slotConnectivityChanged(NetworkManager::Connectivity connectivity);
0112 #endif
0113 
0114 private:
0115     void loadPluginMetaData();
0116 
0117     struct ClientPair {
0118         PotdClient *const client = nullptr;
0119         int instanceCount = 0;
0120     };
0121     std::unordered_multimap<QString /* identifier */, ClientPair> m_clientMap;
0122     std::unordered_map<QString, KPluginMetaData> m_providersMap;
0123 
0124     QTimer m_checkDatesTimer;
0125     int m_updateCount = 0;
0126 
0127     bool m_lastUpdateSuccess = false;
0128 };