Author: Adam Evyčędo <git@apiote.xyz>
try XDG directories in sequence
db.go | 32 +++++++++++++++++++++++++++++++- eostre.sh | 18 ++++++++++++++++-- main.go | 44 +++++++++++++++++++++++++++++++++----------- mimir.go | 7 ++++--- tyr.go | 5 +++--
diff --git a/db.go b/db.go index b12efb681ea49bc271a60eb3b598c07f919fdca5..6434483dfd08745128726949c6d3d4de57e48c3c 100644 --- a/db.go +++ b/db.go @@ -3,6 +3,7 @@ import ( "database/sql" "fmt" + "os" "path/filepath" "strings" "time" @@ -65,7 +66,36 @@ } } func migrate(dbPath string) (*sql.DB, error) { - db, err := open(dbPath) + home, err := os.UserHomeDir() + if err != nil { + return nil, fmt.Errorf("while getting user home dir: %w", err) + } + possibleDbDirs := []string{ + "/var/lib/asgard", + home + "/.local/state/asgard", + ".", + } + + if dbPath != "" { + possibleDbDirs = append([]string{filepath.Dir(dbPath)}, possibleDbDirs...) + } + + finalDbPath := "" + for _, possibleDbDir := range possibleDbDirs { + dirInfo, err := os.Stat(possibleDbDir) + if err == nil && dirInfo.IsDir() { + if filepath.Dir(dbPath) == possibleDbDir && dbPath != "" { + finalDbPath = dbPath + } else { + finalDbPath = possibleDbDir + "/asgard.db" + } + break + } + } + if finalDbPath == "" { + return nil, fmt.Errorf("no suitable db directory found") + } + db, err := open(finalDbPath) _, err = db.Exec(`create table tyr_knownAddresses(address_from text, address_to text, ban boolean, unique(address, direction))`) if err != nil && err.Error() != "table tyr_knownAddresses already exists" { return nil, err diff --git a/eostre.sh b/eostre.sh index 96b7791a2e906b58b1f38c7e8d38280c1a8ad359..02f1910cc343e0d319debe2e0ac1a542fb41e54d 100755 --- a/eostre.sh +++ b/eostre.sh @@ -1,6 +1,19 @@ #!/bin/sh # NEEDS sed,grep,zip,unzip +findTemplate() { + templateName=$1 + for d in /usr/share/asgard/templates ~/.local/share/asgard/templates templates . + do + if stat "$d/$templateName" >/dev/null 2>&1 + then + echo "$d/$templateName" + return + fi + done + return 1 +} + set -e # shellcheck disable=SC2010 @@ -49,12 +62,13 @@ for year in $years do manifest="$manifest\n\t\t<item href=\"Text/$year.xhtml\" id=\"$year.xhtml\" media-type=\"application/xhtml+xml\"/>" spine="$spine\n\t\t<itemref idref=\"$year.xhtml\"/>" - cp templates/content.opf.template tmp/OEBPS/content.opf + + cp "$(findTemplate content.opf.template)" tmp/OEBPS/content.opf sed -i "s|{{manifest}}|$manifest|" tmp/OEBPS/content.opf sed -i "s|{{spine}}|$spine|" tmp/OEBPS/content.opf toc="$toc\n\t\t<li><a href=\"$year.xhtml\">$year</a></li>" - cp templates/nav.xhtml.template tmp/OEBPS/Text/nav.xhtml + cp "$(findTemplate nav.xhtml.template)" tmp/OEBPS/Text/nav.xhtml sed -i "s|{{toc}}|$toc|" tmp/OEBPS/Text/nav.xhtml done diff --git a/main.go b/main.go index 3b2acfbbdd9dd9369b7a7459b3bf6c5a1eb8be16..a76995e2dbf5b2811b1f4e49919e3d3b1b96d0ca 100644 --- a/main.go +++ b/main.go @@ -1,7 +1,9 @@ package main import ( + "embed" "errors" + "fmt" "log" "net/http" "os" @@ -9,6 +11,9 @@ "apiote.xyz/p/go-dirty" "git.sr.ht/~sircmpwn/getopt" ) + +//go:embed templates +var templatesFS embed.FS type TyrConfig struct { ImapAddress string @@ -93,17 +98,34 @@ Gersemi GersemiConfig } func readConfig(configPath string) (Config, error) { - if configPath == "" { - // TODO try XDG_CONFIG/asgard.dirty, /etc/asgard.dirty, ~/.config/asgard.dirty - configPath = "asgard.dirty" + config := Config{} + userConfigDir, err := os.UserConfigDir() + if err != nil { + return config, fmt.Errorf("while getting user config dir: %w", err) + } + possibleConfigs := []string{ + configPath, + "/etc/asgard.dirty", + userConfigDir + "/asgard.dirty", + "asgard.dirty", } - file, err := os.Open(configPath) + finalConfigPath := "" + for _, possibleConfig := range possibleConfigs { + _, err := os.Stat(possibleConfig) + if err == nil { + finalConfigPath = possibleConfig + break + } + } + if finalConfigPath == "" { + return config, fmt.Errorf("no config found") + } + file, err := os.Open(finalConfigPath) if err != nil { log.Printf("error opening configuration %v\n", err) - return Config{}, err + return config, err } defer file.Close() - config := Config{} err = dirty.LoadStruct(file, &config) return config, err } @@ -114,14 +136,14 @@ configPath string dbPath string ) getopt.StringVar(&configPath, "c", "", "path to config file") - getopt.StringVar(&dbPath, "b", "asgard.db", "path to database file") + getopt.StringVar(&dbPath, "b", "", "path to database file") getopt.Parse() config, err := readConfig(configPath) if err != nil { log.Fatalln(err) } - //log.Printf("running with conifig\n%+v\n", config) + db, err := migrate(dbPath) if err != nil { log.Fatalln(err) @@ -205,9 +227,9 @@ case "gersemi": log.Println(gersemi(config)) case "serve": - http.HandleFunc("/tyr", tyr_serve(db, config)) - http.HandleFunc("/mimir", mimir_serve(db)) - http.HandleFunc("/mimir/", mimir_serve(db)) + http.HandleFunc("/tyr", tyr_serve(db, config, templatesFS)) + http.HandleFunc("/mimir", mimir_serve(db, templatesFS)) + http.HandleFunc("/mimir/", mimir_serve(db, templatesFS)) e := http.ListenAndServe(":8081", nil) if e != nil { log.Println(e) diff --git a/mimir.go b/mimir.go index 7c5bb051e45645c23da647bd493e2d9eb3cc3c65..61b7ad93687c58c4caa87cfabe9795b591a2fbd7 100644 --- a/mimir.go +++ b/mimir.go @@ -31,6 +31,7 @@ import ( "bytes" "database/sql" + "embed" "errors" "fmt" "html/template" @@ -274,7 +275,7 @@ m := am.(*MimirImapMessage) return removeMessage(m.client(), m.message().Uid, m.mboxName) } -func mimir_serve(db *sql.DB) func(w http.ResponseWriter, r *http.Request) { +func mimir_serve(db *sql.DB, templatesFs embed.FS) func(w http.ResponseWriter, r *http.Request) { // todo on back check with cache return func(w http.ResponseWriter, r *http.Request) { path := strings.Split(r.URL.Path[1:], "/") @@ -297,7 +298,7 @@ if err != nil { w.WriteHeader(http.StatusInternalServerError) log.Println(err) } - t, err := template.ParseFiles("templates/mimir_threads.html") + t, err := template.ParseFS(templatesFs, "templates/mimir_threads.html") if err != nil { w.WriteHeader(http.StatusInternalServerError) log.Println(err) @@ -322,7 +323,7 @@ log.Println(err) } return } - t, err := template.ParseFiles("templates/mimir_message.html") + t, err := template.ParseFS(templatesFs, "templates/mimir_message.html") if err != nil { w.WriteHeader(http.StatusInternalServerError) log.Println(err) diff --git a/tyr.go b/tyr.go index c4f2459c9bb2cf2ff20ee7044d21e7ecf9521bb6..f2f2e67f28cdf1c678645f1d0ed2be734018b043 100644 --- a/tyr.go +++ b/tyr.go @@ -4,6 +4,7 @@ import ( "bytes" "crypto/sha256" "database/sql" + "embed" "fmt" "html/template" "io" @@ -287,7 +288,7 @@ moveFromQuarantine(c, mbox, lock.address, dest) return nil } -func tyr_serve(db *sql.DB, config Config) func(w http.ResponseWriter, r *http.Request) { +func tyr_serve(db *sql.DB, config Config, templatesFs embed.FS) func(w http.ResponseWriter, r *http.Request) { return func(w http.ResponseWriter, r *http.Request) { r.ParseForm() formAddress := r.Form.Get("address") @@ -300,7 +301,7 @@ Token: formToken, Captcha: "$696a04444feea781aeca9c546e220e0981aff4a8db0b2998decdf13265a95c31", // todo with salt and randomised time Error: formError, } - t, _ := template.ParseFiles("templates/tyr.html") + t, _ := template.ParseFS(templatesFs, "templates/tyr.html") b := bytes.NewBuffer([]byte{}) _ = t.Execute(b, tyrData) io.Copy(w, b)