Commit 630534b

Eric Bower  ·  2026-03-05 23:09:37 -0500 EST
parent f969ffd
feat(pgs): all projects named `bin` will have their files deleted automatically after 2 weeks

This replicates the 0x0.st functionality where you can uploading any file and it'll eventually be deleted.
2 files changed,  +78, -0
+75, -0
......@@ -0,0 +1,75 @@
1+package pgs
2+
3+import (
4+ "log/slog"
5+ "time"
6+
7+ pgsdb "github.com/picosh/pico/pkg/apps/pgs/db"
8+ "github.com/picosh/pico/pkg/shared"
9+ "github.com/picosh/pico/pkg/shared/storage"
10+)
11+
12+const binRetentionDays = 14
13+
14+func BinCron(cfg *PgsConfig) {
15+ logger := cfg.Logger
16+ storage := cfg.Storage
17+ db := cfg.DB
18+
19+ // Loop every 10 minutes
20+ ticker := time.NewTicker(10 * time.Minute)
21+ defer ticker.Stop()
22+ deleteOldBinObjects(logger, db, storage)
23+
24+ for range ticker.C {
25+ deleteOldBinObjects(logger, db, storage)
26+ }
27+}
28+
29+func deleteOldBinObjects(logger *slog.Logger, db pgsdb.PgsDB, storage storage.StorageServe) {
30+ logger.Info("running bin cron")
31+ users, err := db.FindUsers()
32+ if err != nil {
33+ logger.Error("failed to find users", "error", err)
34+ return
35+ }
36+
37+ for _, user := range users {
38+ log := shared.LoggerWithUser(logger, user)
39+ bucketName := shared.GetAssetBucketName(user.ID)
40+ bucket, err := storage.GetBucket(bucketName)
41+ if err != nil {
42+ log.Error("failed to get bucket", "bucket", bucketName, "error", err)
43+ continue
44+ }
45+
46+ project, err := db.FindProjectByName(user.ID, "bin")
47+ if err != nil {
48+ continue
49+ }
50+
51+ log = log.With("project", project.Name)
52+
53+ objs, err := storage.ListObjects(bucket, project.ProjectDir+"/", true)
54+ if err != nil {
55+ log.Error("failed to list objects", "error", err)
56+ continue
57+ }
58+
59+ cutoff := time.Now().Add(-binRetentionDays * 24 * time.Hour)
60+ for _, obj := range objs {
61+ if obj.IsDir() {
62+ continue
63+ }
64+
65+ if obj.ModTime().Before(cutoff) {
66+ objPath := project.ProjectDir + "/" + obj.Name()
67+ if err := storage.DeleteObject(bucket, objPath); err != nil {
68+ logger.Error("failed to delete old object", "file", obj.Name(), "error", err)
69+ } else {
70+ logger.Info("deleted old object", "file", obj.Name(), "age", time.Since(obj.ModTime()))
71+ }
72+ }
73+ }
74+ }
75+}
+3, -0
......@@ -80,6 +80,9 @@ func StartSshServer(cfg *PgsConfig, killCh chan error) {
8080 os.Exit(1)
8181 }
8282
83+ // start cron job for bin project ttl
84+ go BinCron(cfg)
85+
8386 done := make(chan os.Signal, 1)
8487 signal.Notify(done, os.Interrupt, syscall.SIGINT, syscall.SIGTERM)
8588 logger.Info("Starting SSH server", "addr", server.Config.ListenAddr)