muse/main.go

158 lines
3.3 KiB
Go

package main
import (
"crypto/sha512"
"encoding/hex"
"errors"
"html/template"
"io"
"net/http"
"strconv"
"time"
"muse/storage"
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
)
type (
Response struct {
Ok bool `json:"ok"`
Message string `json:"message"`
}
TemplateRenderer struct {
template *template.Template
}
Template string
)
const (
adminUsername = "danolo"
adminPassword = "bd4cad796950f50352225de3c773d8f3c39622bc17f34ad661eabe615cdf6d32751c5751e0648dc17d890f40330018334a2ae899878f200f6dc80121ddb70cc9"
)
var (
list *storage.EntryList = &storage.EntryList{
Filename: "/var/lib/muse.json",
ModTime: time.Unix(0, 0),
}
)
// TemplateRenderer
func (renderer *TemplateRenderer) Render(w io.Writer, name string, data interface{}, c echo.Context) error {
return renderer.template.ExecuteTemplate(w, name, data)
}
func (template Template) TemplateController(c echo.Context) (err error) {
entries, err := list.GetEntries()
if err == nil {
err = c.Render(http.StatusOK, string(template), struct {
Entries []*storage.Entry
Today storage.JSTime
}{
Entries: entries,
Today: storage.JSTime(time.Now()),
})
}
return
}
func AddController(c echo.Context) (err error) {
entry := new(storage.Entry)
err = c.Bind(entry)
if err == nil {
if c.FormValue("date") == "" {
entry.Date = storage.JSTime(time.Now())
}
err = list.AddEntry(entry)
}
if err == nil {
err = c.Redirect(http.StatusFound, "..")
}
return
}
func DelController(c echo.Context) error {
var url string
var status int
var pos int
pos, err := strconv.Atoi(c.Param("index"))
if err == nil {
err = list.DeleteElement(pos)
}
if err == nil {
url = "../.."
status = http.StatusFound
} else {
status = http.StatusInternalServerError
}
return c.Redirect(status, url)
}
func DelConfirmController(c echo.Context) error {
var entries []*storage.Entry
failed := c.QueryParam("failed")
indexStr := c.Param("index")
index, err := strconv.Atoi(indexStr)
if err == nil {
entries, err = list.GetEntries()
}
if index >= len(entries) {
err = errors.New("Index out of range")
}
if err == nil {
err = c.Render(http.StatusOK, "del.html", struct {
Index int
Elem *storage.Entry
Failed string
}{
Index: index,
Elem: entries[index],
Failed: failed,
})
}
return err
}
func auth(username, password string, c echo.Context) (bool, error) {
hash := sha512.Sum512([]byte(password))
hashString := hex.EncodeToString(hash[:])
if username == adminUsername && hashString == adminPassword {
return true, nil
}
return false, nil
}
func RSSController(c echo.Context) (err error) {
if blob, err := list.GetFeed().ToRss(); err == nil {
c.Blob(http.StatusOK, "application/xml", []byte(blob))
}
return
}
func main() {
e := echo.New()
e.Renderer = &TemplateRenderer{
template: template.Must(template.ParseGlob("templates/*.html")),
}
e.GET("/", Template("index.html").TemplateController)
e.GET("/rss", RSSController)
e.Static("/static", "static")
admin := e.Group("/admin", middleware.BasicAuth(auth))
admin.POST("/add", AddController)
admin.POST("/del/:index", DelController)
admin.GET("/del/:index", DelConfirmController)
admin.GET("/", Template("admin.html").TemplateController)
admin.Static("/static", "admin/static")
e.Logger.Fatal(e.Start(":30303"))
}