From 95d898e09d2b4056e3be2b98bfaaf13946d813b0 Mon Sep 17 00:00:00 2001 From: Nicolas Werner Date: Tue, 13 Dec 2022 06:02:07 +0100 Subject: [PATCH] Add cache pruning for old image files --- src/MxcImageProvider.cpp | 59 ++++++++++++++++++++++++++++++++++++++++ src/MxcImageProvider.h | 4 +++ 2 files changed, 63 insertions(+) diff --git a/src/MxcImageProvider.cpp b/src/MxcImageProvider.cpp index cd7e3946..00177b73 100644 --- a/src/MxcImageProvider.cpp +++ b/src/MxcImageProvider.cpp @@ -16,6 +16,8 @@ #include #include #include +#include +#include #include "Logging.h" #include "MatrixClient.h" @@ -23,6 +25,39 @@ QHash infos; +MxcImageProvider::MxcImageProvider(QObject *parent) +#if QT_VERSION < 0x60000 + : QObject(parent) +#else + : QQuickAsyncImageProvider(parent) +#endif +{ + auto timer = new QTimer(this); + timer->setInterval(std::chrono::hours(30)); + connect(timer, &QTimer::timeout, this, [] { + QThreadPool::globalInstance()->start([] { + QDir dir(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + + "/media_cache", + "", + QDir::SortFlags(QDir::Name | QDir::IgnoreCase), + QDir::Filter::Writable | QDir::Filter::NoDotAndDotDot | QDir::Filter::Files); + + for (const auto &fileInfo : dir.entryInfoList()) { + if (fileInfo.fileTime(QFile::FileTime::FileAccessTime) + .daysTo(QDateTime::currentDateTime()) > 30) { + if (QFile::remove(fileInfo.absoluteFilePath())) + nhlog::net()->debug("Deleted stale media '{}'", + fileInfo.absoluteFilePath().toStdString()); + else + nhlog::net()->warn("Failed to delete stale media '{}'", + fileInfo.absoluteFilePath().toStdString()); + } + } + }); + }); + timer->start(); +} + QQuickImageResponse * MxcImageProvider::requestImageResponse(const QString &id, const QSize &requestedSize) { @@ -97,6 +132,24 @@ clipRadius(QImage img, double radius) return out; } +static void +possiblyUpdateAccessTime(const QFileInfo &fileInfo) +{ + if (fileInfo.fileTime(QFile::FileTime::FileAccessTime).daysTo(QDateTime::currentDateTime()) > + 7) { + nhlog::net()->debug("Updating file time for '{}'", + fileInfo.absoluteFilePath().toStdString()); + + QFile f(fileInfo.absoluteFilePath()); + + if (!f.open(QIODevice::ReadWrite) || + !f.setFileTime(QDateTime::currentDateTime(), QFile::FileTime::FileAccessTime)) { + nhlog::net()->warn("Failed to update filetime for '{}'", + fileInfo.absoluteFilePath().toStdString()); + } + } +} + void MxcImageProvider::download(const QString &id, const QSize &requestedSize, @@ -141,6 +194,8 @@ MxcImageProvider::download(const QString &id, if (fileInfo.exists()) { QImage image = utils::readImageFromFile(fileInfo.absoluteFilePath()); if (!image.isNull()) { + possiblyUpdateAccessTime(fileInfo); + if (requestedSize.width() <= 0) { image = image.scaledToHeight(requestedSize.height(), Qt::SmoothTransformation); } else { @@ -185,6 +240,8 @@ MxcImageProvider::download(const QString &id, auto data = QByteArray(res.data(), (int)res.size()); QImage image = utils::readImage(data); if (!image.isNull()) { + possiblyUpdateAccessTime(fileInfo); + if (requestedSize.width() <= 0) { image = image.scaledToHeight(requestedSize.height(), Qt::SmoothTransformation); @@ -238,6 +295,7 @@ MxcImageProvider::download(const QString &id, QImage image = utils::readImage(data); image.setText(QStringLiteral("mxc url"), "mxc://" + id); if (!image.isNull()) { + possiblyUpdateAccessTime(fileInfo); if (radius != 0) { image = clipRadius(std::move(image), radius); } @@ -248,6 +306,7 @@ MxcImageProvider::download(const QString &id, } else { QImage image = utils::readImageFromFile(fileInfo.absoluteFilePath()); if (!image.isNull()) { + possiblyUpdateAccessTime(fileInfo); if (radius != 0) { image = clipRadius(std::move(image), radius); } diff --git a/src/MxcImageProvider.h b/src/MxcImageProvider.h index 9d5aaabc..d8325219 100644 --- a/src/MxcImageProvider.h +++ b/src/MxcImageProvider.h @@ -80,6 +80,10 @@ class MxcImageProvider public QQuickAsyncImageProvider { Q_OBJECT + +public: + MxcImageProvider(QObject *parent = nullptr); + public slots: QQuickImageResponse * requestImageResponse(const QString &id, const QSize &requestedSize) override;