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

0001 // SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org>
0002 // SPDX-FileCopyrightText: 2021 Guo Yunhe <i@guoyunhe.me>
0003 // SPDX-License-Identifier: GPL-2.0-or-later
0004 
0005 #include "potdprovider.h"
0006 
0007 #include <QDate>
0008 #include <QDebug>
0009 #include <QFileInfo>
0010 
0011 #include <KConfig>
0012 #include <KConfigGroup>
0013 
0014 #define CONFIG_ROOT_URL "https://autoconfig.kde.org/potd/"
0015 
0016 class PotdProviderPrivate
0017 {
0018 public:
0019     explicit PotdProviderPrivate();
0020     ~PotdProviderPrivate();
0021 
0022     QString name;
0023     QDate date;
0024     QString identifier;
0025 
0026     std::unique_ptr<PotdProviderData> m_data;
0027 };
0028 
0029 PotdProviderPrivate::PotdProviderPrivate()
0030     : m_data(std::make_unique<PotdProviderData>())
0031 {
0032 }
0033 
0034 PotdProviderPrivate::~PotdProviderPrivate()
0035 {
0036 }
0037 
0038 PotdProvider::PotdProvider(QObject *parent, const KPluginMetaData &data, const QVariantList &args)
0039     : QObject(parent)
0040     , d(new PotdProviderPrivate)
0041 {
0042     if (const QString name = data.name(); !name.isEmpty()) {
0043         d->name = name;
0044     } else {
0045         d->name = QStringLiteral("Unknown");
0046     }
0047 
0048     if (const QString identifier = data.value(QStringLiteral("X-KDE-PlasmaPoTDProvider-Identifier")); !identifier.isEmpty()) {
0049         d->identifier = identifier;
0050     } else {
0051         d->identifier = d->name;
0052     }
0053 
0054     if (!args.empty()) {
0055         for (const auto &arg : args) {
0056             const QDate date = QDate::fromString(arg.toString(), Qt::ISODate);
0057             if (date.isValid()) {
0058                 d->date = date;
0059                 break;
0060             }
0061         }
0062     }
0063 
0064     QString configFileName = d->identifier + QStringLiteral("provider.conf");
0065     configRemoteUrl = QUrl(QStringLiteral(CONFIG_ROOT_URL) + configFileName);
0066     configLocalPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QStringLiteral("/plasma_engine_potd/") + configFileName;
0067     configLocalUrl = QUrl::fromLocalFile(configLocalPath);
0068 }
0069 
0070 PotdProvider::PotdProvider(QObject *parent, const QVariantList &args)
0071     : QObject(parent)
0072     , d(new PotdProviderPrivate)
0073 {
0074     Q_UNUSED(args)
0075     d->name = QStringLiteral("Unknown");
0076     d->identifier = d->name;
0077     qWarning() << "You are using an old PoTD provider plugin. It will not work in Plasma 6. Please consider updating the plugin.";
0078 }
0079 
0080 PotdProvider::~PotdProvider()
0081 {
0082 }
0083 
0084 QString PotdProvider::name() const
0085 {
0086     return d->name;
0087 }
0088 
0089 QDate PotdProvider::date() const
0090 {
0091     return d->date.isNull() ? QDate::currentDate() : d->date;
0092 }
0093 
0094 bool PotdProvider::isFixedDate() const
0095 {
0096     return !d->date.isNull();
0097 }
0098 
0099 QString PotdProvider::identifier() const
0100 {
0101     return d->identifier;
0102 }
0103 
0104 QImage PotdProvider::image() const
0105 {
0106     return potdProviderData()->wallpaperImage;
0107 }
0108 
0109 QUrl PotdProvider::remoteUrl() const
0110 {
0111     return potdProviderData()->wallpaperRemoteUrl;
0112 }
0113 
0114 QUrl PotdProvider::infoUrl() const
0115 {
0116     return potdProviderData()->wallpaperInfoUrl;
0117 }
0118 
0119 QString PotdProvider::title() const
0120 {
0121     return potdProviderData()->wallpaperTitle;
0122 }
0123 
0124 QString PotdProvider::author() const
0125 {
0126     return potdProviderData()->wallpaperAuthor;
0127 }
0128 
0129 void PotdProvider::refreshConfig()
0130 {
0131     // You can only refresh it once in a provider's life cycle
0132     if (refreshed) {
0133         return;
0134     }
0135     // You can only refresh it once in a day
0136     QFileInfo configFileInfo = QFileInfo(configLocalPath);
0137     if (configFileInfo.exists() && configFileInfo.lastModified().addDays(1) > QDateTime::currentDateTime()) {
0138         return;
0139     }
0140 
0141     KIO::StoredTransferJob *job = KIO::storedGet(configRemoteUrl, KIO::NoReload, KIO::HideProgressInfo);
0142     connect(job, &KIO::StoredTransferJob::finished, this, &PotdProvider::configRequestFinished);
0143 
0144     refreshed = true;
0145 }
0146 
0147 void PotdProvider::configRequestFinished(KJob *_job)
0148 {
0149     KIO::StoredTransferJob *job = static_cast<KIO::StoredTransferJob *>(_job);
0150     if (job->error()) {
0151         Q_EMIT error(this);
0152         qDebug() << "configRequestFinished error: failed to fetch data";
0153         return;
0154     }
0155 
0156     KIO::StoredTransferJob *putJob = KIO::storedPut(job->data(), configLocalUrl, -1);
0157     connect(putJob, &KIO::StoredTransferJob::finished, this, &PotdProvider::configWriteFinished);
0158 }
0159 
0160 void PotdProvider::configWriteFinished(KJob *_job)
0161 {
0162     KIO::StoredTransferJob *job = static_cast<KIO::StoredTransferJob *>(_job);
0163     if (job->error()) {
0164         Q_EMIT error(this);
0165         qDebug() << "configWriteFinished error: failed to write data";
0166         return;
0167     }
0168 
0169     loadConfig();
0170 }
0171 
0172 void PotdProvider::loadConfig()
0173 {
0174     KConfig config(configLocalPath);
0175 
0176     KConfigGroup apiGroup = config.group("API");
0177     QString apiKey = apiGroup.readEntry("API_KEY");
0178     QString apiSecret = apiGroup.readEntry("API_SECRET");
0179 
0180     Q_EMIT configLoaded(apiKey, apiSecret);
0181 }
0182 
0183 PotdProviderData *PotdProvider::potdProviderData() const
0184 {
0185     return d->m_data.get();
0186 }