summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNicolas Werner <nicolas.werner@hotmail.de>2022-12-13 06:02:07 +0100
committerNicolas Werner <nicolas.werner@hotmail.de>2022-12-13 06:02:07 +0100
commit95d898e09d2b4056e3be2b98bfaaf13946d813b0 (patch)
tree3e62455bc84ae90245da00ba7357ffcd5e967559 /src
parentAdd a button to room the upgraded room in the timeline (diff)
downloadnheko-95d898e09d2b4056e3be2b98bfaaf13946d813b0.tar.xz
Add cache pruning for old image files
Diffstat (limited to 'src')
-rw-r--r--src/MxcImageProvider.cpp59
-rw-r--r--src/MxcImageProvider.h4
2 files changed, 63 insertions, 0 deletions
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 <QPainter>
 #include <QPainterPath>
 #include <QStandardPaths>
+#include <QThreadPool>
+#include <QTimer>
 
 #include "Logging.h"
 #include "MatrixClient.h"
@@ -23,6 +25,39 @@
 
 QHash<QString, mtx::crypto::EncryptedFile> 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;