diff --git a/dataengines/potd/CMakeLists.txt b/dataengines/potd/CMakeLists.txt --- a/dataengines/potd/CMakeLists.txt +++ b/dataengines/potd/CMakeLists.txt @@ -136,6 +136,8 @@ install( TARGETS plasma_potd_bingprovider DESTINATION ${KDE_INSTALL_PLUGINDIR}/potd ) +# Unsplash + set( potd_unsplash_provider_SRCS unsplashprovider.cpp ) diff --git a/dataengines/potd/potd.h b/dataengines/potd/potd.h --- a/dataengines/potd/potd.h +++ b/dataengines/potd/potd.h @@ -31,9 +31,10 @@ * This class provides the Pictures of The Day from various online websites. * * The query keys have the following structure: - * \:\ + * \:\[:other_args] * e.g. * apod:2007-07-19 + * unsplash:2019-07-25:12435322 * */ class PotdEngine : public Plasma::DataEngine diff --git a/dataengines/potd/potd.cpp b/dataengines/potd/potd.cpp --- a/dataengines/potd/potd.cpp +++ b/dataengines/potd/potd.cpp @@ -92,29 +92,17 @@ } } - const QStringList parts = identifier.split( QLatin1Char( ':' ), QString::SkipEmptyParts ); - if (parts.empty()) { + const QStringList args = identifier.split( QLatin1Char( ':' ), QString::SkipEmptyParts ); + if (args.empty()) { qDebug() << "invalid identifier"; return false; } - const QString providerName = parts[ 0 ]; + const QString providerName = args[ 0 ]; if ( !mFactories.contains( providerName ) ) { - qDebug() << "invalid provider: " << parts[ 0 ]; + qDebug() << "invalid provider: " << args[ 0 ]; return false; } - QVariantList args; - args << providerName; - if ( parts.count() > 1 ) { - const QDate date = QDate::fromString( parts[ 1 ], Qt::ISODate ); - if ( !date.isValid() ) { - qDebug() << "invalid date:" << parts[1]; - return false; - } - - args << date; - } - auto factory = KPluginLoader(mFactories[ providerName ].fileName()).factory(); PotdProvider *provider = nullptr; if (factory) { diff --git a/dataengines/potd/potdprovider.cpp b/dataengines/potd/potdprovider.cpp --- a/dataengines/potd/potdprovider.cpp +++ b/dataengines/potd/potdprovider.cpp @@ -21,6 +21,7 @@ // Qt #include +#include class PotdProviderPrivate @@ -37,8 +38,16 @@ if ( args.count() > 0 ) { d->name = args[ 0 ].toString(); - if ( args.count() > 1 && args[ 1 ].canConvert( QVariant::Date ) ) { - d->date = args[ 1 ].toDate(); + QRegularExpression re(QStringLiteral("\\d{4}-\\d{2}-\\d{2}")); + if ( args.count() > 1 ) { + for (int i = 1; i < args.count(); i++) { + if (re.match(args[ i ].toString()).hasMatch()) { + QDate date = QDate::fromString(args[ i ].toString()); + if (date.isValid()) { + d->date = date; + } + } + } } } else { d->name = QStringLiteral("Unknown"); diff --git a/dataengines/potd/unsplashprovider.h b/dataengines/potd/unsplashprovider.h --- a/dataengines/potd/unsplashprovider.h +++ b/dataengines/potd/unsplashprovider.h @@ -27,8 +27,11 @@ class KJob; /** - * This class provides random wallpapers from Unsplash Wallpapers - * Image urls are parsed from https://unsplash.com/wallpaper/1065396/desktop-wallpapers + * This class provides random wallpapers from Unsplash Wallpapers Desktop Collection + * https://unsplash.com/wallpaper/1065396/desktop-wallpapers + * + * By extending this class and modify mCollection (the number in url), + * we can get photo wallpaper from any collections */ class UnsplashProvider : public PotdProvider { @@ -41,7 +44,7 @@ * @param parent The parent object. * @param args The arguments. */ - UnsplashProvider( QObject *parent, const QVariantList &args ); + UnsplashProvider(QObject *parent, const QVariantList &args ); /** * Destroys the Unsplash provider. @@ -57,7 +60,6 @@ QImage image() const override; private: - void pageRequestFinished(KJob *job); void imageRequestFinished(KJob *job); private: diff --git a/dataengines/potd/unsplashprovider.cpp b/dataengines/potd/unsplashprovider.cpp --- a/dataengines/potd/unsplashprovider.cpp +++ b/dataengines/potd/unsplashprovider.cpp @@ -28,10 +28,11 @@ UnsplashProvider::UnsplashProvider(QObject* parent, const QVariantList& args) : PotdProvider(parent, args) { - const QUrl url(QStringLiteral("https://unsplash.com/wallpaper/1065396/desktop-wallpapers")); + qDebug() << args; + const QUrl url(QStringLiteral("https://source.unsplash.com/collection/%1/3840x2160/daily").arg(args[1].toString())); KIO::StoredTransferJob* job = KIO::storedGet(url, KIO::NoReload, KIO::HideProgressInfo); - connect(job, &KIO::StoredTransferJob::finished, this, &UnsplashProvider::pageRequestFinished); + connect(job, &KIO::StoredTransferJob::finished, this, &UnsplashProvider::imageRequestFinished); } UnsplashProvider::~UnsplashProvider() = default; @@ -41,41 +42,6 @@ return mImage; } -void UnsplashProvider::pageRequestFinished(KJob* _job) -{ - KIO::StoredTransferJob* job = static_cast(_job); - if (job->error()) { - emit error(this); - return; - } - - const QString html = QString::fromUtf8(job->data()); - - // "?ixlib" will filter out the banner image which rarely change... - QRegularExpression re(QStringLiteral("src=\"(https://images\\.unsplash\\.com/photo-\\w+-\\w+)\\?ixlib")); - - QRegularExpressionMatchIterator i = re.globalMatch(html); - - QStringList urls; - - while (i.hasNext()) { - QRegularExpressionMatch match = i.next(); - QString url = match.captured(1); - urls << url; - } - - if (urls.size() > 0) { - // Pick a ramdom photo because the wallpaper page doesn't update every day - QUrl picUrl(urls.at(rand() % urls.size())); // url to full size photo (compressed) - KIO::StoredTransferJob* imageJob = KIO::storedGet(picUrl, KIO::NoReload, KIO::HideProgressInfo); - connect(imageJob, &KIO::StoredTransferJob::finished, this, &UnsplashProvider::imageRequestFinished); - return; - } else { - emit error(this); - return; - } -} - void UnsplashProvider::imageRequestFinished(KJob* _job) { KIO::StoredTransferJob* job = static_cast(_job); diff --git a/wallpapers/potd/contents/config/main.xml b/wallpapers/potd/contents/config/main.xml --- a/wallpapers/potd/contents/config/main.xml +++ b/wallpapers/potd/contents/config/main.xml @@ -10,6 +10,10 @@ apod + + + 1065976 + 0 diff --git a/wallpapers/potd/contents/ui/config.qml b/wallpapers/potd/contents/ui/config.qml --- a/wallpapers/potd/contents/ui/config.qml +++ b/wallpapers/potd/contents/ui/config.qml @@ -30,6 +30,7 @@ anchors.right: parent.right property string cfg_Provider + property string cfg_Category property int cfg_FillMode property alias cfg_Color: colorButton.color property alias formLayout: root @@ -80,6 +81,38 @@ cfg_Provider = providerModel.get(currentIndex)["id"] } } + + // TODO: port to QQC2 version once we've fixed https://bugs.kde.org/show_bug.cgi?id=403153 + QQC1.ComboBox { + id: categoryComboBox + visible: cfg_Provider === 'unsplash' + TextMetrics { + id: categoryTextMetrics + text: categoryComboBox.currentText + } + implicitWidth: Math.max(providerTextMetrics.width + Kirigami.Units.gridUnit * 2 + Kirigami.Units.smallSpacing * 2, pluginComboBox.width) //QQC1 Combobox default sizing is broken + Kirigami.FormData.label: i18ndc("plasma_wallpaper_org.kde.potd", "@label:listbox", "Category:") + model: [ + { + 'label': i18ndc("plasma_wallpaper_org.kde.potd", "@item:inlistbox", "All"), + 'value': '1065976' + }, + ] + + textRole: "label" + onCurrentIndexChanged: { + cfg_Category = model[currentIndex]["value"] + } + Component.onCompleted: setMethod(); + + function setMethod() { + for (var i = 0; i < model.length; i++) { + if (model[i]["value"] == wallpaper.configuration.Category) { + categoryComboBox.currentIndex = i; + } + } + } + } // TODO: port to QQC2 version once we've fixed https://bugs.kde.org/show_bug.cgi?id=403153 QQC1.ComboBox { diff --git a/wallpapers/potd/contents/ui/main.qml b/wallpapers/potd/contents/ui/main.qml --- a/wallpapers/potd/contents/ui/main.qml +++ b/wallpapers/potd/contents/ui/main.qml @@ -25,6 +25,7 @@ id: root readonly property string provider: wallpaper.configuration.Provider + readonly property string category: wallpaper.configuration.Category PlasmaCore.DataSource { id: engine