diff --git a/api.go b/api.go index 282dcd3..483b90a 100644 --- a/api.go +++ b/api.go @@ -86,8 +86,8 @@ func PostTodayApi(w http.ResponseWriter, r *http.Request) { PostFile("day/"+time.Now().Format(time.DateOnly), w, r) } -// GetNote returns contents of a note specified in URL -func GetNote(w http.ResponseWriter, r *http.Request) { +// GetNoteApi returns contents of a note specified in URL +func GetNoteApi(w http.ResponseWriter, r *http.Request) { noteString := chi.URLParam(r, "note") if noteString == "" { w.WriteHeader(http.StatusBadRequest) @@ -97,8 +97,8 @@ func GetNote(w http.ResponseWriter, r *http.Request) { GetFile("notes/"+noteString, w) } -// PostNote writes request's body contents to a note specified in URL -func PostNote(w http.ResponseWriter, r *http.Request) { +// PostNoteApi writes request's body contents to a note specified in URL +func PostNoteApi(w http.ResponseWriter, r *http.Request) { noteString := chi.URLParam(r, "note") if noteString == "" { w.WriteHeader(http.StatusBadRequest) diff --git a/pages/base.html b/pages/base.html index 9a81f2a..44ab90b 100644 --- a/pages/base.html +++ b/pages/base.html @@ -29,6 +29,6 @@ {{define "footer"}} {{end}} \ No newline at end of file diff --git a/pages/entry.html b/pages/entry.html index a01fa00..11834e5 100644 --- a/pages/entry.html +++ b/pages/entry.html @@ -1,4 +1,4 @@ {{define "main"}} -

| Go back

+

{{end}} \ No newline at end of file diff --git a/routes.go b/routes.go index 2b7dc2d..da54941 100644 --- a/routes.go +++ b/routes.go @@ -7,6 +7,7 @@ import ( "log/slog" "net/http" "os" + "strings" "time" ) @@ -33,7 +34,7 @@ func InternalError(w http.ResponseWriter, r *http.Request) { http.ServeFile(w, r, "./pages/error/500.html") } -// GetToday renders HTML page for today's view +// GetToday renders HTML page for today's entry func GetToday(w http.ResponseWriter, r *http.Request) { day, err := ReadToday() if err != nil { @@ -69,16 +70,16 @@ func PostToday(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, r.Header.Get("Referer"), 302) } -// GetDays renders HTML page for list of previous days +// GetDays renders HTML list of previous days' entries func GetDays(w http.ResponseWriter, r *http.Request) { day, err := ListFiles("day") if err != nil { - slog.Error("error reading today's file", "error", err) + slog.Error("error reading file list", "directory", "day", "error", err) InternalError(w, r) return } var daysFormatted []Entry - for i, _ := range day { + for i := range day { v := day[len(day)-1-i] // This is suboptimal, but reverse order is better here dayString := v t, err := time.Parse(time.DateOnly, v) @@ -94,20 +95,20 @@ func GetDays(w http.ResponseWriter, r *http.Request) { files := []string{"./pages/base.html", "./pages/list.html"} ts, err := template.ParseFiles(files...) if err != nil { - slog.Error("Error parsing template files", "error", err) + slog.Error("error parsing template files", "error", err) InternalError(w, r) return } err = ts.ExecuteTemplate(w, "base", EntryList{Title: "Previous days", Entries: daysFormatted}) if err != nil { - slog.Error("Error executing template", "error", err) + slog.Error("error executing template", "error", err) InternalError(w, r) return } } -// GetDay renders HTML page for a specific day +// GetDay renders HTML page for a specific day entry func GetDay(w http.ResponseWriter, r *http.Request) { dayString := chi.URLParam(r, "day") if dayString == "" { @@ -144,3 +145,81 @@ func GetDay(w http.ResponseWriter, r *http.Request) { return } } + +// GetNotes renders HTML list of all notes +func GetNotes(w http.ResponseWriter, r *http.Request) { + notes, err := ListFiles("notes") + if err != nil { + slog.Error("error reading file list", "directory", "notes", "error", err) + InternalError(w, r) + return + } + var notesFormatted []Entry + for _, v := range notes { + titleString := strings.Replace(v, "-", " ", -1) // FIXME: what if I need a hyphen? + notesFormatted = append(notesFormatted, Entry{Title: titleString, Link: "notes/" + v}) + } + + files := []string{"./pages/base.html", "./pages/list.html"} + ts, err := template.ParseFiles(files...) + if err != nil { + slog.Error("error parsing template files", "error", err) + InternalError(w, r) + return + } + + err = ts.ExecuteTemplate(w, "base", EntryList{Title: "Notes", Entries: notesFormatted}) + if err != nil { + slog.Error("error executing template", "error", err) + InternalError(w, r) + return + } +} + +// GetNote renders HTML page for a note +func GetNote(w http.ResponseWriter, r *http.Request) { + noteString := chi.URLParam(r, "note") + if noteString == "" { + w.WriteHeader(http.StatusBadRequest) + HandleWrite(w.Write([]byte("note not specified"))) + return + } + note, err := ReadFile("notes/" + noteString) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + note = []byte("") + } else { + slog.Error("error reading note's file", "error", err) + InternalError(w, r) + return + } + } + + files := []string{"./pages/base.html", "./pages/edit.html"} + ts, err := template.ParseFiles(files...) + if err != nil { + InternalError(w, r) + return + } + + err = ts.ExecuteTemplate(w, "base", Entry{Title: noteString, Content: string(note)}) + if err != nil { + InternalError(w, r) + return + } +} + +// PostNote saves a note form and redirects back to GET +func PostNote(w http.ResponseWriter, r *http.Request) { + noteString := chi.URLParam(r, "note") + if noteString == "" { + w.WriteHeader(http.StatusBadRequest) + HandleWrite(w.Write([]byte("note not specified"))) + return + } + err := SaveFile("notes/"+noteString, []byte(r.FormValue("text"))) + if err != nil { + slog.Error("error saving a note", "note", noteString, "error", err) + } + http.Redirect(w, r, r.Header.Get("Referer"), 302) +} diff --git a/serve.go b/serve.go index d98ca3f..645edd4 100644 --- a/serve.go +++ b/serve.go @@ -21,6 +21,9 @@ func Serve() { r.Post("/", PostToday) r.Get("/day", GetDays) r.Get("/day/{day}", GetDay) + r.Get("/notes", GetNotes) + r.Get("/notes/{note}", GetNote) + r.Post("/notes/{note}", PostNote) // API ============= apiRouter := chi.NewRouter() @@ -29,8 +32,8 @@ func Serve() { apiRouter.Get("/day", func(w http.ResponseWriter, r *http.Request) { GetFileList("day", w) }) apiRouter.Get("/day/{day}", GetDayApi) apiRouter.Get("/notes", func(w http.ResponseWriter, r *http.Request) { GetFileList("notes", w) }) - apiRouter.Get("/notes/{note}", GetNote) - apiRouter.Post("/notes/{note}", PostNote) + apiRouter.Get("/notes/{note}", GetNoteApi) + apiRouter.Post("/notes/{note}", PostNoteApi) apiRouter.Get("/today", GetTodayApi) apiRouter.Post("/today", PostTodayApi) apiRouter.Get("/export", GetExport)