aboutsummaryrefslogtreecommitdiff
path: root/cmd/xesite/main.go
blob: 7365fa9816cbec94688d0399c32ca6c3e62fd63a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package main

import (
	"context"
	"flag"
	"log"
	"log/slog"
	"net"
	"net/http"
	"os"
	"path/filepath"

	"github.com/donatj/hmacsig"
	"github.com/facebookgo/flagenv"
	_ "github.com/joho/godotenv/autoload"
	"xeiaso.net/v4/internal"
	"xeiaso.net/v4/internal/lume"
)

var (
	bind                = flag.String("bind", ":3000", "Port to listen on")
	devel               = flag.Bool("devel", false, "Enable development mode")
	dataDir             = flag.String("data-dir", "./var", "Directory to store data in")
	gitBranch           = flag.String("git-branch", "main", "Git branch to clone")
	gitRepo             = flag.String("git-repo", "https://github.com/Xe/site", "Git repository to clone")
	githubSecret        = flag.String("github-secret", "", "GitHub secret to use for webhooks")
	miToken             = flag.String("mi-token", "", "Token to use for the mi API")
	patreonSaasProxyURL = flag.String("patreon-saasproxy-url", "http://xesite-patreon-saasproxy.flycast/", "URL to use for the patreon saasproxy")
	siteURL             = flag.String("site-url", "https://xeiaso.net/", "URL to use for the site")
)

func main() {
	flagenv.Parse()
	flag.Parse()
	internal.Slog()

	ctx := context.Background()

	ln, err := net.Listen("tcp", *bind)
	if err != nil {
		log.Fatal(err)
	}

	os.MkdirAll(*dataDir, 0700)
	os.MkdirAll(filepath.Join(*dataDir, "tsnet"), 0700)

	pc, err := NewPatreonClient(http.DefaultClient)
	if err != nil {
		slog.Error("can't create patreon client", "err", err)
	}

	fs, err := lume.New(ctx, &lume.Options{
		Branch:        *gitBranch,
		Repo:          *gitRepo,
		StaticSiteDir: "lume",
		URL:           *siteURL,
		Development:   *devel,
		PatreonClient: pc,
		DataDir:       *dataDir,
		MiToken:       *miToken,
	})
	if err != nil {
		log.Fatal(err)
	}

	defer fs.Close()

	if *devel {
		go rebuildOnChange(fs)
	}

	go internalAPI(fs)

	if err != nil {
		log.Fatal(err)
	}

	mux := http.NewServeMux()
	mux.Handle("/", http.FileServer(http.FS(fs)))

	mux.HandleFunc("/blog.atom", func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, "/blog.rss", http.StatusMovedPermanently)
	})

	// NOTE(Xe): Had to rename this page because of a Lume/Go embed bug.
	mux.HandleFunc(`/blog/%F0%9F%A5%BA`, func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, "/blog/xn--ts9h/", http.StatusMovedPermanently)
	})
	mux.HandleFunc(`/blog/🥺`, func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, "/blog/xn--ts9h/", http.StatusMovedPermanently)
	})

	mux.HandleFunc("/static/manifest.json", func(w http.ResponseWriter, r *http.Request) {
		http.Redirect(w, r, "/static/site.webmanifest", http.StatusMovedPermanently)
	})

	gh := &GitHubWebhook{fs: fs}
	s := hmacsig.Handler256(gh, *githubSecret)
	mux.Handle("/.within/hook/github", s)

	mux.Handle("/.within/hook/patreon", &PatreonWebhook{fs: fs})

	var h http.Handler = mux
	h = internal.ClackSet(fs.Clacks()).Middleware(h)
	h = internal.CacheHeader(h)
	h = internal.AcceptEncodingMiddleware(h)
	h = internal.RefererMiddleware(h)

	slog.Info("starting server", "bind", *bind)
	log.Fatal(http.Serve(ln, h))
}