💾 Archived View for source.community › ckaznocha › cliftons-capsule › raw › main › app.go captured on 2023-06-14 at 14:21:09.

View Raw

More Information

⬅️ Previous capture (2021-12-17)

-=-=-=-=-=-=-

package main

import (
	"context"
	"fmt"
	"io/fs"
	"log"
	"strings"
	"text/template"
	"time"

	"source.community/ckaznocha/gemini"
)

type app struct {
	template *template.Template
	gemlog   *gemlog
	logger   *log.Logger
}

type footerArgs struct {
	Date  time.Time
	Title string
}

func newApp(logger *log.Logger, gemlogsFS, templatesFS fs.FS) (*app, error) {
	t, err := template.New("capsule-templates").Funcs(template.FuncMap{
		"now":        time.Now,
		"footerArgs": func(title string, date time.Time) footerArgs { return footerArgs{Title: title, Date: date} },
	}).ParseFS(templatesFS, "templates/*.tmpl.gmi")
	if err != nil {
		return nil, fmt.Errorf("cannot parse templates: %w", err)
	}

	gemlog := &gemlog{gemlogFS: gemlogsFS}
	if err := gemlog.populate(); err != nil {
		return nil, fmt.Errorf("cannot populate gemlog: %w", err)
	}

	return &app{
		template: t,
		gemlog:   gemlog,
		logger:   logger,
	}, nil
}

func (a *app) indexHandler(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request) {
	if strings.Trim(r.URI.Path, "/") != "" {
		w.Failure(ctx, gemini.StatusNotFound, gemini.StatusNotFound.Description())

		return
	}

	if err := a.template.ExecuteTemplate(w.Success(ctx, ""), "index.tmpl.gmi", nil); err != nil {
		a.logger.Panicln(err)
		w.Failure(ctx, gemini.StatusServerFailure, gemini.StatusServerFailure.Description())

		return
	}
}

func (a *app) gemlogHandler(ctx context.Context, w gemini.ResponseWriter, r *gemini.Request) {
	if r.URI.Path == "/gemlog/" {
		gemlogList, err := a.gemlog.list()
		if err != nil {
			a.logger.Println(err)
			w.Failure(ctx, gemini.StatusServerFailure, gemini.StatusServerFailure.Description())

			return
		}

		if err := a.template.ExecuteTemplate(w.Success(ctx, ""), "gemlog.tmpl.gmi", gemlogList); err != nil {
			a.logger.Println(err)
			w.Failure(ctx, gemini.StatusServerFailure, gemini.StatusServerFailure.Description())

			return
		}

		return
	}

	entry, ok := a.gemlog.entry(r.URI.Path)
	if !ok {
		w.Failure(ctx, gemini.StatusNotFound, gemini.StatusNotFound.Description())

		return
	}

	if err := a.template.ExecuteTemplate(w.Success(ctx, ""), "gemlog.entry.tmpl.gmi", entry); err != nil {
		a.logger.Println(err)
		w.Failure(ctx, gemini.StatusServerFailure, gemini.StatusServerFailure.Description())

		return
	}
}