package views import ( "log" "net/http" "os" "path/filepath" "strconv" "strings" urls "forgejo.gwairfelin.com/max/gispatcho" "forgejo.gwairfelin.com/max/gonotes/internal/conf" "forgejo.gwairfelin.com/max/gonotes/internal/notes" "forgejo.gwairfelin.com/max/gonotes/internal/templ" ) var myurls urls.URLs func GetRoutes(prefix string) *http.ServeMux { myurls = urls.URLs{ Prefix: prefix, URLs: map[string]urls.URL{ "list": {Path: "/", Protocol: "GET", Handler: list}, "new": {Path: "/new", Protocol: "GET", Handler: new}, "view_": {Path: "/{note}", Protocol: "GET", Handler: view}, "view": {Path: "/{note}/", Protocol: "GET", Handler: view}, "delete": {Path: "/{note}/delete/", Protocol: "GET", Handler: delete}, "edit": {Path: "/{note}/edit/", Protocol: "GET", Handler: edit}, "save": {Path: "/{note}/edit/save/", Protocol: "POST", Handler: save}, "togglebox": {Path: "/{note}/togglebox/", Protocol: "POST", Handler: togglebox}, }, } return myurls.GetRouter() } func view(w http.ResponseWriter, r *http.Request) { title := r.PathValue("note") note, err := notes.LoadNote(title) urlEdit := myurls.Reverse("edit", urls.Repl{"note": title}) urlDelete := myurls.Reverse("delete", urls.Repl{"note": title}) if err != nil { http.Redirect(w, r, urlEdit, http.StatusFound) return } context := templ.Ctx{"note": note, "urlEdit": urlEdit, "urlDelete": urlDelete} note.Render() err = templ.RenderTemplate(w, "view.tmpl.html", context) if err != nil { log.Print(err.Error()) http.Error(w, "Couldn't load template", http.StatusInternalServerError) return } } func edit(w http.ResponseWriter, r *http.Request) { encodedTitle := r.PathValue("note") note, err := notes.LoadNote(encodedTitle) if err != nil { title := notes.DecodeTitle(encodedTitle) note = ¬es.Note{Title: title} } urlSave := myurls.Reverse("save", urls.Repl{"note": encodedTitle}) context := templ.Ctx{"note": note, "urlSave": urlSave, "text": string(note.Body)} err = templ.RenderTemplate(w, "edit.tmpl.html", context) if err != nil { log.Print(err.Error()) http.Error(w, "Couldn't load template", http.StatusInternalServerError) return } } func new(w http.ResponseWriter, r *http.Request) { title := r.FormValue("title") if len(title) == 0 { title = "" } note := ¬es.Note{Title: title} urlEdit := myurls.Reverse("edit", urls.Repl{"note": note.EncodedTitle()}) http.Redirect(w, r, urlEdit, http.StatusFound) } func delete(w http.ResponseWriter, r *http.Request) { encodedTitle := r.PathValue("note") err := notes.DeleteNote(encodedTitle) if err != nil { log.Print(err.Error()) http.Error(w, "Couldn't delete note", http.StatusInternalServerError) return } urlList := myurls.Reverse("list", urls.Repl{}) http.Redirect(w, r, urlList, http.StatusFound) } func save(w http.ResponseWriter, r *http.Request) { oldTitle := r.PathValue("note") title := r.FormValue("title") body := r.FormValue("body") note := ¬es.Note{Title: title, Body: []byte(body)} note.Save() if oldTitle != note.EncodedTitle() { notes.DeleteNote(oldTitle) } http.Redirect(w, r, myurls.Reverse("view", urls.Repl{"note": note.EncodedTitle()}), http.StatusFound) } func togglebox(w http.ResponseWriter, r *http.Request) { title := r.PathValue("note") nthBox, err := strconv.Atoi(r.FormValue("box")) if err != nil { log.Fatal("You fucked up boy") return } note, err := notes.LoadNote(title) if err != nil { http.Redirect(w, r, myurls.Reverse("view", urls.Repl{"note": title}), http.StatusFound) return } note.ToggleBox(nthBox) http.Redirect(w, r, myurls.Reverse("view", urls.Repl{"note": note.EncodedTitle()}), http.StatusFound) } type titleAndURL struct { Title string URL string } func list(w http.ResponseWriter, r *http.Request) { files, err := os.ReadDir(conf.Conf.NotesDir) if err != nil { log.Print(err.Error()) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } titlesAndUrls := make([]titleAndURL, 0) for _, f := range files { if !f.IsDir() { encodedTitle := strings.TrimSuffix(f.Name(), filepath.Ext(f.Name())) title := notes.DecodeTitle(encodedTitle) log.Printf("Found note %s (title '%s')", encodedTitle, title) titlesAndUrls = append( titlesAndUrls, titleAndURL{Title: title, URL: myurls.Reverse("view", urls.Repl{"note": encodedTitle})}, ) log.Print(titlesAndUrls) } } urlNew := myurls.Reverse("new", urls.Repl{}) err = templ.RenderTemplate(w, "list.tmpl.html", templ.Ctx{"notes": titlesAndUrls, "urlNew": urlNew}) if err != nil { log.Print(err.Error()) http.Error(w, "Internal Server Error", http.StatusInternalServerError) return } }