From 15fb72d2a737f819f702b682d9f105f5e357f560 Mon Sep 17 00:00:00 2001
From: Travis Ralston <travpc@gmail.com>
Date: Mon, 31 Jul 2023 20:17:41 -0600
Subject: [PATCH] Implement URL preview purge

---
 database/table_url_previews.go      | 14 ++++++++++++--
 tasks/task_runner/purge_previews.go | 21 ++++++++++++++++++++-
 2 files changed, 32 insertions(+), 3 deletions(-)

diff --git a/database/table_url_previews.go b/database/table_url_previews.go
index 23514eb9..e4a28ce9 100644
--- a/database/table_url_previews.go
+++ b/database/table_url_previews.go
@@ -27,10 +27,12 @@ type DbUrlPreview struct {
 
 const selectUrlPreview = "SELECT url, error_code, bucket_ts, site_url, site_name, resource_type, description, title, image_mxc, image_type, image_size, image_width, image_height, language_header FROM url_previews WHERE url = $1 AND bucket_ts = $2 AND language_header = $3;"
 const insertUrlPreview = "INSERT INTO url_previews (url, error_code, bucket_ts, site_url, site_name, resource_type, description, title, image_mxc, image_type, image_size, image_width, image_height, language_header) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14);"
+const deleteOldUrlPreviews = "DELETE FROM url_previews WHERE bucket_ts <= $1;"
 
 type urlPreviewsTableStatements struct {
-	selectUrlPreview *sql.Stmt
-	insertUrlPreview *sql.Stmt
+	selectUrlPreview     *sql.Stmt
+	insertUrlPreview     *sql.Stmt
+	deleteOldUrlPreviews *sql.Stmt
 }
 
 type urlPreviewsTableWithContext struct {
@@ -48,6 +50,9 @@ func prepareUrlPreviewsTables(db *sql.DB) (*urlPreviewsTableStatements, error) {
 	if stmts.insertUrlPreview, err = db.Prepare(insertUrlPreview); err != nil {
 		return nil, errors.New("error preparing insertUrlPreview: " + err.Error())
 	}
+	if stmts.deleteOldUrlPreviews, err = db.Prepare(deleteOldUrlPreviews); err != nil {
+		return nil, errors.New("error preparing deleteOldUrlPreviews: " + err.Error())
+	}
 
 	return stmts, nil
 }
@@ -82,3 +87,8 @@ func (s *urlPreviewsTableWithContext) InsertError(url string, errorCode string)
 		// remainder of fields don't matter
 	})
 }
+
+func (s *urlPreviewsTableWithContext) DeleteOlderThan(ts int64) error {
+	_, err := s.statements.deleteOldUrlPreviews.ExecContext(s.ctx, ts)
+	return err
+}
diff --git a/tasks/task_runner/purge_previews.go b/tasks/task_runner/purge_previews.go
index fbddb1ca..3a4b4080 100644
--- a/tasks/task_runner/purge_previews.go
+++ b/tasks/task_runner/purge_previews.go
@@ -1,7 +1,26 @@
 package task_runner
 
-import "github.com/turt2live/matrix-media-repo/common/rcontext"
+import (
+	"github.com/getsentry/sentry-go"
+	"github.com/turt2live/matrix-media-repo/common/config"
+	"github.com/turt2live/matrix-media-repo/common/rcontext"
+	"github.com/turt2live/matrix-media-repo/database"
+	"github.com/turt2live/matrix-media-repo/util"
+)
 
 func PurgePreviews(ctx rcontext.RequestContext) {
+	// dev note: don't use ctx for config lookup to avoid misreading it
 
+	if config.Get().UrlPreviews.ExpireDays <= 0 {
+		return
+	}
+
+	beforeTs := util.NowMillis() - int64(config.Get().UrlPreviews.ExpireDays*24*60*60*1000)
+	db := database.GetInstance().UrlPreviews.Prepare(ctx)
+
+	// TODO: Fix https://github.com/turt2live/matrix-media-repo/issues/424 ("can't clean up preview media")
+	if err := db.DeleteOlderThan(beforeTs); err != nil {
+		ctx.Log.Error("Error deleting previews: ", err)
+		sentry.CaptureException(err)
+	}
 }
-- 
GitLab