File indexing completed on 2024-05-12 16:59:41
0001 /* 0002 * SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org> 0003 * 0004 * SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "cachedprovider.h" 0008 0009 #include <QDateTime> 0010 #include <QDir> 0011 #include <QFile> 0012 #include <QFileInfo> 0013 #include <QJsonDocument> 0014 #include <QJsonObject> 0015 #include <QRegularExpression> 0016 #include <QStandardPaths> 0017 #include <QThreadPool> 0018 #include <QTimer> 0019 0020 #include <QDebug> 0021 #include "debug.h" 0022 0023 LoadImageThread::LoadImageThread(const QString &filePath) 0024 : m_filePath(filePath) 0025 { 0026 } 0027 0028 void LoadImageThread::run() 0029 { 0030 PotdProviderData data; 0031 data.wallpaperImage = QImage(m_filePath); 0032 0033 const QString infoPath = m_filePath + QStringLiteral(".json"); 0034 QFile infoFile(infoPath); 0035 0036 if (infoFile.exists()) { 0037 if (infoFile.open(QIODevice::ReadOnly)) { 0038 QJsonParseError jsonParseError; 0039 const QJsonDocument jsonDoc = QJsonDocument::fromJson(infoFile.readAll(), &jsonParseError); 0040 infoFile.close(); 0041 0042 if (jsonParseError.error == QJsonParseError::NoError && jsonDoc.isObject()) { 0043 const QJsonObject jsonObject = jsonDoc.object(); 0044 data.wallpaperInfoUrl = QUrl(jsonObject.value(QStringLiteral("InfoUrl")).toString()); 0045 data.wallpaperRemoteUrl = QUrl(jsonObject.value(QStringLiteral("RemoteUrl")).toString()); 0046 data.wallpaperTitle = jsonObject.value(QStringLiteral("Title")).toString(); 0047 data.wallpaperAuthor = jsonObject.value(QStringLiteral("Author")).toString(); 0048 } else { 0049 qCWarning(WALLPAPERPOTD) << "Failed to read the wallpaper information!"; 0050 } 0051 } else { 0052 qCWarning(WALLPAPERPOTD) << "Failed to open the wallpaper information file!"; 0053 } 0054 } 0055 0056 Q_EMIT done(data); 0057 } 0058 0059 SaveImageThread::SaveImageThread(const QString &identifier, const QVariantList &args, const PotdProviderData &data) 0060 : m_identifier(identifier) 0061 , m_args(args) 0062 , m_data(data) 0063 { 0064 } 0065 0066 void SaveImageThread::run() 0067 { 0068 m_data.wallpaperLocalUrl = CachedProvider::identifierToPath(m_identifier, m_args); 0069 m_data.wallpaperImage.save(m_data.wallpaperLocalUrl, "JPEG"); 0070 0071 const QString infoPath = m_data.wallpaperLocalUrl + ".json"; 0072 QFile infoFile(infoPath); 0073 if (infoFile.open(QIODevice::WriteOnly)) { 0074 QJsonObject jsonObject; 0075 0076 jsonObject.insert(QStringLiteral("InfoUrl"), m_data.wallpaperInfoUrl.url()); 0077 jsonObject.insert(QStringLiteral("RemoteUrl"), m_data.wallpaperRemoteUrl.url()); 0078 jsonObject.insert(QStringLiteral("Title"), m_data.wallpaperTitle); 0079 jsonObject.insert(QStringLiteral("Author"), m_data.wallpaperAuthor); 0080 0081 infoFile.write(QJsonDocument(jsonObject).toJson(QJsonDocument::Compact)); 0082 infoFile.close(); 0083 } else { 0084 qWarning(WALLPAPERPOTD) << "Failed to save the wallpaper information!"; 0085 } 0086 0087 Q_EMIT done(m_identifier, m_data); 0088 } 0089 0090 QString CachedProvider::identifierToPath(const QString &identifier, const QVariantList &args) 0091 { 0092 const QString argString = std::accumulate(args.cbegin(), args.cend(), QString(), [](const QString &s, const QVariant &arg) { 0093 if (arg.canConvert(QMetaType::QString)) { 0094 return s + QStringLiteral(":%1").arg(arg.toString()); 0095 } 0096 0097 return s; 0098 }); 0099 0100 const QString dataDir = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QLatin1String("/plasma_engine_potd/"); 0101 QDir d; 0102 d.mkpath(dataDir); 0103 return QStringLiteral("%1%2%3").arg(dataDir, identifier, argString); 0104 } 0105 0106 CachedProvider::CachedProvider(const QString &identifier, const QVariantList &args, QObject *parent) 0107 : PotdProvider(parent, KPluginMetaData(), QVariantList()) 0108 , mIdentifier(identifier) 0109 , m_args(args) 0110 { 0111 LoadImageThread *thread = new LoadImageThread(identifierToPath(mIdentifier, m_args)); 0112 connect(thread, &LoadImageThread::done, this, &CachedProvider::triggerFinished); 0113 QThreadPool::globalInstance()->start(thread); 0114 } 0115 0116 QString CachedProvider::identifier() const 0117 { 0118 return mIdentifier; 0119 } 0120 0121 void CachedProvider::triggerFinished(const PotdProviderData &data) 0122 { 0123 potdProviderData()->wallpaperImage = data.wallpaperImage; 0124 potdProviderData()->wallpaperLocalUrl = data.wallpaperLocalUrl; 0125 potdProviderData()->wallpaperInfoUrl = data.wallpaperInfoUrl; 0126 potdProviderData()->wallpaperRemoteUrl = data.wallpaperRemoteUrl; 0127 potdProviderData()->wallpaperTitle = data.wallpaperTitle; 0128 potdProviderData()->wallpaperAuthor = data.wallpaperAuthor; 0129 0130 Q_EMIT finished(this); 0131 } 0132 0133 bool CachedProvider::isCached(const QString &identifier, const QVariantList &args, bool ignoreAge) 0134 { 0135 const QString path = identifierToPath(identifier, args); 0136 if (!QFile::exists(path)) { 0137 return false; 0138 } 0139 0140 QRegularExpression re(QLatin1String(":\\d{4}-\\d{2}-\\d{2}")); 0141 0142 if (!ignoreAge && !re.match(identifier).hasMatch()) { 0143 // no date in the identifier, so it's a daily; check to see ifthe modification time is today 0144 QFileInfo info(path); 0145 if (info.lastModified().daysTo(QDateTime::currentDateTime()) >= 1) { 0146 return false; 0147 } 0148 } 0149 0150 return true; 0151 }