From c961db9fae07bf02dce9a6dd03611e9f7c30d33e Mon Sep 17 00:00:00 2001 From: Timur Ismagilov Date: Sat, 7 Sep 2024 22:22:50 +0300 Subject: [PATCH] Migrate interwiki --- interwiki/interwiki.go | 56 +++++++++++++++++++++++++----------------- interwiki/web.go | 19 +++++++++----- interwiki/wiki.go | 20 +++++++++++---- main.go | 4 ++- 4 files changed, 64 insertions(+), 35 deletions(-) diff --git a/interwiki/interwiki.go b/interwiki/interwiki.go index de4a532..52f1583 100644 --- a/interwiki/interwiki.go +++ b/interwiki/interwiki.go @@ -4,29 +4,36 @@ package interwiki import ( "encoding/json" "errors" - "git.sr.ht/~bouncepaw/mycomarkup/v5/options" - "github.com/bouncepaw/mycorrhiza/internal/files" - "github.com/bouncepaw/mycorrhiza/util" - "log" + "log/slog" "os" "sync" + + "github.com/bouncepaw/mycorrhiza/internal/files" + "github.com/bouncepaw/mycorrhiza/util" + + "git.sr.ht/~bouncepaw/mycomarkup/v5/options" ) -func Init() { - var ( - record, err = readInterwiki() - ) +func Init() error { + record, err := readInterwiki() if err != nil { - log.Fatalln(err) + slog.Error("Failed to read interwiki", "err", err) + return err } + for _, wiki := range record { wiki := wiki // This line is required - wiki.canonize() + if err := wiki.canonize(); err != nil { + return err + } if err := addEntry(&wiki); err != nil { - log.Fatalln(err.Error()) + slog.Error("Failed to add interwiki entry", "err", err) + return err } } - log.Printf("Loaded %d interwiki entries\n", len(listOfEntries)) + + slog.Info("Loaded interwiki map", "entryCount", len(listOfEntries)) + return nil } func dropEmptyStrings(ss []string) (clean []string) { @@ -100,7 +107,6 @@ func deleteEntry(wiki *Wiki) { for i, w := range listOfEntries { i, w := i, w if w.Name == wiki.Name { - log.Println("It came to delete") // Drop ith element. listOfEntries[i] = listOfEntries[len(listOfEntries)-1] listOfEntries = listOfEntries[:len(listOfEntries)-1] @@ -113,21 +119,22 @@ func deleteEntry(wiki *Wiki) { wg.Wait() } +// TODO: There is something clearly wrong with error-returning in this function. func addEntry(wiki *Wiki) error { mutex.Lock() defer mutex.Unlock() wiki.Aliases = dropEmptyStrings(wiki.Aliases) + var ( names = append(wiki.Aliases, wiki.Name) ok, name = areNamesFree(names) ) - if !ok { - log.Printf("There are multiple uses of the same name ‘%s’\n", name) + switch { + case !ok: + slog.Error("There are multiple uses of the same name", "name", name) return errors.New(name) - } - if len(names) == 0 { - log.Println("No names passed for a new interwiki entry") - // There is something clearly wrong with error-returning in this function. + case len(names) == 0: + slog.Error("No names passed for a new interwiki entry") return errors.New("") } @@ -176,10 +183,13 @@ func readInterwiki() ([]Wiki, error) { func saveInterwikiJson() { // Trust me, wiki crashing when an admin takes an administrative action totally makes sense. if data, err := json.MarshalIndent(listOfEntries, "", "\t"); err != nil { - log.Fatalln(err) + slog.Error("Failed to marshal interwiki entries", "err", err) + os.Exit(1) } else if err = os.WriteFile(files.InterwikiJSON(), data, 0666); err != nil { - log.Fatalln(err) - } else { - log.Println("Saved interwiki.json") + slog.Error("Failed to write interwiki.json", "err", err) + os.Exit(1) } + + slog.Info("Saved interwiki.json") + } diff --git a/interwiki/web.go b/interwiki/web.go index 58ba51d..b8c62f8 100644 --- a/interwiki/web.go +++ b/interwiki/web.go @@ -2,11 +2,13 @@ package interwiki import ( "embed" - "github.com/bouncepaw/mycorrhiza/web/viewutil" - "github.com/gorilla/mux" - "log" + "log/slog" "net/http" "strings" + + "github.com/bouncepaw/mycorrhiza/web/viewutil" + + "github.com/gorilla/mux" ) var ( @@ -63,19 +65,24 @@ func handlerModifyEntry(w http.ResponseWriter, rq *http.Request) { ) if oldData, ok = entriesByName[name]; !ok { - log.Printf("Could not modify interwiki entry ‘%s’ because it does not exist", name) + slog.Info("Could not modify entry", + "name", name, + "reason", "does not exist") viewutil.HandlerNotFound(w, rq) return } if err := replaceEntry(oldData, &newData); err != nil { - log.Printf("Could not modify interwiki entry ‘%s’ because one of the proposed aliases/name is taken\n", name) + slog.Info("Could not modify entry", + "name", name, + "reason", "one of the proposed aliases or the name is taken", + "err", err) viewNameTaken(viewutil.MetaFrom(w, rq), oldData, err.Error(), "modify-entry/"+name) return } saveInterwikiJson() - log.Printf("Modified interwiki entry ‘%s’\n", name) + slog.Info("Modified entry", "name", name) http.Redirect(w, rq, "/interwiki", http.StatusSeeOther) } diff --git a/interwiki/wiki.go b/interwiki/wiki.go index 4d0ef51..05df378 100644 --- a/interwiki/wiki.go +++ b/interwiki/wiki.go @@ -1,9 +1,11 @@ package interwiki import ( + "errors" "fmt" + "log/slog" + "github.com/bouncepaw/mycorrhiza/util" - "log" ) // WikiEngine is an enumeration of supported interwiki targets. @@ -47,14 +49,20 @@ type Wiki struct { Engine WikiEngine `json:"engine"` } -func (w *Wiki) canonize() { +func (w *Wiki) canonize() error { switch { case w.Name == "": - log.Fatalln("Cannot have a wiki in the interwiki map with no name") + slog.Error("A site in the interwiki map has no name") + return errors.New("site with no name") case w.URL == "": - log.Fatalf("Wiki ‘%s’ has no URL\n", w.Name) + slog.Error("Site in the interwiki map has no URL", "name", w.Name) + return errors.New("site with no URL") case !w.Engine.Valid(): - log.Fatalf("Unknown engine ‘%s’ for wiki ‘%s’\n", w.Engine, w.Name) + slog.Error("Site in the interwiki map has an unknown engine", + "siteName", w.Name, + "engine", w.Engine, + ) + return errors.New("unknown engine") } w.Name = util.CanonicalName(w.Name) @@ -83,4 +91,6 @@ func (w *Wiki) canonize() { w.ImgSrcFormat = fmt.Sprintf("%s/{NAME}", w.URL) } } + + return nil } diff --git a/main.go b/main.go index a2b6f50..928ac28 100644 --- a/main.go +++ b/main.go @@ -54,7 +54,9 @@ func main() { migration.MigrateHeadingsMaybe() shroom.SetHeaderLinks() categories.Init() - interwiki.Init() + if err := interwiki.Init(); err != nil { + os.Exit(1) + } // Static files: static.InitFS(files.StaticFiles())