From ac1391e64a8fdcb453560fa887ea54541cebec5e Mon Sep 17 00:00:00 2001 From: Timur Ismagilov Date: Sun, 22 May 2022 12:25:22 +0300 Subject: [PATCH] Interwiki: Start implementing --- files/files.go | 4 ++++ interwiki/interwiki.go | 49 ++++++++++++++++++++++++++++++++++++++++++ interwiki/map.go | 14 ++++++++++++ interwiki/wiki.go | 43 ++++++++++++++++++++++++++++++++++++ main.go | 1 + 5 files changed, 111 insertions(+) create mode 100644 interwiki/interwiki.go create mode 100644 interwiki/map.go create mode 100644 interwiki/wiki.go diff --git a/files/files.go b/files/files.go index f957fb6..32824a5 100644 --- a/files/files.go +++ b/files/files.go @@ -16,6 +16,7 @@ var paths struct { tokensJSON string userCredentialsJSON string categoriesJSON string + interwikiJSON string } // HyphaeDir returns the path to hyphae storage. @@ -45,6 +46,8 @@ func CategoriesJSON() string { return paths.categoriesJSON } // FileInRoot returns full path for the given filename if it was placed in the root of the wiki structure. func FileInRoot(filename string) string { return filepath.Join(cfg.WikiDir, filename) } +func InterwikiJSON() string { return paths.interwikiJSON } + // PrepareWikiRoot ensures all needed directories and files exist and have // correct permissions. func PrepareWikiRoot() error { @@ -72,6 +75,7 @@ func PrepareWikiRoot() error { paths.tokensJSON = filepath.Join(paths.cacheDir, "tokens.json") paths.categoriesJSON = filepath.Join(cfg.WikiDir, "categories.json") + paths.interwikiJSON = FileInRoot("interwiki.json") return nil } diff --git a/interwiki/interwiki.go b/interwiki/interwiki.go new file mode 100644 index 0000000..05ade08 --- /dev/null +++ b/interwiki/interwiki.go @@ -0,0 +1,49 @@ +// Package interwiki provides interwiki capabilities. Most of them, at least. +package interwiki + +import ( + "encoding/json" + "github.com/bouncepaw/mycorrhiza/files" + "log" + "os" +) + +func Init() { + var ( + record, err = readInterwiki() + ) + if err != nil { + log.Fatalln(err) + } + for _, wiki := range record { + wiki.canonize() + theMap.list = append(theMap.list, &wiki) + for _, prefix := range wiki.Names { + if _, found := theMap.byName[prefix]; found { + log.Fatalf("There are multiple interwiki map entries having the same prefix ā€˜%s’\n", prefix) + } else { + theMap.byName[prefix] = &wiki + } + } + } + log.Printf("Loaded %d interwiki entries\n", len(theMap.list)) +} + +func readInterwiki() ([]Wiki, error) { + var ( + record []Wiki + fileContents, err = os.ReadFile(files.InterwikiJSON()) + ) + if os.IsNotExist(err) { + return record, nil + } + if err != nil { + return nil, err + } + + err = json.Unmarshal(fileContents, &record) + if err != nil { + return nil, err + } + return record, nil +} diff --git a/interwiki/map.go b/interwiki/map.go new file mode 100644 index 0000000..989788a --- /dev/null +++ b/interwiki/map.go @@ -0,0 +1,14 @@ +package interwiki + +// Map is an interwiki map +type Map struct { + list []*Wiki + byName map[string]*Wiki +} + +var theMap Map + +func init() { + theMap.list = []*Wiki{} + theMap.byName = map[string]*Wiki{} +} diff --git a/interwiki/wiki.go b/interwiki/wiki.go new file mode 100644 index 0000000..49504f7 --- /dev/null +++ b/interwiki/wiki.go @@ -0,0 +1,43 @@ +package interwiki + +// WikiEngine is an enumeration of supported interwiki targets. +type WikiEngine int + +const ( + // Mycorrhiza is a Mycorrhiza wiki. This is the default value. + Mycorrhiza WikiEngine = iota + // Generic is any website. + Generic +) + +// Wiki is an entry in the interwiki map. +type Wiki struct { + // Names is a slice of link prefices that correspond to this wiki. + Names []string `json:"names"` + + // URL is the address of the wiki. + URL string `json:"url"` + + // LinkFormat is a format string for incoming interwiki links. The format strings should look like this: + // http://wiki.example.org/view/%s + // where %s is where text will be inserted. No other % instructions are supported yet. They will be added once we learn of their use cases. + // + // This field is optional. For Generic wikis, it is automatically set to /%s; for Mycorrhiza wikis, it is automatically set to /hypha/%s. + LinkFormat string `json:"link_format"` + + // Description is a plain-text description of the wiki. + Description string `json:"description"` + + // Engine is the engine of the wiki. This field is not set in JSON. + Engine WikiEngine `json:"-"` + + // EngineString is a string name of the engine. It is then converted to Engine. Supported values are: + // * mycorrhiza -> Mycorrhiza + // * generic -> Generic + // All other values will result in an error. + EngineString string `json:"engine"` +} + +func (w *Wiki) canonize() { + +} diff --git a/main.go b/main.go index 72d9a41..ad09d2a 100644 --- a/main.go +++ b/main.go @@ -51,6 +51,7 @@ func main() { migration.MigrateHeadingsMaybe() shroom.SetHeaderLinks() categories.Init() + // interwiki.Init() // Static files: static.InitFS(files.StaticFiles())