File indexing completed on 2024-12-29 05:00:27

0001 /*
0002  *   SPDX-FileCopyrightText: 2017 Weng Xuetian <wengxt@gmail.com>
0003  *
0004  *   SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "bingprovider.h"
0008 
0009 #include <QJsonArray>
0010 #include <QJsonDocument>
0011 #include <QRegularExpression> // Extract from the copyright text
0012 
0013 #include <KIO/StoredTransferJob>
0014 #include <KPluginFactory>
0015 
0016 BingProvider::BingProvider(QObject *parent, const KPluginMetaData &data, const QVariantList &args)
0017     : PotdProvider(parent, data, args)
0018     , m_screenWidth(args.size() >= 2 ? args[0].toInt() : 0)
0019     , m_screenHeight(args.size() >= 2 ? args[1].toInt() : 0)
0020 {
0021     const QUrl url(QStringLiteral("https://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1"));
0022 
0023     KIO::StoredTransferJob *job = KIO::storedGet(url, KIO::NoReload, KIO::HideProgressInfo);
0024     connect(job, &KIO::StoredTransferJob::finished, this, &BingProvider::pageRequestFinished);
0025 }
0026 
0027 void BingProvider::pageRequestFinished(KJob *_job)
0028 {
0029     KIO::StoredTransferJob *job = static_cast<KIO::StoredTransferJob *>(_job);
0030     if (job->error()) {
0031         Q_EMIT error(this);
0032         return;
0033     }
0034 
0035     auto json = QJsonDocument::fromJson(job->data());
0036     do {
0037         if (json.isNull()) {
0038             break;
0039         }
0040         auto imagesArray = json.object().value(QLatin1String("images"));
0041         if (!imagesArray.isArray() || imagesArray.toArray().size() <= 0) {
0042             break;
0043         }
0044         auto imageObj = imagesArray.toArray().at(0);
0045         if (!imageObj.isObject()) {
0046             break;
0047         }
0048         const QJsonObject imageObject = imageObj.toObject();
0049         auto url = imageObject.value(QLatin1String("urlbase"));
0050         QString urlString = url.isString() ? url.toString() : QString();
0051         if (urlString.isEmpty()) {
0052             break;
0053         }
0054 
0055         urlString = QStringLiteral("https://www.bing.com/") + urlString;
0056 
0057         if (m_screenWidth > 1920 || m_screenHeight > 1080) {
0058             // Use 4k wallpaper
0059             urlString += QStringLiteral("_UHD.jpg");
0060         } else {
0061             urlString += QStringLiteral("_1920x1080.jpg");
0062         }
0063         m_remoteUrl = QUrl(urlString);
0064 
0065         // Parse the title and the copyright text from the json data
0066         // Example copyright text: "草丛中的母狮和它的幼崽,南非 (© Andrew Coleman/Getty Images)"
0067         const QString copyright = imageObject.value(QStringLiteral("copyright")).toString();
0068         const QRegularExpression copyrightRegEx(QStringLiteral("(.+?)[\\((](.+?)[\\))]"));
0069         if (const QRegularExpressionMatch match = copyrightRegEx.match(copyright); match.hasMatch()) {
0070             // In some regions "title" is empty, so extract the title from the copyright text.
0071             m_title = match.captured(1).trimmed();
0072             m_author = match.captured(2).remove(QStringLiteral("©")).trimmed();
0073         }
0074 
0075         const QString title = imageObject.value(QStringLiteral("title")).toString();
0076         if (!title.isEmpty()) {
0077             m_title = title;
0078         }
0079 
0080         const QString infoUrl = imageObject.value(QStringLiteral("copyrightlink")).toString();
0081         if (!infoUrl.isEmpty()) {
0082             m_infoUrl = QUrl(infoUrl);
0083         }
0084 
0085         KIO::StoredTransferJob *imageJob = KIO::storedGet(m_remoteUrl, KIO::NoReload, KIO::HideProgressInfo);
0086         connect(imageJob, &KIO::StoredTransferJob::finished, this, &BingProvider::imageRequestFinished);
0087         return;
0088     } while (0);
0089 
0090     Q_EMIT error(this);
0091     return;
0092 }
0093 
0094 void BingProvider::imageRequestFinished(KJob *_job)
0095 {
0096     KIO::StoredTransferJob *job = static_cast<KIO::StoredTransferJob *>(_job);
0097     if (job->error()) {
0098         Q_EMIT error(this);
0099         return;
0100     }
0101     QByteArray data = job->data();
0102     Q_EMIT finished(this, QImage::fromData(data));
0103 }
0104 
0105 K_PLUGIN_CLASS_WITH_JSON(BingProvider, "bingprovider.json")
0106 
0107 #include "bingprovider.moc"