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

0001 /*
0002  *   SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org>
0003  *   SPDX-FileCopyrightText: 2008 Anne-Marie Mahfouf <annma@kde.org>
0004  *
0005  *   SPDX-License-Identifier: GPL-2.0-or-later
0006  */
0007 
0008 #include "noaaprovider.h"
0009 
0010 #include <QRegularExpression>
0011 #include <QTextDocumentFragment> // For parsing title from HTML source
0012 
0013 #include <KIO/StoredTransferJob>
0014 #include <KPluginFactory>
0015 
0016 #include "debug.h"
0017 
0018 NOAAProvider::NOAAProvider(QObject *parent, const KPluginMetaData &data, const QVariantList &args)
0019     : PotdProvider(parent, data, args)
0020 {
0021     const QUrl url(QStringLiteral("https://www.nesdis.noaa.gov/real-time-imagery/imagery-collections/image-of-the-day"));
0022 
0023     KIO::StoredTransferJob *job = KIO::storedGet(url, KIO::NoReload, KIO::HideProgressInfo);
0024     connect(job, &KIO::StoredTransferJob::finished, this, &NOAAProvider::listPageRequestFinished);
0025 }
0026 
0027 void NOAAProvider::listPageRequestFinished(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     const QString data = QString::fromUtf8(job->data()).simplified();
0036 
0037     // Using regular expression could be fragile in such case, but the HTML
0038     // NOAA page itself is not a valid XML file and unfortunately it could
0039     // not be parsed successfully till the content we want. And we do not want
0040     // to use heavy weight QtWebkit. So we use QRegularExpression to capture
0041     // the wanted url here.
0042     // Example: <a href="/news/hunga-tonga-hunga-haapai-erupts-again" hreflang="en">Hunga Tonga-Hunga Ha&#039;apai Erupts Again</a>
0043     const QRegularExpression re("<div class=\"item-list\">.*?<li>.*?<a href=\"(.+?)\".*?>");
0044     auto result = re.match(data);
0045     if (result.hasMatch()) {
0046         m_infoUrl = QUrl(QStringLiteral("https://www.nesdis.noaa.gov") + result.captured(1));
0047     }
0048     if (!m_infoUrl.isValid()) {
0049         qCWarning(WALLPAPERPOTD) << "Failed to get the latest article from NOAAProvider!";
0050         Q_EMIT error(this);
0051         return;
0052     }
0053 
0054     KIO::StoredTransferJob *pageJob = KIO::storedGet(m_infoUrl, KIO::NoReload, KIO::HideProgressInfo);
0055     connect(pageJob, &KIO::StoredTransferJob::finished, this, &NOAAProvider::pageRequestFinished);
0056 }
0057 
0058 void NOAAProvider::pageRequestFinished(KJob *_job)
0059 {
0060     KIO::StoredTransferJob *job = static_cast<KIO::StoredTransferJob *>(_job);
0061     if (job->error()) {
0062         Q_EMIT error(this);
0063         return;
0064     }
0065 
0066     const QString data = QString::fromUtf8(job->data()).simplified();
0067 
0068     /**
0069      * Example:
0070      * <a class="call-to-action blue" href="/s3dl?path=/s3/2022-01/20220113-HungaVolcanoA.gif">
0071      *      <span class="fas fa-download"></span> Download Animation
0072      * </a>
0073      */
0074     const QRegularExpression re("<a class=\"call-to-action.*?\" href=\"(.+?)\">.*?Download.*?</a>");
0075     const QRegularExpressionMatch result = re.match(data);
0076     if (result.hasMatch()) {
0077         m_remoteUrl = QUrl(QStringLiteral("https://www.nesdis.noaa.gov") + result.captured(1));
0078     }
0079     if (!m_remoteUrl.isValid()) {
0080         qWarning() << "Failed to match the latest image URL from NOAAProvider!";
0081         Q_EMIT error(this);
0082         return;
0083     }
0084 
0085     /**
0086      * Match title
0087      * Example:
0088      * <meta property="og:title" content="Hunga Tonga-Hunga Ha&#039;apai Erupts Again" />
0089      */
0090     const QRegularExpression titleRegEx(QStringLiteral("<meta property=\"og:title\" content=\"(.+?)\""));
0091     const QRegularExpressionMatch titleMatch = titleRegEx.match(data);
0092     if (titleMatch.hasMatch()) {
0093         m_title = QTextDocumentFragment::fromHtml(titleMatch.captured(1).trimmed()).toPlainText();
0094     }
0095 
0096     KIO::StoredTransferJob *imageJob = KIO::storedGet(m_remoteUrl, KIO::NoReload, KIO::HideProgressInfo);
0097     connect(imageJob, &KIO::StoredTransferJob::finished, this, &NOAAProvider::imageRequestFinished);
0098 }
0099 
0100 void NOAAProvider::imageRequestFinished(KJob *_job)
0101 {
0102     KIO::StoredTransferJob *job = static_cast<KIO::StoredTransferJob *>(_job);
0103     if (job->error()) {
0104         qCWarning(WALLPAPERPOTD) << "Failed to get the latest image from NOAAProvider. Please report the issue on bugs.kde.org";
0105         Q_EMIT error(this);
0106         return;
0107     }
0108 
0109     Q_EMIT finished(this, QImage::fromData(job->data()));
0110 }
0111 
0112 K_PLUGIN_CLASS_WITH_JSON(NOAAProvider, "noaaprovider.json")
0113 
0114 #include "noaaprovider.moc"