From fe4fd09cee399ea412e2a7ffdd2cf949a4bc53e6 Mon Sep 17 00:00:00 2001 From: Timur Ismagilov Date: Tue, 8 Aug 2023 00:37:14 +0500 Subject: [PATCH] Interwiki: Fix some bugs * Actually, you could not edit interwiki entries before * Fix faulty template in English locale --- interwiki/interwiki.go | 86 +++++++++++++++++++++++++++++----- interwiki/view_interwiki.html | 6 ++- interwiki/view_name_taken.html | 2 +- interwiki/web.go | 40 ++++++++++++++-- viewutil/err.go | 6 +++ 5 files changed, 123 insertions(+), 17 deletions(-) diff --git a/interwiki/interwiki.go b/interwiki/interwiki.go index d90b58e..5925db3 100644 --- a/interwiki/interwiki.go +++ b/interwiki/interwiki.go @@ -29,6 +29,32 @@ func Init() { log.Printf("Loaded %d interwiki entries\n", len(listOfEntries)) } +func dropEmptyStrings(ss []string) (clean []string) { + for _, s := range ss { + if s != "" { + clean = append(clean, s) + } + } + return clean +} + +// difference returns the elements in `a` that aren't in `b`. +// Taken from https://stackoverflow.com/a/45428032 +// CC BY-SA 4.0, no changes made +func difference(a, b []string) []string { + mb := make(map[string]struct{}, len(b)) + for _, x := range b { + mb[x] = struct{}{} + } + var diff []string + for _, x := range a { + if _, found := mb[x]; !found { + diff = append(diff, x) + } + } + return diff +} + func areNamesFree(names []string) (bool, string) { for _, name := range names { if _, found := entriesByName[name]; found { @@ -40,21 +66,59 @@ func areNamesFree(names []string) (bool, string) { var mutex sync.Mutex -func addEntry(wiki *Wiki) error { +func replaceEntry(oldWiki *Wiki, newWiki *Wiki) error { + diff := difference( + append(newWiki.Aliases, newWiki.Name), + append(oldWiki.Aliases, oldWiki.Name), + ) + if ok, name := areNamesFree(diff); !ok { + return errors.New(name) + } + deleteEntry(oldWiki) + return addEntry(newWiki) +} + +func deleteEntry(wiki *Wiki) { mutex.Lock() defer mutex.Unlock() - var ( - // non-empty names only - names = func(names []string) []string { - var result []string - for _, name := range names { - if name != "" { - result = append(result, name) - } + // I'm being fancy here. Come on, the code here is already a mess. + // Let me have some fun. + var wg sync.WaitGroup + + wg.Add(2) + go func() { + names := append(wiki.Aliases, wiki.Name) + for _, name := range names { + name := name // I guess we need that + delete(entriesByName, name) + } + wg.Done() + }() + + go func() { + 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] + break } - return result - }(append(wiki.Aliases, wiki.Name)) + } + wg.Done() + }() + + wg.Wait() +} + +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 { diff --git a/interwiki/view_interwiki.html b/interwiki/view_interwiki.html index f4b57a5..6865476 100644 --- a/interwiki/view_interwiki.html +++ b/interwiki/view_interwiki.html @@ -5,6 +5,8 @@ {{define "aliases (,)"}}Aliases (separated by commas):{{end}} {{define "engine"}}Engine:{{end}} {{define "engine/mycorrhiza"}}Mycorrhiza{{end}} + {{define "engine/betula"}}Betula{{end}} + {{define "engine/agora"}}Agora{{end}} {{define "engine/generic"}}Generic (any website){{end}} {{define "url"}}URL{{end}} {{define "link href format"}}Link href attribute format string:{{end}} @@ -53,7 +55,7 @@

-

@@ -125,7 +127,7 @@

- +
{{end}} diff --git a/interwiki/view_name_taken.html b/interwiki/view_name_taken.html index f206285..b4700be 100644 --- a/interwiki/view_name_taken.html +++ b/interwiki/view_name_taken.html @@ -2,7 +2,7 @@

{{block "heading" .}}Name taken{{end}}

{{block "tip" .TakenName}}Name {{.}} is already taken, please choose a different one.{{end}}

-
+