Commit 04c4d02a authored by Yunhe Guo's avatar Yunhe Guo Committed by Yunhe Guo
Browse files

[dataengines/potd] Fix flickr provider

Now flickr provider always fetch the keys from KDE Invent. If the key
expires, we just update it in KDE Invent, and users don't need to do
anything.

Fix #3

BUG: 427566
parent 850a0e88
......@@ -31,7 +31,7 @@ set_target_properties(plasmapotdprovidercore PROPERTIES
SOVERSION ${POTDPROVIDER_VERSION_MAJOR}
EXPORT_NAME PotdProvider
)
target_link_libraries( plasmapotdprovidercore Qt::Gui KF5::CoreAddons )
target_link_libraries( plasmapotdprovidercore Qt::Gui KF5::CoreAddons KF5::ConfigCore KF5::KIOCore)
target_include_directories(plasmapotdprovidercore
PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
INTERFACE "$<INSTALL_INTERFACE:${KDE_INSTALL_INCLUDEDIR}>"
......
[API]
API_KEY=65a0b7386726804b1af4f30dcf69adaf
API_SECRET=0e2fbf39103c41c5
\ No newline at end of file
/*
* SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org>
* SPDX-FileCopyrightText: 2008 Anne-Marie Mahfouf <annma@kde.org>
* SPDX-FileCopyrightText: 2008 Georges Toth <gtoth@trypill.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
// SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org>
// SPDX-FileCopyrightText: 2008 Anne-Marie Mahfouf <annma@kde.org>
// SPDX-FileCopyrightText: 2008 Georges Toth <gtoth@trypill.org>
// SPDX-FileCopyrightText: 2021 Guo Yunhe <i@guoyunhe.me>
//
// SPDX-License-Identifier: GPL-2.0-or-later
#include "flickrprovider.h"
#include <KIO/Job>
#include <KPluginFactory>
#include <QDebug>
#include <QRandomGenerator>
#include <QRegularExpression>
#include <QUrlQuery>
#define FLICKR_API_KEY QStringLiteral("65a0b7386726804b1af4f30dcf69adaf")
#include <KIO/Job>
#include <KPluginFactory>
static QUrl buildUrl(const QDate &date)
static QUrl buildUrl(const QDate &date, const QString apiKey)
{
QUrl url(QLatin1String("https://api.flickr.com/services/rest/"));
QUrlQuery urlQuery(url);
urlQuery.addQueryItem(QStringLiteral("api_key"), FLICKR_API_KEY);
urlQuery.addQueryItem(QStringLiteral("api_key"), apiKey);
urlQuery.addQueryItem(QStringLiteral("method"), QStringLiteral("flickr.interestingness.getList"));
urlQuery.addQueryItem(QStringLiteral("date"), date.toString(Qt::ISODate));
// url_o might be either too small or too large.
......@@ -33,12 +32,9 @@ static QUrl buildUrl(const QDate &date)
FlickrProvider::FlickrProvider(QObject *parent, const QVariantList &args)
: PotdProvider(parent, args)
{
mActualDate = date();
connect(this, &PotdProvider::configLoaded, this, &FlickrProvider::sendXmlRequest);
const QUrl url = buildUrl(mActualDate);
KIO::StoredTransferJob *job = KIO::storedGet(url, KIO::NoReload, KIO::HideProgressInfo);
connect(job, &KIO::StoredTransferJob::finished, this, &FlickrProvider::pageRequestFinished);
loadConfig();
}
FlickrProvider::~FlickrProvider() = default;
......@@ -48,12 +44,30 @@ QImage FlickrProvider::image() const
return mImage;
}
void FlickrProvider::pageRequestFinished(KJob *_job)
void FlickrProvider::sendXmlRequest(QString apiKey, QString apiSecret)
{
Q_UNUSED(apiSecret);
if (apiKey.isNull()) {
refreshConfig();
return;
}
mApiKey = apiKey;
mActualDate = date().addDays(-2);
const QUrl xmlUrl = buildUrl(mActualDate, apiKey);
KIO::StoredTransferJob *xmlJob = KIO::storedGet(xmlUrl, KIO::NoReload, KIO::HideProgressInfo);
connect(xmlJob, &KIO::StoredTransferJob::finished, this, &FlickrProvider::xmlRequestFinished);
}
void FlickrProvider::xmlRequestFinished(KJob *_job)
{
KIO::StoredTransferJob *job = static_cast<KIO::StoredTransferJob *>(_job);
if (job->error()) {
Q_EMIT error(this);
qDebug() << "pageRequestFinished error";
qDebug() << "xmlRequestFinished error";
refreshConfig();
return;
}
......@@ -71,22 +85,11 @@ void FlickrProvider::pageRequestFinished(KJob *_job)
if (xml.isStartElement()) {
auto attributes = xml.attributes();
if (xml.name() == QLatin1String("rsp")) {
const int maxFailure = 5;
/* no pictures available for the specified parameters */
if (attributes.value(QLatin1String("stat")).toString() != QLatin1String("ok")) {
if (mFailureNumber < maxFailure) {
/* To be sure, decrement the date to two days earlier... @TODO */
mActualDate = mActualDate.addDays(-2);
QUrl url = buildUrl(mActualDate);
KIO::StoredTransferJob *pageJob = KIO::storedGet(url, KIO::NoReload, KIO::HideProgressInfo);
connect(pageJob, &KIO::StoredTransferJob::finished, this, &FlickrProvider::pageRequestFinished);
mFailureNumber++;
return;
} else {
Q_EMIT error(this);
qDebug() << "pageRequestFinished error";
return;
}
Q_EMIT error(this);
qDebug() << "xmlRequestFinished error: no photos for the query";
return;
}
} else if (xml.name() == QLatin1String("photo")) {
if (attributes.value(QLatin1String("ispublic")).toString() != QLatin1String("1")) {
......
/*
* SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org>
* SPDX-FileCopyrightText: 2008 Anne-Marie Mahfouf <annma@kde.org>
* SPDX-FileCopyrightText: 2008 Georges Toth <gtoth@trypill.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
// SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org>
// SPDX-FileCopyrightText: 2008 Anne-Marie Mahfouf <annma@kde.org>
// SPDX-FileCopyrightText: 2008 Georges Toth <gtoth@trypill.org>
// SPDX-FileCopyrightText: 2021 Guo Yunhe <i@guoyunhe.me>
//
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef FLICKRPROVIDER_H
#define FLICKRPROVIDER_H
#include "potdprovider.h"
// Qt
#include <QDate>
#include <QImage>
#include <QXmlStreamReader>
class KJob;
#include <KIO/Job>
/**
* This class grabs a random image from the flickr
......@@ -50,11 +49,13 @@ public:
QImage image() const override;
private:
void pageRequestFinished(KJob *job);
void sendXmlRequest(QString apiKey, QString apiSecret);
void xmlRequestFinished(KJob *job);
void imageRequestFinished(KJob *job);
private:
QDate mActualDate;
QString mApiKey;
QImage mImage;
QXmlStreamReader xml;
......
/*
* SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
// SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org>
// SPDX-FileCopyrightText: 2021 Guo Yunhe <i@guoyunhe.me>
// SPDX-License-Identifier: GPL-2.0-or-later
#include "potdprovider.h"
// Qt
#include <QDate>
#include <QDebug>
#include <QFileInfo>
#include <KConfig>
#include <KConfigGroup>
#define CONFIG_ROOT_URL "https://autoconfig.kde.org/potd/"
class PotdProviderPrivate
{
......@@ -39,6 +43,11 @@ PotdProvider::PotdProvider(QObject *parent, const QVariantList &args)
d->name = QStringLiteral("Unknown");
d->identifier = d->name;
}
QString configFileName = d->identifier + QStringLiteral("provider.conf");
configRemoteUrl = QUrl(QStringLiteral(CONFIG_ROOT_URL) + configFileName);
configLocalPath = QStandardPaths::writableLocation(QStandardPaths::GenericCacheLocation) + QLatin1String("/plasma_engine_potd/") + configFileName;
configLocalUrl = QUrl::fromLocalFile(configLocalPath);
}
PotdProvider::~PotdProvider()
......@@ -64,3 +73,57 @@ QString PotdProvider::identifier() const
{
return d->identifier;
}
void PotdProvider::refreshConfig()
{
// You can only refresh it once in a provider's life cycle
if (refreshed) {
return;
}
// You can only refresh it once in a day
QFileInfo configFileInfo = QFileInfo(configLocalPath);
if (configFileInfo.exists() && configFileInfo.lastModified().addDays(1) > QDateTime::currentDateTime()) {
return;
}
KIO::StoredTransferJob *job = KIO::storedGet(configRemoteUrl, KIO::NoReload, KIO::HideProgressInfo);
connect(job, &KIO::StoredTransferJob::finished, this, &PotdProvider::configRequestFinished);
refreshed = true;
}
void PotdProvider::configRequestFinished(KJob *_job)
{
KIO::StoredTransferJob *job = static_cast<KIO::StoredTransferJob *>(_job);
if (job->error()) {
Q_EMIT error(this);
qDebug() << "configRequestFinished error: failed to fetch data";
return;
}
KIO::StoredTransferJob *putJob = KIO::storedPut(job->data(), configLocalUrl, -1);
connect(putJob, &KIO::StoredTransferJob::finished, this, &PotdProvider::configWriteFinished);
}
void PotdProvider::configWriteFinished(KJob *_job)
{
KIO::StoredTransferJob *job = static_cast<KIO::StoredTransferJob *>(_job);
if (job->error()) {
Q_EMIT error(this);
qDebug() << "configWriteFinished error: failed to write data";
return;
}
loadConfig();
}
void PotdProvider::loadConfig()
{
KConfig config(configLocalPath);
KConfigGroup apiGroup = config.group("API");
QString apiKey = apiGroup.readEntry("API_KEY");
QString apiSecret = apiGroup.readEntry("API_SECRET");
Q_EMIT configLoaded(apiKey, apiSecret);
}
/*
* SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org>
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
// SPDX-FileCopyrightText: 2007 Tobias Koenig <tokoe@kde.org>
// SPDX-FileCopyrightText: 2021 Guo Yunhe <i@guoyunhe.me>
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef POTDPROVIDER_H
#define POTDPROVIDER_H
#include <QObject>
#include <QUrl>
#include <QVariantList>
#include <KIO/Job>
#include "plasma_potd_export.h"
class QImage;
......@@ -64,6 +65,9 @@ public:
*/
bool isFixedDate() const;
void refreshConfig();
void loadConfig();
Q_SIGNALS:
/**
* This signal is emitted whenever a request has been finished
......@@ -80,8 +84,18 @@ Q_SIGNALS:
*/
void error(PotdProvider *provider);
void configLoaded(QString apiKey, QString apiSecret);
private:
void configRequestFinished(KJob *job);
void configWriteFinished(KJob *job);
const QScopedPointer<class PotdProviderPrivate> d;
QUrl configRemoteUrl;
QUrl configLocalUrl;
QString configLocalPath;
bool refreshed = false;
};
#endif
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment