You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
152 lines
3.2 KiB
152 lines
3.2 KiB
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), entries)
|
|
}
|
|
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"))
|
|
}
|