small pixel drawing of a pufferfish j3s.sh

thought/thought.go

package thought

import (
	"bufio"
	"embed"
	"io"
	"io/fs"
	"log"
	"sort"
	"strings"
	"time"
)

const (
	timeLayoutAtom = "2006-01-02T15:04:05.000Z"
	timeLayoutPost = "2006-01-02"
)

//go:embed *.html
var thoughtFS embed.FS

// a ThoughtPost represents a single "thought post", duh
type ThoughtPost struct {
	Link      string
	Published bool
	Title     string
	Updated   string
	// Content includes the Title + Date
	// in its "source format", which often means
	// a bunch of aesthetic spaces and shit
	Content string
}

// parse takes a thought name & attempts to parse it
// from the thoughtFS into a struct.
// error = no post found
func parse(file string) (ThoughtPost, error) {
	var p ThoughtPost

	f, err := thoughtFS.Open(file)
	if err != nil {
		return p, err
	}

	scanner := bufio.NewScanner(f)
	scanner.Scan()
	// strip spaces
	title := scanner.Text()
	p.Title = strings.TrimSpace(title)
	scanner.Scan()
	timestr := strings.TrimSpace(scanner.Text())
	updated, err := time.Parse(timeLayoutPost, timestr)
	// if the time parses, we can assume that jes's intent
	// was to publish the post.
	if err != nil {
		p.Published = false
		p.Updated = "1993-02-18"
	} else {
		p.Published = true
		p.Updated = updated.Format(timeLayoutAtom)
	}
	p.Link = "https://j3s.sh/thought/" + file
	f.Close()

	// i know, reopening a file again to read content
	// is "very silly" as one would say. ha ha. is jes
	// a bad programmer? no bitch, this was just the easiest
	// way to do this, and it reads easily. the filesystem is
	// in memory anyway, so we're really talking about a micro
	// optimization. WHAT ELSE WOULD YOU HAVE ME DO?
	//
	// y has god forsaken me?
	f, err = thoughtFS.Open(file)
	if err != nil {
		return p, err
	}
	defer f.Close()

	b, err := io.ReadAll(f)
	if err != nil {
		return p, err
	}

	p.Content = string(b)

	return p, nil
}

func Post(name string) (ThoughtPost, error) {
	post, err := parse(name)
	if err != nil {
		return post, err
	}
	return post, nil
}

// GetPublishedPosts gets all posts that have
// a valid title + date that parse according to
// my extremely shitty parser
//
// (line 1 = title, line 2 = date)
func Posts() ([]ThoughtPost, error) {
	var thoughtPosts []ThoughtPost

	files, err := fs.Glob(thoughtFS, "*.html")
	if err != nil {
		log.Println(err)
		return thoughtPosts, err
	}

	for _, f := range files {
		thoughtPost, err := parse(f)
		if err != nil {
			log.Println(err)
			return thoughtPosts, err
		}
		thoughtPosts = append(thoughtPosts, thoughtPost)
	}

	return thoughtPosts, err
}

func DateSort(tp []ThoughtPost) {
	sort.Slice(tp, func(i, j int) bool {
		// we assume that timeLayoutAtom is correct here because
		// it was passed up correctly hopefully
		ti, _ := time.Parse(timeLayoutAtom, tp[i].Updated)
		tj, _ := time.Parse(timeLayoutAtom, tp[j].Updated)
		return ti.After(tj)
	})
}