]> Sergey Matveev's repositories - sgblog.git/blobdiff - common.go
More compact Base64 ETag
[sgblog.git] / common.go
index bcc0d9c511dc96b5a8fd7abdb0b497a56c678be5..e7ac21752d701e533c25f62ccba47e8e87fcce5f 100644 (file)
--- a/common.go
+++ b/common.go
@@ -1,7 +1,104 @@
-// SGBlog -- Git-based CGI/inetd blogging/phlogging engine
+// SGBlog -- Git-backed CGI/UCSPI blogging/phlogging/gemlogging engine
+// Copyright (C) 2020-2024 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
+// published by the Free Software Foundation, version 3 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// 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/>.
+
+// SGBlog -- Git-backed CGI/UCSPI blogging/phlogging/gemlogging engine
 package sgblog
 
+import (
+       "bytes"
+       "fmt"
+       "io"
+       "sort"
+       "text/scanner"
+
+       "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 (
-       Version = "0.5.0"
+       Version = "0.34.0"
        WhenFmt = "2006-01-02 15:04:05Z07:00"
 )
+
+func ParseComments(data []byte) []string {
+       comments := []string{}
+       r := recfile.NewReader(bytes.NewReader(data))
+       for {
+               fields, err := r.Next()
+               if err != nil {
+                       break
+               }
+               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 GetNote(repo *git.Repository, tree *object.Tree, what plumbing.Hash) []byte {
+       if tree == nil {
+               return nil
+       }
+       var entry *object.TreeEntry
+       var err error
+       paths := make([]string, 3)
+       paths[0] = what.String()
+       paths[1] = paths[0][:2] + "/" + paths[0][2:]
+       paths[2] = paths[1][:4+1] + "/" + paths[1][4+1:]
+       for _, p := range paths {
+               entry, err = tree.FindEntry(p)
+               if err == nil {
+                       break
+               }
+       }
+       if entry == nil {
+               return nil
+       }
+       blob, err := repo.BlobObject(entry.Hash)
+       if err != nil {
+               return nil
+       }
+       r, err := blob.Reader()
+       if err != nil {
+               return nil
+       }
+       data, err := io.ReadAll(r)
+       if err != nil {
+               return nil
+       }
+       return bytes.TrimSuffix(data, []byte{'\n'})
+}