Implement thread pruning based on bumped_at

This commit is contained in:
Dominic Ferrando
2025-04-21 14:00:10 -04:00
parent 997d65707c
commit 80a0a5eb89
4 changed files with 88 additions and 14 deletions
+72
View File
@@ -2,10 +2,15 @@ package database
import (
"database/sql"
"os"
"path"
"github.com/dominicf2001/comfychan/internal/util"
)
type Queryer interface {
Exec(query string, args ...any) (sql.Result, error)
Query(query string, args ...any) (*sql.Rows, error)
QueryRow(query string, args ...any) *sql.Row
}
@@ -149,6 +154,33 @@ func PutThread(db *sql.DB, boardSlug string, subject string, body string, mediaP
return err
}
row := tx.QueryRow("SELECT COUNT(*) FROM threads WHERE board_slug = ?", boardSlug)
var threadCount int
if err = row.Scan(&threadCount); err != nil {
return err
}
if threadCount > util.MAX_THREAD_COUNT {
row := tx.QueryRow(`
SELECT id FROM threads
WHERE id = (
SELECT id FROM threads
WHERE board_slug = ?
ORDER BY bumped_at ASC
LIMIT 1)`, boardSlug)
var pruneThreadId int
err := row.Scan(&pruneThreadId)
if err != nil {
return err
}
if err := DeleteThread(tx, pruneThreadId); err != nil {
return err
}
}
if err = tx.Commit(); err != nil {
return err
}
@@ -187,3 +219,43 @@ func PutPost(db Queryer, boardSlug string, threadId int, body string, mediaPath
return nil
}
func DeleteThread(db Queryer, threadId int) error {
// cleanup images
rows, err := db.Query(`
SELECT media_path
FROM posts
WHERE thread_id = ?`, threadId)
if err != nil {
return err
}
defer rows.Close()
var pruneMediaPaths []string
for rows.Next() {
var pruneMediaPath string
if err := rows.Scan(&pruneMediaPath); err != nil {
return err
}
pruneMediaPaths = append(pruneMediaPaths, pruneMediaPath)
}
for _, pruneMediaPath := range pruneMediaPaths {
if err := os.Remove(path.Join(util.POST_IMG_FULL_PATH, pruneMediaPath)); err != nil && !os.IsNotExist(err) {
return err
}
if err := os.Remove(path.Join(util.POST_IMG_THUMB_PATH, pruneMediaPath)); err != nil && !os.IsNotExist(err) {
return err
}
}
// delete thread
_, err = db.Exec(`
DELETE FROM threads
WHERE id = ?`, threadId)
if err != nil {
return err
}
return nil
}
+6 -4
View File
@@ -17,11 +17,13 @@ var (
var CooldownMutex sync.Mutex
// const POST_COOLDOWN = 15 * time.Second
const POST_COOLDOWN = 0 * time.Second
const POST_COOLDOWN = 15 * time.Second
// const THREAD_COOLDOWN = 2 * time.Minute
const THREAD_COOLDOWN = 0 * time.Minute
// const POST_COOLDOWN = 0 * time.Second
const THREAD_COOLDOWN = 2 * time.Minute
// const THREAD_COOLDOWN = 0 * time.Minute
func IsOnCooldown(ip string, m map[string]time.Time, duration time.Duration) bool {
CooldownMutex.Lock()
+1 -9
View File
@@ -13,13 +13,13 @@ import (
"strings"
"github.com/disintegration/imaging"
"github.com/dominicf2001/comfychan/internal/database"
)
// 10 MB memory limit
const FILE_MEM_LIMIT int64 = 10 << 20
const POST_IMG_FULL_PATH = "web/static/img/posts/full"
const POST_IMG_THUMB_PATH = "web/static/img/posts/thumb"
const MAX_THREAD_COUNT = 50
func EnrichPost(body string) string {
var b strings.Builder
@@ -105,14 +105,6 @@ func SavePostFile(file *multipart.File, filename string) error {
return nil
}
func SumUniquePostIps(posts []database.Post) int {
uniqueIpHashes := map[string]bool{}
for _, post := range posts {
uniqueIpHashes[post.IpHash] = true
}
return len(uniqueIpHashes)
}
type PostImageInfo struct {
Size int64
Height int
+9 -1
View File
@@ -30,6 +30,14 @@ func disableCacheInDevMode(next http.Handler) http.Handler {
})
}
func SumUniquePostIps(posts []database.Post) int {
uniqueIpHashes := map[string]bool{}
for _, post := range posts {
uniqueIpHashes[post.IpHash] = true
}
return len(uniqueIpHashes)
}
func main() {
// -----------------
// SETUP
@@ -244,7 +252,7 @@ func main() {
ThreadURL: fmt.Sprintf("/%s/threads/%d", slug, thread.Id),
MediaPath: op.MediaPath,
ReplyCount: len(posts),
IpCount: util.SumUniquePostIps(posts),
IpCount: SumUniquePostIps(posts),
})
}