hedgedoc-watcher/hedgedoc-watcher.go
2022-12-05 23:10:20 +01:00

128 lines
2.8 KiB
Go
Executable File

///bin/sh -c true; exec /usr/bin/env go run "$0" "$@"
package main
import (
"encoding/json"
"io/ioutil"
"net/url"
"os"
"os/exec"
"path"
"strings"
"text/template"
"time"
"github.com/russross/blackfriday/v2"
)
const (
DL_LIMIT = 15 * 1024 * 1024
CACHE_FOLDER = "cache"
)
const RSS_TEMPLATE string = `<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:content="http://purl.org/rss/1.0/modules/content/">
<channel>
<title><![CDATA[ {{.ID}} ]]></title>
<link><![CDATA[ {{.Server}}/{{.ID}} ]]></link>
<description><![CDATA[ {{.ID}} ]]></description>
<item>
<title><![CDATA[ {{.Server}}/{{.ID}} ]]></title>
<content:encoded><![CDATA[ {{.Content}} ]]></content:encoded>
<guid><![CDATA[ {{.Server}}/{{.ID}}/{{.Modified.Format "20060102-150405"}} ]]></guid>
<link><![CDATA[ {{.Server}}/{{.ID}} ]]></link>
<pubDate>{{.Modified.Format "Mon, 02 Jan 2006 15:04:05 -0700"}}</pubDate>
</item>
</channel>
</rss>
`
func optPanic(err error) {
if err != nil {
panic(err)
}
}
func (n *Note) filename() string {
return path.Join(CACHE_FOLDER, n.ID)
}
func (n *Note) setContent() {
cmd := exec.Command("hedgedoc", "export", "--md", n.ID)
cmd.Env = os.Environ()
cmd.Env = append(cmd.Env, "HEDGEDOC_SERVER="+n.Server)
if n.CookiesFile != "" {
cmd.Env = append(cmd.Env, "HEDGEDOC_COOKIES_FILE="+n.CookiesFile)
}
filename, err := cmd.Output()
optPanic(err)
b, err := ioutil.ReadFile(strings.TrimSpace(string(filename)))
optPanic(err)
n.Content = string(blackfriday.Run(b))
n.Modified = time.Now()
}
func unmarshalNoteObject(filename string) Note {
bytes, err := ioutil.ReadFile(filename)
if err != nil {
bytes = []byte{}
}
var noteObject Note
err = json.Unmarshal(bytes, &noteObject)
if err != nil {
noteObject = Note{}
}
return noteObject
}
func marshalNoteObject(filename string, note Note) {
bytes, err := json.MarshalIndent(note, "", " ")
optPanic(err)
err = ioutil.WriteFile(filename, bytes, 0644)
optPanic(err)
}
func (newNote *Note) genRSS() {
var chosen Note
oldNote := unmarshalNoteObject(newNote.filename())
if oldNote.Content != newNote.Content {
chosen = *newNote
} else {
chosen = oldNote
}
err := rssTemplate.Execute(os.Stdout, chosen)
optPanic(err)
marshalNoteObject(newNote.filename(), chosen)
}
type Note struct {
Server string
ID string
Content string
Modified time.Time
CookiesFile string
}
func NewNote(server string, ID string) *Note {
n := &Note{Server: server, ID: ID}
n.setContent()
return n
}
var rssTemplate *template.Template
func rssify(noteURL string) {
u, err := url.Parse(noteURL)
optPanic(err)
NewNote(u.Scheme+"://"+u.Host, u.Path[1:]).genRSS()
}
func main() {
rssTemplate = template.Must(template.New("rss").Parse(RSS_TEMPLATE))
os.Mkdir(CACHE_FOLDER, 0755)
// todo: Cookie-file flag
rssify(os.Args[1])
}