Migrate interwiki

This commit is contained in:
Timur Ismagilov 2024-09-07 22:22:50 +03:00
parent ab82ba2b73
commit c961db9fae
4 changed files with 64 additions and 35 deletions

View File

@ -4,29 +4,36 @@ package interwiki
import ( import (
"encoding/json" "encoding/json"
"errors" "errors"
"git.sr.ht/~bouncepaw/mycomarkup/v5/options" "log/slog"
"github.com/bouncepaw/mycorrhiza/internal/files"
"github.com/bouncepaw/mycorrhiza/util"
"log"
"os" "os"
"sync" "sync"
"github.com/bouncepaw/mycorrhiza/internal/files"
"github.com/bouncepaw/mycorrhiza/util"
"git.sr.ht/~bouncepaw/mycomarkup/v5/options"
) )
func Init() { func Init() error {
var ( record, err := readInterwiki()
record, err = readInterwiki()
)
if err != nil { if err != nil {
log.Fatalln(err) slog.Error("Failed to read interwiki", "err", err)
return err
} }
for _, wiki := range record { for _, wiki := range record {
wiki := wiki // This line is required wiki := wiki // This line is required
wiki.canonize() if err := wiki.canonize(); err != nil {
return err
}
if err := addEntry(&wiki); err != nil { 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) { func dropEmptyStrings(ss []string) (clean []string) {
@ -100,7 +107,6 @@ func deleteEntry(wiki *Wiki) {
for i, w := range listOfEntries { for i, w := range listOfEntries {
i, w := i, w i, w := i, w
if w.Name == wiki.Name { if w.Name == wiki.Name {
log.Println("It came to delete")
// Drop ith element. // Drop ith element.
listOfEntries[i] = listOfEntries[len(listOfEntries)-1] listOfEntries[i] = listOfEntries[len(listOfEntries)-1]
listOfEntries = listOfEntries[:len(listOfEntries)-1] listOfEntries = listOfEntries[:len(listOfEntries)-1]
@ -113,21 +119,22 @@ func deleteEntry(wiki *Wiki) {
wg.Wait() wg.Wait()
} }
// TODO: There is something clearly wrong with error-returning in this function.
func addEntry(wiki *Wiki) error { func addEntry(wiki *Wiki) error {
mutex.Lock() mutex.Lock()
defer mutex.Unlock() defer mutex.Unlock()
wiki.Aliases = dropEmptyStrings(wiki.Aliases) wiki.Aliases = dropEmptyStrings(wiki.Aliases)
var ( var (
names = append(wiki.Aliases, wiki.Name) names = append(wiki.Aliases, wiki.Name)
ok, name = areNamesFree(names) ok, name = areNamesFree(names)
) )
if !ok { switch {
log.Printf("There are multiple uses of the same name %s\n", name) case !ok:
slog.Error("There are multiple uses of the same name", "name", name)
return errors.New(name) return errors.New(name)
} case len(names) == 0:
if len(names) == 0 { slog.Error("No names passed for a new interwiki entry")
log.Println("No names passed for a new interwiki entry")
// There is something clearly wrong with error-returning in this function.
return errors.New("") return errors.New("")
} }
@ -176,10 +183,13 @@ func readInterwiki() ([]Wiki, error) {
func saveInterwikiJson() { func saveInterwikiJson() {
// Trust me, wiki crashing when an admin takes an administrative action totally makes sense. // Trust me, wiki crashing when an admin takes an administrative action totally makes sense.
if data, err := json.MarshalIndent(listOfEntries, "", "\t"); err != nil { 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 { } else if err = os.WriteFile(files.InterwikiJSON(), data, 0666); err != nil {
log.Fatalln(err) slog.Error("Failed to write interwiki.json", "err", err)
} else { os.Exit(1)
log.Println("Saved interwiki.json")
} }
slog.Info("Saved interwiki.json")
} }

View File

@ -2,11 +2,13 @@ package interwiki
import ( import (
"embed" "embed"
"github.com/bouncepaw/mycorrhiza/web/viewutil" "log/slog"
"github.com/gorilla/mux"
"log"
"net/http" "net/http"
"strings" "strings"
"github.com/bouncepaw/mycorrhiza/web/viewutil"
"github.com/gorilla/mux"
) )
var ( var (
@ -63,19 +65,24 @@ func handlerModifyEntry(w http.ResponseWriter, rq *http.Request) {
) )
if oldData, ok = entriesByName[name]; !ok { 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) viewutil.HandlerNotFound(w, rq)
return return
} }
if err := replaceEntry(oldData, &newData); err != nil { 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) viewNameTaken(viewutil.MetaFrom(w, rq), oldData, err.Error(), "modify-entry/"+name)
return return
} }
saveInterwikiJson() saveInterwikiJson()
log.Printf("Modified interwiki entry %s\n", name) slog.Info("Modified entry", "name", name)
http.Redirect(w, rq, "/interwiki", http.StatusSeeOther) http.Redirect(w, rq, "/interwiki", http.StatusSeeOther)
} }

View File

@ -1,9 +1,11 @@
package interwiki package interwiki
import ( import (
"errors"
"fmt" "fmt"
"log/slog"
"github.com/bouncepaw/mycorrhiza/util" "github.com/bouncepaw/mycorrhiza/util"
"log"
) )
// WikiEngine is an enumeration of supported interwiki targets. // WikiEngine is an enumeration of supported interwiki targets.
@ -47,14 +49,20 @@ type Wiki struct {
Engine WikiEngine `json:"engine"` Engine WikiEngine `json:"engine"`
} }
func (w *Wiki) canonize() { func (w *Wiki) canonize() error {
switch { switch {
case w.Name == "": 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 == "": 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(): 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) w.Name = util.CanonicalName(w.Name)
@ -83,4 +91,6 @@ func (w *Wiki) canonize() {
w.ImgSrcFormat = fmt.Sprintf("%s/{NAME}", w.URL) w.ImgSrcFormat = fmt.Sprintf("%s/{NAME}", w.URL)
} }
} }
return nil
} }

View File

@ -54,7 +54,9 @@ func main() {
migration.MigrateHeadingsMaybe() migration.MigrateHeadingsMaybe()
shroom.SetHeaderLinks() shroom.SetHeaderLinks()
categories.Init() categories.Init()
interwiki.Init() if err := interwiki.Init(); err != nil {
os.Exit(1)
}
// Static files: // Static files:
static.InitFS(files.StaticFiles()) static.InitFS(files.StaticFiles())