|
|
@@ -1,216 +1,104 @@
|
|
|
package server
|
|
|
|
|
|
import (
|
|
|
- "bytes"
|
|
|
- "encoding/json"
|
|
|
"fmt"
|
|
|
- "io"
|
|
|
"net/http"
|
|
|
"os"
|
|
|
"path/filepath"
|
|
|
"strings"
|
|
|
- "text/template"
|
|
|
- "time"
|
|
|
|
|
|
- "git.linuxit.ro/turos.robert/mynotes/cmds/webservice/types"
|
|
|
"git.linuxit.ro/turos.robert/mynotes/lib/inout"
|
|
|
- "github.com/yuin/goldmark"
|
|
|
- "github.com/yuin/goldmark/extension"
|
|
|
)
|
|
|
|
|
|
-func Wildcard(w http.ResponseWriter, r *http.Request) {
|
|
|
+func Wildcard(w http.ResponseWriter, r *http.Request, s *Server) {
|
|
|
+ baseDir := "./templates/"
|
|
|
+ endpoint := strings.TrimPrefix(r.URL.Path, "/")
|
|
|
|
|
|
- if r.Method == "GET" {
|
|
|
- base_dir := "./templates/"
|
|
|
- endpoint := strings.TrimPrefix(r.URL.Path, "/")
|
|
|
- //fmt.Println(endpoint)
|
|
|
- //fmt.Println(r.URL.Path)
|
|
|
- if endpoint == "" {
|
|
|
- //in cazul in care apelam root
|
|
|
- endpoint = "index.html"
|
|
|
- }
|
|
|
- path := filepath.Join(base_dir, endpoint)
|
|
|
- _, err := os.Stat(path)
|
|
|
- if err != nil {
|
|
|
- w.Header().Add("Content-Type", "text/html")
|
|
|
+ if action, ok := findRoute(r.URL.Path, s.Routes); ok {
|
|
|
+ handlers := makeFuncMap()
|
|
|
|
|
|
- resp, code := inout.ParseTemplate("templates/design.tmpl", err)
|
|
|
+ handler, exists := handlers[action]
|
|
|
+ if !exists {
|
|
|
+ resp, code := inout.ParseTemplate("templates/error.tmpl", fmt.Errorf("handler %s not found", action))
|
|
|
+ w.Header().Set("Content-Type", "text/html")
|
|
|
w.WriteHeader(code)
|
|
|
w.Write(resp)
|
|
|
return
|
|
|
}
|
|
|
- w.Write(inout.FileToBytes(path))
|
|
|
+
|
|
|
+ handler(w, r)
|
|
|
return
|
|
|
}
|
|
|
|
|
|
-}
|
|
|
-
|
|
|
-func API(w http.ResponseWriter, r *http.Request, s *Server) {
|
|
|
- action := strings.TrimPrefix(r.URL.Path, "/api/")
|
|
|
- if r.Method == "POST" {
|
|
|
- //w.WriteHeader(http.StatusNotImplemented)
|
|
|
- //w.Write(fmt.Appendf(nil, "action not implemented: %s", action))
|
|
|
- switch action {
|
|
|
- case "save_note":
|
|
|
- r.ParseForm()
|
|
|
- n := types.Notita{}
|
|
|
- n.Titlu = r.Form.Get("titlu")
|
|
|
- n.Continut = r.Form.Get("notita")
|
|
|
- n.Folder = r.Form.Get("director")
|
|
|
- if n.Folder == "" {
|
|
|
- n.Folder = "default"
|
|
|
- }
|
|
|
- err := inout.SafeDir(n.Folder)
|
|
|
- if err != nil {
|
|
|
- resp, code := inout.ParseTemplate("templates/error.tmpl", err)
|
|
|
- w.Header().Set("Content-Type", "text/html")
|
|
|
- w.WriteHeader(code)
|
|
|
- w.Write(resp)
|
|
|
- return
|
|
|
- }
|
|
|
- path := filepath.Join(s.NotesDir, n.Folder)
|
|
|
- err = os.MkdirAll(path, 0755)
|
|
|
- fmt.Println(n.Folder)
|
|
|
- if err != nil {
|
|
|
- resp, code := inout.ParseTemplate("templates/error.tmpl", err)
|
|
|
- w.Header().Set("Content-Type", "text/html")
|
|
|
- w.WriteHeader(code)
|
|
|
- w.Write(resp)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- fisier := fmt.Sprintf("notita-%s.json", time.Now().Format("2006-01-02-150405.999999"))
|
|
|
- n.Path = filepath.Join("notes_folder", n.Folder, fisier)
|
|
|
- //fmt.Println(fisier, r.Form)
|
|
|
- //return
|
|
|
-
|
|
|
- err = inout.ObjToFile(filepath.Join(s.NotesDir, n.Folder, fisier), n, true)
|
|
|
- if err != nil {
|
|
|
- resp, code := inout.ParseTemplate("templates/error.tmpl", err)
|
|
|
- w.Header().Set("Content-Type", "text/html")
|
|
|
- w.WriteHeader(code)
|
|
|
- w.Write(resp)
|
|
|
- return
|
|
|
- }
|
|
|
- referinta := r.Referer()
|
|
|
- fmt.Println(referinta)
|
|
|
- if referinta != "" {
|
|
|
- http.Redirect(w, r, referinta, http.StatusSeeOther)
|
|
|
- } else {
|
|
|
- http.Redirect(w, r, "/index.html", http.StatusSeeOther)
|
|
|
- }
|
|
|
- case "update_note":
|
|
|
- r.ParseForm()
|
|
|
- n := types.Notita{}
|
|
|
- n.Titlu = r.Form.Get("titlu")
|
|
|
- n.Path = r.Form.Get("path")
|
|
|
- n.Folder = r.Form.Get("director")
|
|
|
- n.Continut = r.Form.Get("notita")
|
|
|
- fmt.Println(n.Path)
|
|
|
- err := inout.ObjToFile(n.Path, n, true)
|
|
|
- if err != nil {
|
|
|
- w.WriteHeader(http.StatusInternalServerError)
|
|
|
- fmt.Fprintf(w, "%+v", err)
|
|
|
- return
|
|
|
- }
|
|
|
- referinta := r.Referer()
|
|
|
- if referinta != "" {
|
|
|
- http.Redirect(w, r, referinta, http.StatusSeeOther)
|
|
|
- } else {
|
|
|
- http.Redirect(w, r, "/index.html", http.StatusSeeOther)
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
+ if endpoint == "" {
|
|
|
+ endpoint = "index.html"
|
|
|
}
|
|
|
- resp, code := inout.ParseTemplate("templates/error.tmpl", fmt.Errorf("method %s not allowed", r.Method))
|
|
|
- w.Header().Set("Content-Type", "text/html")
|
|
|
- w.WriteHeader(code)
|
|
|
- w.Write(resp)
|
|
|
-}
|
|
|
|
|
|
-func Notes(w http.ResponseWriter, r *http.Request, fisier string) {
|
|
|
- var buf bytes.Buffer
|
|
|
- notita := types.Notita{}
|
|
|
- err := inout.FileToObj(fisier, ¬ita)
|
|
|
+ path := filepath.Join(baseDir, endpoint)
|
|
|
+ _, err := os.Stat(path)
|
|
|
if err != nil {
|
|
|
- w.WriteHeader(http.StatusInternalServerError)
|
|
|
- w.Write([]byte(WEB_ERR))
|
|
|
- template.Must(template.ParseFiles("templates/error.tmpl")).Execute(w, err)
|
|
|
- return
|
|
|
- }
|
|
|
- if err := goldmark.Convert([]byte(notita.Continut), &buf); err != nil {
|
|
|
- w.WriteHeader(http.StatusInternalServerError)
|
|
|
- w.Write([]byte(WEB_ERR))
|
|
|
- template.Must(template.ParseFiles("templates/error.tmpl")).Execute(w, err)
|
|
|
- return
|
|
|
- }
|
|
|
- notita.HTML = buf.String()
|
|
|
- resp, code := inout.ParseTemplate("templates/notita.tmpl", notita)
|
|
|
- w.WriteHeader(code)
|
|
|
- w.Write(resp)
|
|
|
-}
|
|
|
-
|
|
|
-func ListNotes(w http.ResponseWriter, r *http.Request, s *Server) {
|
|
|
-
|
|
|
- if r.Method == "GET" {
|
|
|
- f := inout.Folder{}
|
|
|
- err := inout.GetFolderStructure(s.NotesDir, &f)
|
|
|
- if err != nil {
|
|
|
- resp, code := inout.ParseTemplate("templates/error.tmpl", err)
|
|
|
- w.Header().Set("Content-Type", "text/html")
|
|
|
- w.WriteHeader(code)
|
|
|
- w.Write(resp)
|
|
|
- return
|
|
|
- }
|
|
|
- resp, code := inout.ParseTemplate("templates/list_notes.tmpl", f)
|
|
|
w.Header().Set("Content-Type", "text/html")
|
|
|
+ resp, code := inout.ParseTemplate("templates/error.tmpl", err)
|
|
|
w.WriteHeader(code)
|
|
|
w.Write(resp)
|
|
|
return
|
|
|
}
|
|
|
- w.WriteHeader(http.StatusMethodNotAllowed)
|
|
|
- w.Write([]byte("methoda nepermisa"))
|
|
|
+
|
|
|
+ w.Write(inout.FileToBytes(path))
|
|
|
}
|
|
|
+func findRoute(path string, routes map[string]string) (string, bool) {
|
|
|
+ // 1. exact match
|
|
|
+ if action, ok := routes[path]; ok {
|
|
|
+ return action, true
|
|
|
+ }
|
|
|
|
|
|
-func EditNotes(w http.ResponseWriter, r *http.Request, filename string) {
|
|
|
+ // 2. longest prefix match
|
|
|
+ longest := ""
|
|
|
+ action := ""
|
|
|
|
|
|
- if r.Method == "GET" {
|
|
|
- f := types.Notita{}
|
|
|
- err := inout.FileToObj(filename, &f)
|
|
|
- if err != nil {
|
|
|
- resp, code := inout.ParseTemplate("templates/error.tmpl", err)
|
|
|
- w.WriteHeader(code)
|
|
|
- w.Write(resp)
|
|
|
+ for route, a := range routes {
|
|
|
+ if strings.HasPrefix(path, route) {
|
|
|
+ if len(route) > len(longest) {
|
|
|
+ longest = route
|
|
|
+ action = a
|
|
|
+ }
|
|
|
}
|
|
|
- resp, code := inout.ParseTemplate("templates/edit_notes.tmpl", f)
|
|
|
- w.WriteHeader(code)
|
|
|
- w.Write(resp)
|
|
|
- return
|
|
|
}
|
|
|
- resp, code := inout.ParseTemplate("templates/error.tmpl", fmt.Errorf("method %s not allowed", r.Method))
|
|
|
- w.WriteHeader(code)
|
|
|
- w.Write(resp)
|
|
|
-}
|
|
|
|
|
|
-func MDToHTML(w http.ResponseWriter, r *http.Request) {
|
|
|
- body, err := io.ReadAll(r.Body)
|
|
|
- if err != nil {
|
|
|
- fmt.Fprintf(w, "%+v", err)
|
|
|
+ if longest != "" {
|
|
|
+ return action, true
|
|
|
}
|
|
|
- mp := make(map[string]any)
|
|
|
- err = json.Unmarshal(body, &mp)
|
|
|
- if err != nil {
|
|
|
- fmt.Fprintf(w, "%+v", err)
|
|
|
- }
|
|
|
- var buff bytes.Buffer
|
|
|
- md := goldmark.New(
|
|
|
- goldmark.WithExtensions(extension.Table,
|
|
|
- extension.DefinitionList,
|
|
|
- extension.Footnote,
|
|
|
- extension.Typographer))
|
|
|
- err = md.Convert([]byte(mp["markdown"].(string)), &buff)
|
|
|
- if err != nil {
|
|
|
- fmt.Fprintf(w, "%+v", err)
|
|
|
+
|
|
|
+ return "", false
|
|
|
+}
|
|
|
+
|
|
|
+func makeFuncMap() map[string]hfunc {
|
|
|
+ handlers := map[string]hfunc{
|
|
|
+ "VIEW_NOTE": func(w http.ResponseWriter, r *http.Request) {
|
|
|
+ note := r.URL.Query().Get("note")
|
|
|
+ Notes(w, r, note)
|
|
|
+ },
|
|
|
+ "EDIT_NOTE": func(w http.ResponseWriter, r *http.Request) {
|
|
|
+ note := r.URL.Query().Get("note")
|
|
|
+ EditNotes(w, r, note)
|
|
|
+ },
|
|
|
+ "LIST_NOTES": func(w http.ResponseWriter, r *http.Request) {
|
|
|
+ srv := Server{}
|
|
|
+ err := inout.FileToObj("mynotes_cfg.json", &srv)
|
|
|
+ if err != nil {
|
|
|
+ srv.Err = err
|
|
|
+ }
|
|
|
+ ListNotes(w, r, &srv)
|
|
|
+ },
|
|
|
+ "API": func(w http.ResponseWriter, r *http.Request) {
|
|
|
+ srv := Server{}
|
|
|
+ err := inout.FileToObj("mynotes_cfg.json", &srv)
|
|
|
+ if err != nil {
|
|
|
+ srv.Err = err
|
|
|
+ }
|
|
|
+ API(w, r, &srv)
|
|
|
+ },
|
|
|
+ "MKDOWN_CONVERT": MDToHTML,
|
|
|
}
|
|
|
- w.Write(buff.Bytes())
|
|
|
+ return handlers
|
|
|
}
|