mdsite/main.go

128 lines
2.6 KiB
Go
Raw Permalink Normal View History

2017-02-25 16:00:54 +01:00
package main
import (
2018-11-06 19:28:35 +01:00
"bytes"
2018-11-07 18:35:45 +01:00
"encoding/json"
"flag"
2017-02-25 16:00:54 +01:00
"html/template"
"io/ioutil"
"log"
"net/http"
"os"
2018-11-07 18:35:45 +01:00
"os/exec"
2017-02-25 16:00:54 +01:00
"path"
"strconv"
"strings"
"github.com/russross/blackfriday"
)
2017-02-25 16:05:03 +01:00
func main() {
loadConfig()
2017-02-25 16:05:03 +01:00
2018-11-07 18:35:45 +01:00
_ = os.Setenv(`GIT_TERMINAL_PROMPT`, `0`)
2017-02-25 16:05:03 +01:00
if err := updateTemplate(); err != nil {
log.Fatal(`Failed to load template. (` + err.Error() + `)`)
2017-02-25 16:05:03 +01:00
}
2020-05-08 12:31:12 +02:00
log.Fatal(http.ListenAndServe("127.0.0.1:"+strconv.Itoa(config.Port), http.HandlerFunc(serveRequest)))
2017-02-25 16:05:03 +01:00
}
2017-02-25 16:00:54 +01:00
var config struct {
Port int
Template string
Pages string
Static string
2018-11-07 18:35:45 +01:00
Webhook string
2017-02-25 16:00:54 +01:00
}
func loadConfig() {
flag.IntVar(&config.Port, `port`, 80, `The port mdsite will listen on`)
flag.StringVar(&config.Template, `template`, `template.html`, `The template used by mdsite`)
flag.StringVar(&config.Pages, `pages`, `pages`, `The OS path used when searching a page`)
flag.StringVar(&config.Static, `static`, `static`, `The OS path used for static resource`)
2018-11-07 18:35:45 +01:00
flag.StringVar(&config.Webhook, `webhook`, ``, `The secret for webhooks to update the content`)
flag.Parse()
2017-02-25 16:00:54 +01:00
}
var t *template.Template
func updateTemplate() error {
2018-11-07 18:35:45 +01:00
tmpl, err := template.ParseFiles(config.Template)
2017-02-25 16:00:54 +01:00
if err != nil {
return err
}
2018-11-07 18:35:45 +01:00
t = tmpl
2017-02-25 16:00:54 +01:00
return nil
}
func serveRequest(w http.ResponseWriter, r *http.Request) {
2018-11-07 18:35:45 +01:00
if r.Method == http.MethodPost && config.Webhook != `` && r.URL.Path == `/hook` {
var input struct {
Secret string `json:"secret"`
}
err := json.NewDecoder(r.Body).Decode(&input)
_ = r.Body.Close()
if err != nil || input.Secret != config.Webhook {
w.WriteHeader(403)
return
}
err = exec.Command(`git`, `fetch`).Run()
if err == nil {
err = exec.Command(`git`, `reset`, `--hard`, `origin/master`).Run()
}
if err == nil {
err = updateTemplate()
}
if err != nil {
w.WriteHeader(500)
w.Write([]byte(`Update failed`))
}
return
}
2017-02-25 16:00:54 +01:00
if strings.HasPrefix(r.URL.Path, `/static/`) {
path := path.Join(config.Static, path.Clean(strings.TrimPrefix(r.URL.Path, `/static/`)))
http.ServeFile(w, r, path)
2017-02-25 16:00:54 +01:00
return
}
servePage(w, r)
}
func servePage(w http.ResponseWriter, r *http.Request) {
p := path.Join(config.Pages, path.Clean(r.URL.Path))
2017-02-25 16:00:54 +01:00
s, err := os.Stat(p)
if err == nil && s.IsDir() {
2017-02-25 16:00:54 +01:00
if p[len(p)-1] != '/' {
p += `/`
}
p += `index`
}
c, err := ioutil.ReadFile(p + `.md`)
if err != nil {
w.WriteHeader(404)
return
}
2018-11-06 19:28:35 +01:00
var title string
if idx := bytes.IndexByte(c, '\n'); idx != -1 {
fl := string(c[:idx])
if strings.HasPrefix(fl, `[title]:`) {
title = strings.TrimPrefix(fl, `[title]:`)
}
}
data := struct {
Title string
Content template.HTML
}{title, template.HTML(blackfriday.MarkdownCommon(c))}
t.Execute(w, data)
2017-02-25 16:00:54 +01:00
}