diff --git a/libdiscover/backends/FlatpakBackend/FlatpakResource.cpp b/libdiscover/backends/FlatpakBackend/FlatpakResource.cpp --- a/libdiscover/backends/FlatpakBackend/FlatpakResource.cpp +++ b/libdiscover/backends/FlatpakBackend/FlatpakResource.cpp @@ -194,7 +194,7 @@ break; case AppStream::Icon::KindRemote: const QString fileName = QStringLiteral("%1/icons/%2").arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) - .arg(icon.url().fileName()); + .arg(icon.url().fileName()); if (QFileInfo::exists(fileName)) { ret.addFile(fileName); } else { @@ -428,17 +428,23 @@ void FlatpakResource::fetchScreenshots() { QList thumbnails, screenshots; + QList remoteThumbnails, remoteScreenshots; Q_FOREACH (const AppStream::Screenshot &s, m_appdata->screenshots()) { const QUrl thumbnail = imageOfKind(s.images(), AppStream::Image::KindThumbnail); const QUrl plain = imageOfKind(s.images(), AppStream::Image::KindSource); if (plain.isEmpty()) qWarning() << "invalid screenshot for" << name(); - screenshots << plain; - thumbnails << (thumbnail.isEmpty() ? plain : thumbnail); + remoteScreenshots << plain; + remoteThumbnails << (thumbnail.isEmpty() ? plain : thumbnail); } + // Fetch screenshots to cache so next time we can get them immediately without waiting + // for them to be downloaded + thumbnails = fetchRemoteImages(remoteThumbnails, QStringLiteral("screenshots/thumbnails")); + screenshots = fetchRemoteImages(remoteScreenshots, QStringLiteral("screenshots")); + Q_EMIT screenshotsFetched(thumbnails, screenshots); } diff --git a/libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp b/libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp --- a/libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp +++ b/libdiscover/backends/PackageKitBackend/AppPackageKitResource.cpp @@ -167,17 +167,23 @@ void AppPackageKitResource::fetchScreenshots() { QList thumbnails, screenshots; + QList remoteThumbnails, remoteScreenshots; Q_FOREACH (const AppStream::Screenshot &s, m_appdata.screenshots()) { const QUrl thumbnail = imageOfKind(s.images(), AppStream::Image::KindThumbnail); const QUrl plain = imageOfKind(s.images(), AppStream::Image::KindSource); if (plain.isEmpty()) qWarning() << "invalid screenshot for" << name(); - screenshots << plain; - thumbnails << (thumbnail.isEmpty() ? plain : thumbnail); + remoteScreenshots << plain; + remoteThumbnails << (thumbnail.isEmpty() ? plain : thumbnail); } + // Fetch screenshots to cache so next time we can get them immediately without waiting + // for them to be downloaded + thumbnails = fetchRemoteImages(remoteThumbnails, QStringLiteral("screenshots/thumbnails")); + screenshots = fetchRemoteImages(remoteScreenshots, QStringLiteral("screenshots")); + Q_EMIT screenshotsFetched(thumbnails, screenshots); } diff --git a/libdiscover/resources/AbstractResource.h b/libdiscover/resources/AbstractResource.h --- a/libdiscover/resources/AbstractResource.h +++ b/libdiscover/resources/AbstractResource.h @@ -202,6 +202,11 @@ void screenshotsFetched(const QList& thumbnails, const QList& screenshots); void changelogFetched(const QString& changelog); + protected: + // Attempts to fetch remote images to cache, returning fetched images or remote + // urls when images are not fetched yet + QList fetchRemoteImages(const QList &urls, const QString &dir); + private: void reportNewState(); diff --git a/libdiscover/resources/AbstractResource.cpp b/libdiscover/resources/AbstractResource.cpp --- a/libdiscover/resources/AbstractResource.cpp +++ b/libdiscover/resources/AbstractResource.cpp @@ -22,12 +22,20 @@ #include "AbstractResourcesBackend.h" #include #include + +#include #include #include #include + +#include +#include +#include +#include +#include #include #include -#include + AbstractResource::AbstractResource(AbstractResourcesBackend* parent) : QObject(parent) @@ -147,6 +155,41 @@ return {}; } +QList AbstractResource::fetchRemoteImages(const QList &urls, const QString &dir) +{ + QList images; + + Q_FOREACH (const QUrl &url, urls) { + bool fetchImage = false; + const QString fileName = QStringLiteral("%1/images/%2/%3/%4").arg(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)) + .arg(appstreamId()) + .arg(dir) + .arg(url.fileName()); + if (QFileInfo::exists(fileName)) { + QFileInfo file(fileName); + // Refresh the cached ratings if they are older than a month - msecs * secs * minutes * hours * days + if (file.lastModified().msecsTo(QDateTime::currentDateTime()) > ((qint64)(1000 * 60 * 60 * 24) * 30)) { + fetchImage = true; + } else { + images << QUrl::fromLocalFile(fileName); + } + } else { + fetchImage = true; + } + + if (fetchImage) { + const QDir cacheDir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation)); + cacheDir.mkpath(QStringLiteral("images/%1/%2").arg(appstreamId()).arg(dir)); + // We don't need to probably check for results, either the image will be cached or not + KIO::file_copy(url, QUrl::fromLocalFile(fileName), -1, KIO::Overwrite | KIO::HideProgressInfo); + // We don't have image fetched yet, return remote URL + images << url; + } + } + + return images; +} + void AbstractResource::reportNewState() { if (backend()->isFetching())