1
0
mirror of https://github.com/osmarks/mycorrhiza.git synced 2025-01-06 10:00:26 +00:00

Refactor and document some stuff

This commit is contained in:
Timur Ismagilov 2021-05-11 13:33:00 +05:00
parent d69ce77251
commit a1852d363e
18 changed files with 141 additions and 101 deletions

View File

@ -2,5 +2,9 @@
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="CssUnknownTarget" enabled="true" level="WEAK WARNING" enabled_by_default="true" />
<inspection_tool class="NonAsciiCharacters" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="CHECK_FOR_NOT_ASCII_IDENTIFIER_NAME" value="false" />
<option name="CHECK_FOR_DIFFERENT_LANGUAGES_IN_IDENTIFIER_NAME" value="false" />
</inspection_tool>
</profile>
</component>

View File

@ -1,3 +1,4 @@
// Package cfg contains global variables that represent the current wiki configuration, including CLI options, configuration file values and header links.
package cfg
import (
@ -8,6 +9,9 @@ import (
"github.com/go-ini/ini"
)
// These variables represent the configuration. You are not meant to modify them after they were set.
//
// See https://mycorrhiza.lesarbr.es/hypha/configuration/fields for their docs.
var (
WikiName string
NaviTitleIcon string
@ -20,9 +24,6 @@ var (
URL string
GeminiCertificatePath string
WikiDir string
ConfigFilePath string
UseFixedAuth bool
FixedAuthCredentialsPath string
UseRegistration bool
@ -30,9 +31,15 @@ var (
LimitRegistration int
)
// Config represents a Mycorrhiza wiki configuration file.
//
// See https://mycorrhiza.lesarbr.es/hypha/configuration/fields for fields' docs.
// These variables are set before reading the config file, they are set in main.parseCliArgs.
var (
// WikiDir is a full path to the wiki storage directory, which also must be a git repo.
WikiDir string
// ConfigFilePath is a path to the config file. Its value is used when calling ReadConfigFile.
ConfigFilePath string
)
// Config represents a Mycorrhiza wiki configuration file. This type is used only when reading configs.
type Config struct {
WikiName string
NaviTitleIcon string
@ -65,8 +72,10 @@ type Authorization struct {
LimitRegistration uint64
}
// ReadConfigFile reads a config on the given path and stores the configuration.
func ReadConfigFile(path string) {
// ReadConfigFile reads a config on the given path and stores the configuration. Call it sometime during the initialization.
//
// Note that it may log.Fatal.
func ReadConfigFile() {
cfg := &Config{
WikiName: "MycorrhizaWiki",
NaviTitleIcon: "🍄",
@ -90,8 +99,8 @@ func ReadConfigFile(path string) {
},
}
if path != "" {
path, err := filepath.Abs(path)
if ConfigFilePath != "" {
path, err := filepath.Abs(ConfigFilePath)
if err != nil {
log.Fatalf("cannot expand config file path: %s", err)
}
@ -117,4 +126,9 @@ func ReadConfigFile(path string) {
UseRegistration = cfg.UseRegistration
RegistrationCredentialsPath = cfg.RegistrationCredentialsPath
LimitRegistration = int(cfg.LimitRegistration)
// This URL makes much more sense.
if URL == "" {
URL = "http://0.0.0.0:" + HTTPPort
}
}

48
cfg/header_links.go Normal file
View File

@ -0,0 +1,48 @@
package cfg
// See https://mycorrhiza.lesarbr.es/hypha/configuration/header
import (
"strings"
)
// HeaderLinks is a list off current header links. Feel free to iterate it directly but do not modify it by yourself. Call ParseHeaderLinks if you need to set new header links.
var HeaderLinks []HeaderLink
// SetDefaultHeaderLinks sets the header links to the default list of: home hypha, recent changes, hyphae list, random hypha.
func SetDefaultHeaderLinks() {
HeaderLinks = []HeaderLink{
{"/", WikiName},
{"/recent-changes", "Recent changes"},
{"/list", "All hyphae"},
{"/random", "Random"},
}
}
// ParseHeaderLinks extracts all rocketlinks from the given text and saves them as header links. rocketlinkλ must be set to markup.Rocketlink. You have to pass it like that to avoid cyclical dependency.
func ParseHeaderLinks(text string, rocketlinkλ func(string, string) (string, string, string)) {
HeaderLinks = []HeaderLink{}
for _, line := range strings.Split(text, "\n") {
// There is a false positive when parsing markup like that:
//
// ```
// => this is not a link, it is part of the preformatted block
// ```
//
// I do not really care.
if strings.HasPrefix(line, "=>") {
href, display, _ := rocketlinkλ(line, HeaderLinksHypha)
HeaderLinks = append(HeaderLinks, HeaderLink{
Href: href,
Display: display,
})
}
}
}
// HeaderLink represents a header link. Header links are the links shown in the top gray bar.
type HeaderLink struct {
// Href is the URL of the link. It goes <a href="here">...</a>.
Href string
// Display is what is shown when the link is rendered. It goes <a href="...">here</a>.
Display string
}

View File

@ -1,3 +1,4 @@
// Package files is used to get paths to different files Mycorrhiza uses. Also see cfg.
package files
import (
@ -17,9 +18,20 @@ var paths struct {
fixedCredentialsJSON string
}
func TokensJSON() string { return paths.tokensJSON }
// TokensJSON returns a path to the JSON file where users' tokens are stored.
//
// Default path: $XDG_DATA_HOME/mycorrhiza/tokens.json
func TokensJSON() string { return paths.tokensJSON }
// RegistrationCredentialsJSON returns a path to the JSON file where registration credentials are stored.
//
// Default path: $XDG_DATA_HOME/mycorrhiza/registration.json
func RegistrationCredentialsJSON() string { return paths.registrationCredentialsJSON }
func FixedCredentialsJSON() string { return paths.fixedCredentialsJSON }
// FixedCredentialsJSON returns a path to the JSON file where fixed credentials are stored.
//
// There is no default path.
func FixedCredentialsJSON() string { return paths.fixedCredentialsJSON }
// CalculatePaths looks for all external paths and stores them. Tries its best to find any errors. It is safe it to call it multiple times in order to save new paths.
func CalculatePaths() error {

35
flag.go
View File

@ -9,25 +9,32 @@ import (
"path/filepath"
"github.com/bouncepaw/mycorrhiza/assets"
"github.com/bouncepaw/mycorrhiza/util"
)
// CLI options are read and parsed here.
var printExampleConfig bool
func init() {
flag.StringVar(&cfg.ConfigFilePath, "config-path", "", "Path to a configuration file. Leave empty if you don't want to use it.")
flag.BoolVar(&printExampleConfig, "print-example-config", false, "If true, print an example configuration file contents and exit. You can save the output to a file and base your own configuration on it.")
flag.Usage = func() {
fmt.Fprintf(
flag.CommandLine.Output(),
assets.HelpMessage(),
os.Args[0],
)
flag.PrintDefaults()
}
flag.Usage = printHelp
}
// Do the things related to cli args and die maybe
// printHelp prints the help message. The help message is stored in assets.
func printHelp() {
_, err := fmt.Fprintf(
flag.CommandLine.Output(),
assets.HelpMessage(),
os.Args[0],
)
if err != nil {
log.Fatal(err)
}
flag.PrintDefaults()
}
// parseCliArgs parses CLI options and sets several important global variables. Call it early.
func parseCliArgs() {
flag.Parse()
@ -46,12 +53,4 @@ func parseCliArgs() {
if err != nil {
log.Fatal(err)
}
if cfg.URL == "" {
cfg.URL = "http://0.0.0.0:" + cfg.HTTPPort
}
cfg.HomeHypha = util.CanonicalName(cfg.HomeHypha)
cfg.UserHypha = util.CanonicalName(cfg.UserHypha)
cfg.HeaderLinksHypha = util.CanonicalName(cfg.HeaderLinksHypha)
}

View File

@ -1,29 +1,37 @@
package main
// Gemini-related stuff. This is currently a proof-of-concept implementation, no one really uses it.
// Maybe we should deprecate it until we find power to do it properly?
//
// When this stuff gets more serious, a separate module will be needed.
import (
"crypto/tls"
"crypto/x509/pkix"
"github.com/bouncepaw/mycorrhiza/cfg"
"io"
"io/ioutil"
"log"
"path/filepath"
"strings"
"time"
"git.sr.ht/~adnano/go-gemini"
"git.sr.ht/~adnano/go-gemini/certificate"
"github.com/bouncepaw/mycorrhiza/cfg"
"github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/markup"
"github.com/bouncepaw/mycorrhiza/util"
)
func geminiHomeHypha(w *gemini.ResponseWriter, rq *gemini.Request) {
log.Println(rq.URL)
w.Write([]byte(`# MycorrhizaWiki
_, _ = io.WriteString(w, `# MycorrhizaWiki
You have successfully served the wiki through Gemini. Currently, support is really work-in-progress; you should resort to using Mycorrhiza through the web protocols.
Visit home hypha:
=> /hypha/` + cfg.HomeHypha))
=> /hypha/`+cfg.HomeHypha)
}
func geminiHypha(w *gemini.ResponseWriter, rq *gemini.Request) {
@ -42,9 +50,9 @@ func geminiHypha(w *gemini.ResponseWriter, rq *gemini.Request) {
}
}
if hasAmnt {
w.Write([]byte("This hypha has an attachment\n"))
_, _ = io.WriteString(w, "This hypha has an attachment\n")
}
w.Write([]byte(contents))
_, _ = io.WriteString(w, contents)
}
func handleGemini() {
@ -82,3 +90,15 @@ func handleGemini() {
log.Fatal(err)
}
}
// geminiHyphaNameFromRq extracts hypha name from gemini request. You have to also pass the action which is embedded in the url or several actions. For url /hypha/hypha, the action would be "hypha".
func geminiHyphaNameFromRq(rq *gemini.Request, actions ...string) string {
p := rq.URL.Path
for _, action := range actions {
if strings.HasPrefix(p, "/"+action+"/") {
return util.CanonicalName(strings.TrimPrefix(p, "/"+action+"/"))
}
}
log.Fatal("HyphaNameFromRq: no matching action passed")
return ""
}

View File

@ -2,6 +2,7 @@
//go:generate qtc -dir=assets
//go:generate qtc -dir=views
//go:generate qtc -dir=tree
// Command mycorrhiza is a program that runs a mycorrhiza wiki.
package main
import (
@ -21,7 +22,7 @@ func main() {
parseCliArgs()
// It is ok if the path is ""
cfg.ReadConfigFile(cfg.ConfigFilePath)
cfg.ReadConfigFile()
if err := files.CalculatePaths(); err != nil {
log.Fatal(err)

22
name.go
View File

@ -1,22 +0,0 @@
package main
import (
"log"
"strings"
"git.sr.ht/~adnano/go-gemini"
"github.com/bouncepaw/mycorrhiza/util"
)
// geminiHyphaNameFromRq extracts hypha name from gemini request. You have to also pass the action which is embedded in the url or several actions. For url /hypha/hypha, the action would be "hypha".
func geminiHyphaNameFromRq(rq *gemini.Request, actions ...string) string {
p := rq.URL.Path
for _, action := range actions {
if strings.HasPrefix(p, "/"+action+"/") {
return util.CanonicalName(strings.TrimPrefix(p, "/"+action+"/"))
}
}
log.Fatal("HyphaNameFromRq: no matching action passed")
return ""
}

View File

@ -7,7 +7,6 @@ import (
"github.com/bouncepaw/mycorrhiza/hyphae"
"github.com/bouncepaw/mycorrhiza/markup"
"github.com/bouncepaw/mycorrhiza/util"
)
// FetchTextPart tries to read text file of the given hypha. If there is no file, empty string is returned.
@ -26,14 +25,14 @@ func FetchTextPart(h *hyphae.Hypha) (string, error) {
func SetHeaderLinks() {
if userLinksHypha := hyphae.ByName(cfg.HeaderLinksHypha); !userLinksHypha.Exists {
util.SetDefaultHeaderLinks()
cfg.SetDefaultHeaderLinks()
} else {
contents, err := ioutil.ReadFile(userLinksHypha.TextPath)
if err != nil || len(contents) == 0 {
util.SetDefaultHeaderLinks()
cfg.SetDefaultHeaderLinks()
} else {
text := string(contents)
util.ParseHeaderLinks(text, markup.Rocketlink)
cfg.ParseHeaderLinks(text, markup.Rocketlink)
}
}
}

View File

@ -1,36 +0,0 @@
package util
import (
"github.com/bouncepaw/mycorrhiza/cfg"
"strings"
)
func SetDefaultHeaderLinks() {
HeaderLinks = []HeaderLink{
{"/", cfg.WikiName},
{"/recent-changes", "Recent changes"},
{"/list", "All hyphae"},
{"/random", "Random"},
}
}
// rocketlinkλ is markup.Rocketlink. You have to pass it like that to avoid cyclical dependency.
func ParseHeaderLinks(text string, rocketlinkλ func(string, string) (string, string, string)) {
HeaderLinks = []HeaderLink{}
for _, line := range strings.Split(text, "\n") {
if strings.HasPrefix(line, "=>") {
href, text, _ := rocketlinkλ(line, cfg.HeaderLinksHypha)
HeaderLinks = append(HeaderLinks, HeaderLink{
Href: href,
Display: text,
})
}
}
}
type HeaderLink struct {
Href string
Display string
}
var HeaderLinks []HeaderLink

View File

@ -3,12 +3,13 @@ package util
import (
"crypto/rand"
"encoding/hex"
"github.com/bouncepaw/mycorrhiza/cfg"
"log"
"net/http"
"regexp"
"strings"
"unicode"
"github.com/bouncepaw/mycorrhiza/cfg"
)
func PrepareRq(rq *http.Request) {

View File

@ -63,7 +63,7 @@ func StreamBaseHTML(qw422016 *qt422016.Writer, title, body string, u *user.User,
<ul class="header-links__list">
`)
//line views/stuff.qtpl:21
for _, link := range util.HeaderLinks {
for _, link := range cfg.HeaderLinks {
//line views/stuff.qtpl:21
qw422016.N().S(` <li class="header-links__entry"><a class="header-links__link" href="`)
//line views/stuff.qtpl:22

View File

@ -1,6 +1,6 @@
// http_stuff.go is used for meta stuff about the wiki or all hyphae at once.
package web
// stuff.go is used for meta stuff about the wiki or all hyphae at once.
import (
"github.com/bouncepaw/mycorrhiza/cfg"
"io"