nyx/resources/db.go

140 lines
3.6 KiB
Go

package resources
import (
"errors"
"fmt"
"github.com/tidwall/buntdb"
"regexp"
"strings"
)
const (
setup = "/jack/setup"
hostEnable = "/jack/%s/enabled"
boardPath = "/jack/%s/board/%s/board-data"
threadPath = "/jack/%s/board/%s/thread/%032d/thread-data"
threadSPath = "/jack/%s/board/%s/thread/*/thread-data"
replyPath = "/jack/%s/board/%s/thread/%032d/reply/%032d/reply-data"
replySPath = "/jack/%s/board/%s/thread/%032d/reply/*/reply-data"
modPassPath = "/jack/%s/pass/mod/%s/mod-data"
adminPassPath = "/jack/./pass/admin/%s/admin-data"
)
func GetHostnameFromKey(key string) (string, error) {
regex := regexp.MustCompile(`^/jack/(.+)/(board|pass)`)
res := regex.FindStringSubmatch(key)
if len(res) != 3 {
fmt.Printf("Found %d keys: %s", len(res), res)
return "", errors.New("Could not find host in key")
}
return unescapeString(res[1]), nil
}
func InitialSetup(db *buntdb.DB) error {
return db.Update(func(tx *buntdb.Tx) error {
if _, err := tx.Get(setup); err != nil {
fmt.Println("")
if err != buntdb.ErrNotFound {
fmt.Println("DB setup not known.")
return err
}
fmt.Println("DB not setup.")
tx.Set(setup, "yes", nil)
} else {
fmt.Println("DB setup.")
return nil
}
fmt.Println("Creating Indices")
err := tx.CreateIndex("board/short", "/jack/*/board/*/board-data", buntdb.IndexJSON("short"))
if err != nil {
return err
}
err = tx.CreateIndex("replies", "/jack/*/board/*/thread/*/reply/*/reply-data", buntdb.IndexJSON("thread"))
if err != nil {
return err
}
err = tx.CreateIndex("board/thread", "/jack/*/board/*/thread/*/thread-data", buntdb.IndexJSON("board"))
if err != nil {
return err
}
fmt.Println("Creating default admin")
admin := &AdminPass{
ID: "admin",
}
err = admin.HashLogin("admin")
if err != nil {
return err
}
fmt.Println("Saving default admin to DB")
err = NewAdmin(tx, admin)
if err != nil {
return err
}
fmt.Println("Committing setup...")
return nil
})
}
func CreateHost(db *buntdb.DB, hostname string) error {
return db.Update(func(tx *buntdb.Tx) error {
hostname = escapeString(hostname)
_, replaced, err := tx.Set(fmt.Sprintf(hostEnable, "hostname"), "", nil)
if err != nil {
tx.Rollback()
return err
}
if replaced {
tx.Rollback()
return errors.New("Hostname already enabled")
}
board := &Board{
ShortName: "d",
LongName: "default",
Metadata: map[string]string{
"locked": "true",
"description": "Default Board",
},
}
err = NewBoard(tx, hostname, board)
if err != nil {
tx.Rollback()
return err
}
return nil
})
}
func escapeString(in string) string {
in = strings.Replace(in, ".", ".dot.", -1)
in = strings.Replace(in, "-", ".minus.", -1)
in = strings.Replace(in, "\\", ".backslash.", -1)
in = strings.Replace(in, "*", ".star.", -1)
in = strings.Replace(in, "?", ".ask.", -1)
in = strings.Replace(in, "/", ".slash.", -1)
in = strings.Replace(in, "@", ".at.", -1)
in = strings.Replace(in, ">>", ".quote.", -1)
in = strings.Replace(in, ">", ".arrow-left.", -1)
in = strings.Replace(in, "<", ".arrow-right.", -1)
return in
}
func unescapeString(in string) string {
in = strings.Replace(in, ".arrow-right.", "<", -1)
in = strings.Replace(in, ".arrow-left.", ">", -1)
in = strings.Replace(in, ".quote.", ">>", -1)
in = strings.Replace(in, ".at.", "@", -1)
in = strings.Replace(in, ".slash.", "/", -1)
in = strings.Replace(in, ".ask.", "?", -1)
in = strings.Replace(in, ".star.", "*", -1)
in = strings.Replace(in, ".backslash.", "\\", -1)
in = strings.Replace(in, ".minus.", "-", -1)
in = strings.Replace(in, ".dot.", ".", -1)
return in
}