- Module github.com/cdnutter/canon, binary/command cmd/canon, Docker image and compose project "canon" - Environment variables now use the CANON_ prefix - Default site title is "<Your name>'s Canon" (or "Canon" with no name); a Site title set in Settings still overrides it - Existing topdeck.db (and WAL files) is renamed to canon.db on start - README: upgrade notes, including moving the old compose volume Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
84 lines
2.0 KiB
Go
84 lines
2.0 KiB
Go
package server
|
|
|
|
import (
|
|
"encoding/json"
|
|
"html/template"
|
|
"net/http"
|
|
|
|
"github.com/cdnutter/canon/internal/store"
|
|
)
|
|
|
|
// adminPage carries a JSON blob the page script boots from.
|
|
type adminPage struct {
|
|
Boot template.JS
|
|
List *store.List
|
|
}
|
|
|
|
func bootJSON(v any) template.JS {
|
|
b, _ := json.Marshal(v)
|
|
return template.JS(b)
|
|
}
|
|
|
|
type sizeLimits struct {
|
|
Max int `json:"max"`
|
|
Recommended int `json:"recommended"`
|
|
Warn int `json:"warn"`
|
|
}
|
|
|
|
var limits = sizeLimits{store.MaxListSize, store.RecommendedListSize, store.SoftListSizeWarning}
|
|
|
|
func (s *Server) handleAdminLists(w http.ResponseWriter, r *http.Request) {
|
|
lists, err := s.store.Lists(r.Context(), true)
|
|
if err != nil {
|
|
s.serverError(w, r, err)
|
|
return
|
|
}
|
|
if lists == nil {
|
|
lists = []store.List{}
|
|
}
|
|
covers, err := s.store.ListCovers(r.Context(), 3)
|
|
if err != nil {
|
|
s.serverError(w, r, err)
|
|
return
|
|
}
|
|
s.render(w, r, http.StatusOK, "admin_lists", "Your lists", adminPage{Boot: bootJSON(map[string]any{
|
|
"lists": lists,
|
|
"covers": covers,
|
|
"categories": store.Categories,
|
|
"limits": limits,
|
|
})})
|
|
}
|
|
|
|
func (s *Server) handleAdminList(w http.ResponseWriter, r *http.Request) {
|
|
id, err := pathID(r)
|
|
if err != nil {
|
|
s.notFound(w, r)
|
|
return
|
|
}
|
|
l, err := s.store.ListByID(r.Context(), id)
|
|
if err != nil {
|
|
s.notFound(w, r)
|
|
return
|
|
}
|
|
cat := listCategory(l)
|
|
provider := ""
|
|
if p, err := s.providers.For(r.Context(), l.Category); err == nil {
|
|
provider = p.Label()
|
|
}
|
|
s.render(w, r, http.StatusOK, "admin_list", l.Title, adminPage{List: &l, Boot: bootJSON(map[string]any{
|
|
"list": l,
|
|
"category": cat,
|
|
"categories": store.Categories,
|
|
"limits": limits,
|
|
"provider": provider,
|
|
"productions": store.TheaterProductions,
|
|
"pageSize": listPageSize,
|
|
})})
|
|
}
|
|
|
|
func (s *Server) handleAdminSettings(w http.ResponseWriter, r *http.Request) {
|
|
s.render(w, r, http.StatusOK, "admin_settings", "Settings", adminPage{Boot: bootJSON(map[string]any{
|
|
"categories": store.Categories,
|
|
})})
|
|
}
|