2021-07-05 04:11:45 +00:00
// Package cfg contains global variables that represent the current wiki
// configuration, including CLI options, configuration file values and header
// links.
2021-05-09 09:36:39 +00:00
package cfg
2021-03-06 09:40:47 +00:00
import (
2021-06-19 16:48:54 +00:00
"errors"
2021-06-19 17:00:28 +00:00
"fmt"
2021-06-19 16:48:54 +00:00
"os"
2022-02-03 18:52:56 +00:00
"strings"
2021-03-06 09:40:47 +00:00
"github.com/go-ini/ini"
)
2021-06-19 16:48:54 +00:00
// These variables represent the configuration. You are not meant to modify
// them after they were set.
2021-07-05 04:22:17 +00:00
// See https://mycorrhiza.wiki/hypha/configuration/fields for the
2021-06-19 16:48:54 +00:00
// documentation.
2021-05-09 09:36:39 +00:00
var (
2022-02-19 09:54:20 +00:00
WikiName string
NaviTitleIcon string
UseSiblingHyphaeSidebar bool
2021-05-09 09:36:39 +00:00
2022-07-01 15:51:22 +00:00
HomeHypha string
UserHypha string
HeaderLinksHypha string
RedirectionCategory string
2021-05-09 09:36:39 +00:00
2021-07-10 19:04:21 +00:00
ListenAddr string
URL string
2021-05-09 09:36:39 +00:00
2021-07-02 08:20:03 +00:00
UseAuth bool
AllowRegistration bool
RegistrationLimit uint64
2021-07-10 19:04:21 +00:00
Locked bool
2021-07-15 17:46:35 +00:00
UseWhiteList bool
WhiteList [ ] string
2021-05-22 18:05:14 +00:00
2021-07-01 09:45:29 +00:00
CommonScripts [ ] string
ViewScripts [ ] string
EditScripts [ ] string
2021-07-14 19:51:55 +00:00
// TelegramEnabled if both TelegramBotToken and TelegramBotName are not empty strings.
2021-07-15 17:46:35 +00:00
TelegramEnabled bool
2021-07-14 19:51:55 +00:00
TelegramBotToken string
2021-07-15 17:46:35 +00:00
TelegramBotName string
2021-05-09 09:36:39 +00:00
)
2021-06-19 16:48:54 +00:00
// WikiDir is a full path to the wiki storage directory, which also must be a
// git repo. This variable is set in parseCliArgs().
var WikiDir string
2021-05-11 08:33:00 +00:00
2021-06-19 16:48:54 +00:00
// Config represents a Mycorrhiza wiki configuration file. This type is used
// only when reading configs.
2021-03-06 09:40:47 +00:00
type Config struct {
2022-02-19 09:54:20 +00:00
WikiName string ` comment:"This name appears in the header and on various pages." `
NaviTitleIcon string ` comment:"This icon is used in the breadcrumbs bar." `
UseSiblingHyphaeSidebar bool ` comment:"You are discouraged from using the sibling hyphae sidebar on new wikis. Enable it on old wikis that depend on it heavily." `
2021-03-06 09:40:47 +00:00
Hyphae
Network
2021-07-05 04:11:45 +00:00
Authorization
2021-06-19 16:48:54 +00:00
CustomScripts ` comment:"You can specify additional scripts to load on different kinds of pages, delimited by a comma ',' sign." `
2021-07-15 17:46:35 +00:00
Telegram ` comment:"You can enable Telegram authorization. Follow these instructions: https://core.telegram.org/widgets/login#setting-up-a-bot" `
2021-03-06 09:40:47 +00:00
}
2021-05-09 09:36:39 +00:00
// Hyphae is a section of Config which has fields related to special hyphae.
2021-03-06 09:40:47 +00:00
type Hyphae struct {
2022-07-01 15:51:22 +00:00
HomeHypha string ` comment:"This hypha will be the main (index) page of your wiki, served on /." `
UserHypha string ` comment:"This hypha is used as a prefix for user hyphae." `
HeaderLinksHypha string ` comment:"You can also specify a hypha to populate your own custom header links from." `
RedirectionCategory string ` comment:"Redirection hyphae will be added to this category. Default: redirection." `
2021-03-06 09:40:47 +00:00
}
2022-02-19 09:54:20 +00:00
// Network is a section of Config that has fields related to network stuff.
2021-03-06 09:40:47 +00:00
type Network struct {
2021-07-05 14:35:27 +00:00
ListenAddr string
URL string ` comment:"Set your wiki's public URL here. It's used for OpenGraph generation and syndication feeds." `
2021-03-06 09:40:47 +00:00
}
2021-06-19 16:48:54 +00:00
// CustomScripts is a section with paths to JavaScript files that are loaded on
// specified pages.
2021-05-22 18:05:14 +00:00
type CustomScripts struct {
2021-07-01 09:45:29 +00:00
// CommonScripts: everywhere...
CommonScripts [ ] string ` delim:"," comment:"These scripts are loaded from anywhere." `
2021-05-22 18:05:14 +00:00
// ViewScripts: /hypha, /rev
2021-06-19 16:48:54 +00:00
ViewScripts [ ] string ` delim:"," comment:"These scripts are only loaded on view pages." `
2021-05-22 18:05:14 +00:00
// Edit: /edit
2021-06-19 16:48:54 +00:00
EditScripts [ ] string ` delim:"," comment:"These scripts are only loaded on the edit page." `
2021-05-22 18:05:14 +00:00
}
2021-06-19 16:48:54 +00:00
// Authorization is a section of Config that has fields related to
// authorization and authentication.
2021-03-06 09:40:47 +00:00
type Authorization struct {
2021-07-02 08:20:03 +00:00
UseAuth bool
AllowRegistration bool
2021-07-15 17:46:35 +00:00
RegistrationLimit uint64 ` comment:"This field controls the maximum amount of allowed registrations." `
Locked bool ` comment:"Set if users have to authorize to see anything on the wiki." `
UseWhiteList bool ` comment:"If true, WhiteList is used. Else it is not used." `
WhiteList [ ] string ` delim:"," comment:"Usernames of people who can log in to your wiki separated by comma." `
2022-02-19 09:54:20 +00:00
// TODO: let admins enable auth-less editing
2021-03-06 09:40:47 +00:00
}
2021-07-14 19:51:55 +00:00
// Telegram is the section of Config that sets Telegram authorization.
type Telegram struct {
2021-10-29 09:27:12 +00:00
TelegramBotToken string ` comment:"Token of your bot." `
TelegramBotName string ` comment:"Username of your bot, sans @." `
2021-07-14 19:51:55 +00:00
}
2021-06-19 16:48:54 +00:00
// ReadConfigFile reads a config on the given path and stores the
// configuration. Call it sometime during the initialization.
2021-06-19 17:00:28 +00:00
func ReadConfigFile ( path string ) error {
2021-03-06 09:40:47 +00:00
cfg := & Config {
2022-02-19 09:54:20 +00:00
WikiName : "Mycorrhiza Wiki" ,
NaviTitleIcon : "🍄" ,
UseSiblingHyphaeSidebar : false ,
2021-03-06 09:40:47 +00:00
Hyphae : Hyphae {
2022-07-01 15:51:22 +00:00
HomeHypha : "home" ,
UserHypha : "u" ,
HeaderLinksHypha : "" ,
RedirectionCategory : "redirection" ,
2021-03-06 09:40:47 +00:00
} ,
Network : Network {
2021-07-05 14:35:27 +00:00
ListenAddr : "127.0.0.1:1737" ,
URL : "" ,
2021-03-06 09:40:47 +00:00
} ,
Authorization : Authorization {
2021-07-02 08:20:03 +00:00
UseAuth : false ,
AllowRegistration : false ,
RegistrationLimit : 0 ,
2021-07-10 19:04:21 +00:00
Locked : false ,
2021-07-15 17:46:35 +00:00
UseWhiteList : false ,
WhiteList : [ ] string { } ,
2021-03-06 09:40:47 +00:00
} ,
2021-05-22 18:05:14 +00:00
CustomScripts : CustomScripts {
2021-07-01 09:45:29 +00:00
CommonScripts : [ ] string { } ,
ViewScripts : [ ] string { } ,
EditScripts : [ ] string { } ,
2021-05-22 18:05:14 +00:00
} ,
2021-07-14 19:51:55 +00:00
Telegram : Telegram {
TelegramBotToken : "" ,
2021-07-15 17:46:35 +00:00
TelegramBotName : "" ,
2021-07-14 19:51:55 +00:00
} ,
2021-03-06 09:40:47 +00:00
}
2021-03-09 14:27:14 +00:00
2021-06-19 16:48:54 +00:00
f , err := ini . Load ( path )
if err != nil {
if errors . Is ( err , os . ErrNotExist ) {
f = ini . Empty ( )
2021-07-05 04:11:45 +00:00
// Save the default configuration
err = f . ReflectFrom ( cfg )
if err != nil {
return fmt . Errorf ( "Failed to serialize the config: %w" , err )
}
// Disable key-value auto-aligning, but retain spaces around '=' sign
ini . PrettyFormat = false
ini . PrettyEqual = true
if err = f . SaveTo ( path ) ; err != nil {
return fmt . Errorf ( "Failed to save the config file: %w" , err )
}
2021-06-19 16:48:54 +00:00
} else {
2021-06-19 17:00:28 +00:00
return fmt . Errorf ( "Failed to open the config file: %w" , err )
2021-06-19 16:48:54 +00:00
}
}
// Map the config file to the config struct. It'll do nothing if the file
// doesn't exist or is empty.
2021-07-10 19:04:21 +00:00
if err := f . MapTo ( cfg ) ; err != nil {
return err
}
2021-06-19 16:48:54 +00:00
2021-04-12 14:26:49 +00:00
// Map the struct to the global variables
2021-05-09 09:36:39 +00:00
WikiName = cfg . WikiName
NaviTitleIcon = cfg . NaviTitleIcon
2022-02-19 09:54:20 +00:00
UseSiblingHyphaeSidebar = cfg . UseSiblingHyphaeSidebar
2021-05-09 09:36:39 +00:00
HomeHypha = cfg . HomeHypha
2021-03-06 09:40:47 +00:00
UserHypha = cfg . UserHypha
HeaderLinksHypha = cfg . HeaderLinksHypha
2022-07-01 15:51:22 +00:00
RedirectionCategory = cfg . RedirectionCategory
2021-07-05 19:47:07 +00:00
if ListenAddr == "" {
ListenAddr = cfg . ListenAddr
}
2021-03-06 09:40:47 +00:00
URL = cfg . URL
2021-07-02 08:20:03 +00:00
UseAuth = cfg . UseAuth
AllowRegistration = cfg . AllowRegistration
RegistrationLimit = cfg . RegistrationLimit
2021-07-10 19:04:21 +00:00
Locked = cfg . Locked && cfg . UseAuth // Makes no sense to have the lock but no auth
2021-07-14 21:30:30 +00:00
UseWhiteList = cfg . UseWhiteList
WhiteList = cfg . WhiteList
2021-07-01 09:45:29 +00:00
CommonScripts = cfg . CommonScripts
2021-05-22 18:05:14 +00:00
ViewScripts = cfg . ViewScripts
EditScripts = cfg . EditScripts
2021-07-14 19:51:55 +00:00
TelegramBotToken = cfg . TelegramBotToken
TelegramBotName = cfg . TelegramBotName
TelegramEnabled = ( TelegramBotToken != "" ) && ( TelegramBotName != "" )
2021-05-11 08:33:00 +00:00
2022-02-03 18:52:56 +00:00
// This URL makes much more sense. If no URL is set or the protocol is forgotten, assume HTTP.
2022-06-24 13:15:27 +00:00
if URL == "" {
2021-07-05 14:35:27 +00:00
URL = "http://" + ListenAddr
2022-06-24 13:15:27 +00:00
} else if ! strings . Contains ( URL , ":" ) {
URL = "http://" + URL
2021-05-11 08:33:00 +00:00
}
2021-06-19 17:00:28 +00:00
return nil
2021-03-06 09:40:47 +00:00
}