0
0
mirror of https://github.com/rls-moe/nyx synced 2024-11-22 22:12:24 +00:00
nyx/http/admin/cleanup.go

140 lines
3.5 KiB
Go

package admin
import (
"encoding/json"
"fmt"
"github.com/tidwall/buntdb"
"go.rls.moe/nyx/http/errw"
"go.rls.moe/nyx/http/middle"
"go.rls.moe/nyx/resources"
"net/http"
"strings"
"time"
)
func handleCleanup(w http.ResponseWriter, r *http.Request) {
sess := middle.GetSession(r)
if sess == nil {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Unauthorized"))
return
}
if sess.CAttr("mode") != "admin" {
w.WriteHeader(http.StatusUnauthorized)
w.Write([]byte("Unauthorized"))
return
}
fmt.Println("Beginning cleanup...")
db := middle.GetDB(r)
var delKeys = []string{}
err := db.View(func(tx *buntdb.Tx) error {
var err error
tx.AscendKeys("*", func(key, value string) bool {
keyType := detectType(key)
if keyType == "thread" {
var host string
host, err = resources.GetHostnameFromKey(key)
if err != nil {
fmt.Printf("Error: %s", err)
return false
}
var thread = &resources.Thread{}
err = json.Unmarshal([]byte(value), thread)
if err != nil {
fmt.Printf("Error: %s", err)
return false
}
threadTime := resources.DateFromId(thread.ID)
dur := threadTime.Sub(time.Now())
if dur > time.Hour*24*7 {
fmt.Printf("Sched %s for deletion: expired\n", key)
delKeys = append(delKeys, key)
return true
}
err = resources.FillReplies(tx, host, thread)
if err != nil {
fmt.Printf("Error: %s", err)
return false
}
if len(thread.GetReplies()) == 0 {
fmt.Printf("Sched %s for deletion: empty\n", key)
delKeys = append(delKeys, key)
return true
}
if _, err := resources.GetReply(tx, host, thread.Board, thread.ID, thread.StartReply); err == buntdb.ErrNotFound {
fmt.Printf("Sched %s for delection: main reply dead\n", key)
delKeys = append(delKeys, key)
return true
}
} else if keyType == "reply" {
var host string
host, err = resources.GetHostnameFromKey(key)
if err != nil {
fmt.Printf("Error: %s", err)
return false
}
var reply = &resources.Reply{}
err = json.Unmarshal([]byte(value), reply)
if err != nil {
fmt.Printf("Error: %s", err)
return false
}
replyTime := resources.DateFromId(reply.ID)
dur := replyTime.Sub(time.Now())
if dur > time.Hour*24*7 {
fmt.Printf("Sched %s for deletion: expired\n", key)
delKeys = append(delKeys, key)
return true
}
if val, ok := reply.Metadata["deleted"]; ok && val == "yes" {
fmt.Printf("Sched %s for deletion: deleted\n", key)
delKeys = append(delKeys, key)
return true
}
if err := resources.TestThread(tx, host, reply.Board, reply.Thread); err == buntdb.ErrNotFound {
fmt.Printf("Sched %s for deletion: missing parent %d: %s\n", key, reply.Thread, err)
delKeys = append(delKeys, key)
return true
}
}
return true
})
/* Insert cleanup codes here */
return err
})
fmt.Println("Removing sched' entries")
db.Update(func(tx *buntdb.Tx) error {
for _, v := range delKeys {
fmt.Printf("Deleting %s\n", v)
tx.Delete(v)
}
return nil
})
fmt.Println("Shrinking DB")
err = db.Shrink()
if err != nil {
errw.ErrorWriter(err, w, r)
return
}
fmt.Println("Finished Cleanup")
http.Redirect(w, r, "/admin/panel.html", http.StatusSeeOther)
}
func detectType(key string) string {
if strings.Contains(key, "/jack/") {
if strings.HasSuffix(key, "/board-data") {
return "board"
}
if strings.HasSuffix(key, "/thread") {
return "thread"
}
if strings.HasSuffix(key, "/reply-data") {
return "reply"
}
return "system"
}
return "none"
}