]> Sergey Matveev's repositories - sgblog.git/blobdiff - cmd/sgblog/main.go
Images support
[sgblog.git] / cmd / sgblog / main.go
index ef3ff45d0128cf97c112c994f222e8e76a21553a..a7613021a61eb2491f66af3af73682fdb85a0885 100644 (file)
@@ -1,6 +1,6 @@
 /*
-SGBlog -- Git-backed CGI/inetd blogging/phlogging engine
-Copyright (C) 2020-2021 Sergey Matveev <stargrave@stargrave.org>
+SGBlog -- Git-backed CGI/UCSPI blogging/phlogging/gemlogging engine
+Copyright (C) 2020-2023 Sergey Matveev <stargrave@stargrave.org>
 
 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU Affero General Public License as
@@ -15,15 +15,18 @@ You should have received a copy of the GNU Affero General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-// Git-backed CGI/inetd blogging/phlogging engine
+// Git-backed CGI/UCSPI blogging/phlogging/gemlogging engine
 package main
 
 import (
        "crypto/sha1"
+       "embed"
        "encoding/json"
        "flag"
        "fmt"
-       "io/ioutil"
+       "io/fs"
+       "log"
+       "os"
        "regexp"
        "strings"
 
@@ -31,6 +34,8 @@ import (
        "github.com/go-git/go-git/v5/plumbing"
        "github.com/go-git/go-git/v5/plumbing/object"
        "github.com/hjson/hjson-go"
+       "github.com/vorlif/spreak"
+       "golang.org/x/text/language"
 )
 
 const (
@@ -45,12 +50,18 @@ var (
        commentsTree *object.Tree
        topicsRef    *plumbing.Reference
        topicsTree   *object.Tree
+
+       localizer *spreak.Localizer
+
+       //go:embed locale/*
+       locales embed.FS
 )
 
 type Cfg struct {
        GitPath string
        Branch  string
        Title   string
+       Lang    string
 
        URLPrefix string
 
@@ -70,6 +81,9 @@ type Cfg struct {
        TopicsCachePath string
 
        GopherDomain string
+
+       ImgPath   string
+       ImgDomain string
 }
 
 func msgSplit(msg string) []string {
@@ -125,7 +139,7 @@ func initRepo(cfg *Cfg) (*plumbing.Hash, error) {
 }
 
 func readCfg(cfgPath string) (*Cfg, error) {
-       cfgRaw, err := ioutil.ReadFile(cfgPath)
+       cfgRaw, err := os.ReadFile(cfgPath)
        if err != nil {
                return nil, err
        }
@@ -144,17 +158,38 @@ func readCfg(cfgPath string) (*Cfg, error) {
        return cfg, nil
 }
 
+func initLocalizer(lang string) {
+       fsys, _ := fs.Sub(locales, "locale")
+       bundle, err := spreak.NewBundle(
+               spreak.WithSourceLanguage(language.English),
+               spreak.WithDomainFs(spreak.NoDomain, fsys),
+               spreak.WithLanguage(language.Russian),
+       )
+       if err != nil {
+               log.Fatalln(err)
+       }
+       if lang == "" {
+               lang = language.English.String()
+       }
+       localizer = spreak.NewLocalizer(bundle, language.MustParse(lang))
+}
+
 func main() {
        gopherCfgPath := flag.String("gopher", "", "Path to gopher-related configuration file")
+       geminiCfgPath := flag.String("gemini", "", "Path to gemini-related configuration file")
        flag.Usage = func() {
                fmt.Fprintf(flag.CommandLine.Output(), `Usage of sgblog:
        sgblog -- run CGI HTTP backend
        sgblog -gopher /path/to/cfg.hjson -- run UCSPI/inetd Gopher backend
+       sgblog -gemini /path/to/cfg.hjson -- run UCSPI+tlss Gemini backend
 `)
        }
        flag.Parse()
+       log.SetFlags(log.Lshortfile)
        if *gopherCfgPath != "" {
                serveGopher(*gopherCfgPath)
+       } else if *geminiCfgPath != "" {
+               serveGemini(*geminiCfgPath)
        } else {
                serveHTTP()
        }