-// SGBlog -- Git-based CGI blogging engine
+// SGBlog -- Git-backed CGI/UCSPI blogging/phlogging/gemlogging engine
package sgblog
+import (
+ "bytes"
+ "fmt"
+ "io/ioutil"
+ "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.25.0"
WhenFmt = "2006-01-02 15:04:05Z07:00"
- Version = "0.3.2"
)
+
+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 := ioutil.ReadAll(r)
+ if err != nil {
+ return nil
+ }
+ return bytes.TrimSuffix(data, []byte{'\n'})
+}