endpoint_funcs.go 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295
  1. package server
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "fmt"
  6. "io"
  7. "net/http"
  8. "os"
  9. "path/filepath"
  10. "regexp"
  11. "strings"
  12. "text/template"
  13. "time"
  14. "git.linuxit.ro/turos.robert/mynotes/cmds/webservice/types"
  15. "git.linuxit.ro/turos.robert/mynotes/lib/inout"
  16. "github.com/yuin/goldmark"
  17. "github.com/yuin/goldmark/extension"
  18. "github.com/yuin/goldmark/renderer/html"
  19. )
  20. /*func Notes(w http.ResponseWriter, r *http.Request, fisier string) {
  21. var buf bytes.Buffer
  22. notita := types.Notita{}
  23. err := inout.FileToObj(fisier, &notita)
  24. if err != nil {
  25. WriteError(w, err)
  26. return
  27. }
  28. if err := goldmark.Convert([]byte(notita.Continut), &buf); err != nil {
  29. WriteError(w, err)
  30. return
  31. }
  32. notita.HTML = buf.String()
  33. resp, code := inout.ParseTemplate("templates/notita.tmpl", notita)
  34. w.WriteHeader(code)
  35. w.Write(resp)
  36. }
  37. /*func ListNotes(w http.ResponseWriter, r *http.Request, s *Server) {
  38. if r.Method == "GET" {
  39. f := inout.Folder{}
  40. err := inout.GetFolderStructure(s.NotesDir, &f)
  41. if err != nil {
  42. WriteError(w, err)
  43. return
  44. }
  45. resp, code := inout.ParseTemplate("templates/list_notes.tmpl", f)
  46. w.Header().Set("Content-Type", "text/html")
  47. w.WriteHeader(code)
  48. w.Write(resp)
  49. return
  50. }
  51. w.WriteHeader(http.StatusMethodNotAllowed)
  52. w.Write([]byte("methoda nepermisa"))
  53. }*/
  54. /*func EditNotes(w http.ResponseWriter, r *http.Request, filename string) {
  55. if r.Method == "GET" {
  56. f := types.Notita{}
  57. err := inout.FileToObj(filename, &f)
  58. if err != nil {
  59. WriteError(w, err)
  60. return
  61. }
  62. resp, code := inout.ParseTemplate("templates/edit_notes.tmpl", f)
  63. w.WriteHeader(code)
  64. w.Write(resp)
  65. return
  66. }
  67. WriteError(w, fmt.Errorf("method %s not allowed", r.Method))
  68. }*/
  69. func MDToHTML(w http.ResponseWriter, r *http.Request) {
  70. body, err := io.ReadAll(r.Body)
  71. if err != nil {
  72. fmt.Fprintf(w, "%+v", err)
  73. }
  74. mp := make(map[string]any)
  75. err = json.Unmarshal(body, &mp)
  76. if err != nil {
  77. fmt.Fprintf(w, "%+v", err)
  78. }
  79. var buff bytes.Buffer
  80. md := goldmark.New(
  81. goldmark.WithExtensions(
  82. extension.Table,
  83. extension.DefinitionList,
  84. extension.Footnote,
  85. extension.Typographer,
  86. ),
  87. goldmark.WithRendererOptions(
  88. html.WithUnsafe(),
  89. ),
  90. )
  91. tagRegex := regexp.MustCompile(`\[\[([^\[]+)\]\]`)
  92. markdown := tagRegex.ReplaceAllString(mp["markdown"].(string), `<a href="/tags/?tag=$1" class="tag">${1}</a>`)
  93. err = md.Convert([]byte(markdown), &buff)
  94. if err != nil {
  95. fmt.Fprintf(w, "%+v", err)
  96. }
  97. w.Write(buff.Bytes())
  98. }
  99. func API(w http.ResponseWriter, r *http.Request, s *Server) {
  100. action := strings.Trim(strings.TrimPrefix(r.URL.Path, "/api/"), "/")
  101. fmt.Println(action)
  102. if r.Method == "POST" {
  103. //w.WriteHeader(http.StatusNotImplemented)
  104. //w.Write(fmt.Appendf(nil, "action not implemented: %s", action))
  105. switch action {
  106. case "save_note":
  107. r.ParseForm()
  108. n := types.Notita{}
  109. n.Titlu = r.Form.Get("titlu")
  110. n.Continut = r.Form.Get("notita")
  111. n.Folder = r.Form.Get("director")
  112. if n.Folder == "" {
  113. n.Folder = "default"
  114. }
  115. err := inout.SafeDir(n.Folder)
  116. if err != nil {
  117. WriteError(w, err)
  118. return
  119. }
  120. path := filepath.Join(s.NotesDir, n.Folder)
  121. err = os.MkdirAll(path, 0755)
  122. fmt.Println(n.Folder)
  123. if err != nil {
  124. WriteError(w, err)
  125. return
  126. }
  127. fisier := fmt.Sprintf("notita-%s.json", time.Now().Format("2006-01-02-150405.999999"))
  128. n.Path = filepath.Join("notes_folder", n.Folder, fisier)
  129. //fmt.Println(fisier, r.Form)
  130. //return
  131. err = inout.ObjToFile(filepath.Join(s.NotesDir, n.Folder, fisier), n, true)
  132. if err != nil {
  133. WriteError(w, err)
  134. return
  135. }
  136. referinta := r.Referer()
  137. fmt.Println(referinta)
  138. if referinta != "" {
  139. http.Redirect(w, r, referinta, http.StatusSeeOther)
  140. } else {
  141. http.Redirect(w, r, "/index.html", http.StatusSeeOther)
  142. }
  143. case "update_note":
  144. r.ParseForm()
  145. n := types.Notita{}
  146. n.Titlu = r.Form.Get("titlu")
  147. n.Path = r.Form.Get("path")
  148. n.Folder = r.Form.Get("director")
  149. n.Continut = r.Form.Get("notita")
  150. fmt.Println(n.Path)
  151. err := inout.ObjToFile(n.Path, n, true)
  152. if err != nil {
  153. WriteError(w, err)
  154. return
  155. }
  156. referinta := r.Referer()
  157. if referinta != "" {
  158. http.Redirect(w, r, referinta, http.StatusSeeOther)
  159. } else {
  160. http.Redirect(w, r, "/index.html", http.StatusSeeOther)
  161. }
  162. case "create_dir":
  163. r.ParseForm()
  164. path := filepath.Join("notes_folder", r.Form.Get("director"), r.Form.Get("subdirector"))
  165. fmt.Println(path)
  166. err := os.Mkdir(path, 0755)
  167. if err != nil {
  168. WriteError(w, err)
  169. return
  170. }
  171. referinta := r.Referer()
  172. if referinta != "" {
  173. http.Redirect(w, r, referinta, http.StatusSeeOther)
  174. } else {
  175. http.Redirect(w, r, "/index.html", http.StatusSeeOther)
  176. }
  177. case "delete_dir":
  178. r.ParseForm()
  179. path := filepath.Join("./notes_folder", r.Form.Get("path"))
  180. fmt.Println(path)
  181. err := inout.SafeDir(path)
  182. if err != nil {
  183. WriteError(w, err)
  184. return
  185. }
  186. err = os.RemoveAll(path)
  187. if err != nil {
  188. WriteError(w, err)
  189. return
  190. }
  191. referinta := r.Referer()
  192. if referinta != "" {
  193. http.Redirect(w, r, referinta, http.StatusSeeOther)
  194. } else {
  195. http.Redirect(w, r, "/index.html", http.StatusSeeOther)
  196. }
  197. case "delete_file":
  198. r.ParseForm()
  199. path := filepath.Join("./", r.Form.Get("path"))
  200. err := inout.SafeDir(path)
  201. if err != nil {
  202. WriteError(w, err)
  203. return
  204. }
  205. err = os.Remove(path)
  206. if err != nil {
  207. WriteError(w, err)
  208. return
  209. }
  210. referinta := r.Referer()
  211. if referinta != "" {
  212. http.Redirect(w, r, referinta, http.StatusSeeOther)
  213. } else {
  214. http.Redirect(w, r, "/index.html", http.StatusSeeOther)
  215. }
  216. }
  217. }
  218. resp, code := inout.ParseTemplate("templates/error.tmpl", fmt.Errorf("method %s not allowed", r.Method))
  219. w.Header().Set("Content-Type", "text/html")
  220. w.WriteHeader(code)
  221. w.Write(resp)
  222. }
  223. func Design_viewer(w http.ResponseWriter, r *http.Request, s *Server, filename string) {
  224. var continut string
  225. if filename == "" {
  226. continut = ""
  227. } else {
  228. var note types.Notita
  229. err := inout.FileToObj(filename, &note)
  230. if err != nil {
  231. WriteError(w, err)
  232. return
  233. }
  234. continut = note.Continut
  235. }
  236. f := inout.Folder{}
  237. err := inout.GetFolderStructure(s.NotesDir, &f)
  238. if err != nil {
  239. WriteError(w, err)
  240. return
  241. }
  242. data := struct {
  243. Folders inout.Folder
  244. Continut string
  245. Notepath string
  246. Titlu string
  247. }{
  248. Folders: f,
  249. Continut: continut,
  250. Notepath: filename,
  251. Titlu: "lapte",
  252. }
  253. renderPage(w, []string{
  254. "templates/design.tmpl",
  255. "templates/design/sections/nav_big.tmpl",
  256. }, data)
  257. }
  258. func WriteError(w http.ResponseWriter, err error) {
  259. resp, code := inout.ParseTemplate("templates/error.tmpl", err)
  260. w.Header().Set("Content-Type", "text/html")
  261. w.WriteHeader(code)
  262. w.Write(resp)
  263. }
  264. func renderPage(w http.ResponseWriter, templates []string, data any) {
  265. tmpl, err := template.New(filepath.Base(templates[0])).Funcs(inout.GetFuncMap()).ParseFiles(templates...)
  266. if err != nil {
  267. WriteError(w, err)
  268. return
  269. }
  270. err = tmpl.ExecuteTemplate(w, filepath.Base(templates[0]), data)
  271. if err != nil {
  272. WriteError(w, err)
  273. return
  274. }
  275. }