]> Sergey Matveev's repositories - sgblog.git/blobdiff - cmd/sgblog/main.go
Use external recfiles parser library
[sgblog.git] / cmd / sgblog / main.go
index f3d009ab464181d04d5df45e031da49dda66f6ff..f5b45823510e36a62f025335e741e22d0ecc8339 100644 (file)
@@ -1,5 +1,5 @@
 /*
-SGBlog -- Git-based CGI blogging engine
+SGBlog -- Git-backed CGI/inetd blogging/phlogging engine
 Copyright (C) 2020 Sergey Matveev <stargrave@stargrave.org>
 
 This program is free software: you can redistribute it and/or modify
@@ -15,20 +15,24 @@ 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-based CGI blogging engine
+// Git-backed CGI/inetd blogging/phlogging engine
 package main
 
 import (
        "bytes"
+       "crypto/sha1"
+       "fmt"
        "io/ioutil"
        "os"
        "regexp"
+       "sort"
        "strings"
+       "text/scanner"
 
-       "go.cypherpunks.ru/netstring/v2"
-       "gopkg.in/src-d/go-git.v4"
-       "gopkg.in/src-d/go-git.v4/plumbing"
-       "gopkg.in/src-d/go-git.v4/plumbing/object"
+       "github.com/go-git/go-git/v5"
+       "github.com/go-git/go-git/v5/plumbing"
+       "github.com/go-git/go-git/v5/plumbing/object"
+       "go.cypherpunks.ru/recfile"
 )
 
 const (
@@ -36,10 +40,13 @@ const (
 )
 
 var (
-       sha1DigestRe = regexp.MustCompilePOSIX("([0-9a-f]{40,40})")
+       sha1DigestRe = regexp.MustCompilePOSIX(fmt.Sprintf("([0-9a-f]{%d,%d})", sha1.Size*2, sha1.Size*2))
        repo         *git.Repository
        notesTree    *object.Tree
+       commentsRef  *plumbing.Reference
        commentsTree *object.Tree
+       topicsRef    *plumbing.Reference
+       topicsTree   *object.Tree
 )
 
 type Cfg struct {
@@ -61,6 +68,9 @@ type Cfg struct {
        CommentsNotesRef string
        CommentsEmail    string
 
+       TopicsNotesRef  string
+       TopicsCachePath string
+
        GopherDomain string
 }
 
@@ -109,18 +119,39 @@ func getNote(tree *object.Tree, what plumbing.Hash) []byte {
 
 func parseComments(data []byte) []string {
        comments := []string{}
-       nsr := netstring.NewReader(bytes.NewReader(data))
+       r := recfile.NewReader(bytes.NewReader(data))
        for {
-               if _, err := nsr.Next(); err != nil {
+               fields, err := r.Next()
+               if err != nil {
                        break
                }
-               if comment, err := ioutil.ReadAll(nsr); err == nil {
-                       comments = append(comments, string(comment))
+               if len(fields) != 3 ||
+                       fields[0].Name != "From" ||
+                       fields[1].Name != "Date" ||
+                       fields[2].Name != "Body" {
+                       continue
                }
+               comments = append(comments, fmt.Sprintf(
+                       "%s: %s\n%s: %s\n%s",
+                       fields[0].Name, fields[0].Value,
+                       fields[1].Name, fields[1].Value,
+                       fields[2].Value,
+               ))
        }
        return comments
 }
 
+func parseTopics(data []byte) []string {
+       var s scanner.Scanner
+       s.Init(bytes.NewBuffer(data))
+       topics := []string{}
+       for tok := s.Scan(); tok != scanner.EOF; tok = s.Scan() {
+               topics = append(topics, s.TokenText())
+       }
+       sort.Strings(topics)
+       return topics
+}
+
 func initRepo(cfg *Cfg) (*plumbing.Hash, error) {
        var err error
        repo, err = git.PlainOpen(cfg.GitPath)
@@ -134,13 +165,14 @@ func initRepo(cfg *Cfg) (*plumbing.Hash, error) {
        headHash := head.Hash()
        if notes, err := repo.Notes(); err == nil {
                var notesRef *plumbing.Reference
-               var commentsRef *plumbing.Reference
                notes.ForEach(func(ref *plumbing.Reference) error {
                        switch string(ref.Name()) {
                        case "refs/notes/commits":
                                notesRef = ref
                        case cfg.CommentsNotesRef:
                                commentsRef = ref
+                       case cfg.TopicsNotesRef:
+                               topicsRef = ref
                        }
                        return nil
                })
@@ -154,6 +186,11 @@ func initRepo(cfg *Cfg) (*plumbing.Hash, error) {
                                commentsTree, _ = commentsCommit.Tree()
                        }
                }
+               if topicsRef != nil {
+                       if topicsCommit, err := repo.CommitObject(topicsRef.Hash()); err == nil {
+                               topicsTree, _ = topicsCommit.Tree()
+                       }
+               }
        }
        return &headHash, nil
 }