package main

import (

"bufio"

"bytes"

"fmt"

"io/fs"

"net/url"

"sort"

"strings"

"sync"

"time"

)

type entryMetadata struct {

Filename string

Date     time.Time

Title    []byte

}

type entry struct {

Metadata *entryMetadata

Body     []byte

}

type gemlog struct {

gemlogFS  fs.FS

entrySet  map[string]*entryMetadata

entryList []*entryMetadata

mu        sync.RWMutex

}

func (g *gemlog) list() ([]*entryMetadata, error) {

g.mu.Lock()

defer g.mu.Unlock()

if err := g.populate(); err != nil {

	return nil, err

}

return g.entryList, nil

}

func (g *gemlog) entry(path string) (*entry, bool) {

g.mu.RLock()

defer g.mu.RUnlock()

path, err := url.QueryUnescape(strings.TrimPrefix(path, "/"))

if err != nil {

	return nil, false

}

metadata, ok := g.entrySet[path]

if !ok {

	return nil, false

}

f, err := fs.ReadFile(g.gemlogFS, path)

if err != nil {

	return nil, false

}

return &entry{

	Metadata: metadata,

	Body:     bytes.TrimSpace(f[bytes.Index(f, []byte{'\n'})+1:]),

}, true

}

func (g *gemlog) populate() error {

dirInfo, err := fs.ReadDir(g.gemlogFS, "gemlog")

if err != nil {

	return fmt.Errorf("cannot read gemlog dir: %w", err)

}

if len(g.entryList) == len(dirInfo) {

	return nil

}

g.entryList = []*entryMetadata{}

g.entrySet = map[string]*entryMetadata{}

if err := fs.WalkDir(g.gemlogFS, "gemlog", g.walkFS); err != nil {

	return fmt.Errorf("cannot walk gemlog dir: %w", err)

}

sort.Stable(g)

return nil

}

func (g *gemlog) Len() int { return len(g.entryList) }

func (g *gemlog) Swap(i, j int) { g.entryList[i], g.entryList[j] = g.entryList[j], g.entryList[i] }

func (g *gemlog) Less(i, j int) bool { return g.entryList[i].Filename >= g.entryList[j].Filename }

func (g *gemlog) walkFS(path string, d fs.DirEntry, e error) error {

if e != nil {

	return e

}

if d.IsDir() {

	return nil

}

t, err := time.Parse(time.RFC3339[:10], d.Name()[:10])

if err != nil {

	return fmt.Errorf("unable to parse time stamp: %w", err)

}

f, err := g.gemlogFS.Open(path)

if err != nil {

	return fmt.Errorf("unable to open file: %w", err)

}

title, err := bufio.NewReader(f).ReadBytes('\n')

if err != nil {

	return fmt.Errorf("unable to read title: %w", err)

}

metadata := &entryMetadata{

	Filename: d.Name(),

	Date:     t,

	Title:    bytes.TrimSpace(bytes.TrimPrefix(title, []byte{'#'})),

}

g.entrySet[path] = metadata

g.entryList = append(g.entryList, metadata)

return nil

}

Proxy Information
Original URL
gemini://source.community/ckaznocha/cliftons-capsule/raw/main/gemlog.go
Status Code
Success (20)
Meta
text/plain
Capsule Response Time
519.624002 milliseconds
Gemini-to-HTML Time
0.968068 milliseconds

This content has been proxied by September (ba2dc).