package workers import ( "log" "os" "path/filepath" "strconv" "time" "git.elijahkuntz.com/Elijah/drive/config" "git.elijahkuntz.com/Elijah/drive/database" ) // StartTrashWorker runs a periodic task to permanently delete old items from the trash func StartTrashWorker(cfg *config.Config, db *database.DB) { ticker := time.NewTicker(24 * time.Hour) go func() { for range ticker.C { runTrashPurge(cfg, db) } }() // Also run one purge 5 minutes after startup time.AfterFunc(5*time.Minute, func() { runTrashPurge(cfg, db) }) } func runTrashPurge(cfg *config.Config, db *database.DB) { purgeDaysStr, err := db.GetSetting("trash_auto_purge_days") if err != nil { purgeDaysStr = "30" // fallback } purgeDays, err := strconv.Atoi(purgeDaysStr) if err != nil { purgeDays = 30 } if purgeDays <= 0 { return // 0 means disabled } log.Printf("🗑️ Running trash auto-purge (items older than %d days)...", purgeDays) rows, err := db.Query( "SELECT id, path FROM files WHERE is_trashed = 1 AND trashed_at <= date('now', '-' || ? || ' days')", purgeDays, ) if err != nil { log.Printf("❌ Failed to query old trash items: %v", err) return } defer rows.Close() var deletedCount int for rows.Next() { var id int var path string if err := rows.Scan(&id, &path); err != nil { continue } trashPath := filepath.Join(cfg.TrashDir, filepath.FromSlash(path)) // Remove physical file/directory if err := os.RemoveAll(trashPath); err != nil { log.Printf("❌ Failed to delete physical trash file %s: %v", trashPath, err) continue } // Remove from DB if _, err := db.Exec("DELETE FROM files WHERE id = ?", id); err != nil { log.Printf("❌ Failed to delete DB record for %s: %v", path, err) continue } deletedCount++ } if deletedCount > 0 { log.Printf("✅ Trash auto-purge completed: deleted %d old items.", deletedCount) db.AddAuditLog("trash_auto_purge", strconv.Itoa(deletedCount)+" items permanently deleted", "system") } }