1 package server
2
3 import (
4 "bytes"
5 "fmt"
6 "io"
7 "net/http"
8 "os"
9 "path/filepath"
10 "strconv"
11 "strings"
12
13 "codeberg.org/tslocum/sriracha/internal/database"
14 . "codeberg.org/tslocum/sriracha/model"
15 . "codeberg.org/tslocum/sriracha/util"
16 )
17
18 func (s *Server) loadPageForm(db *database.DB, r *http.Request, p *Page) error {
19 p.Path = FormString(r, "path")
20 p.Content = FormString(r, "content")
21
22 p.Path = strings.TrimSuffix(p.Path, ".html")
23
24 return s.writePage(db, nil, nil, p, io.Discard)
25 }
26
27 func (s *Server) servePage(data *templateData, db *database.DB, w http.ResponseWriter, r *http.Request) {
28 data.Template = "manage_page"
29 data.Boards = db.AllBoards()
30 data.Manage.Page = &Page{}
31
32 if PathString(r, "/sriracha/page/rebuild/") != "" {
33 if s.forbidden(w, data, "page.update") {
34 return
35 }
36 var pages []*Page
37 rebuildPageID := PathInt(r, "/sriracha/page/rebuild/")
38 if rebuildPageID > 0 {
39 p := db.PageByID(rebuildPageID)
40 if p == nil {
41 data.ManageError("Invalid page.")
42 return
43 }
44 pages = append(pages, p)
45 data.Info = Get(nil, data.Account, "Rebuilt %s.", p.Path)
46 } else {
47 pages = db.AllPages()
48 data.Info = Get(nil, data.Account, "Rebuilt all pages.")
49 }
50 s.writePages(db, pages)
51 }
52
53 deletePageID := PathInt(r, "/sriracha/page/delete/")
54 if deletePageID > 0 {
55 if s.forbidden(w, data, "page.delete") {
56 return
57 }
58 p := db.PageByID(deletePageID)
59 if p == nil {
60 data.ManageError("Invalid page.")
61 return
62 }
63 db.DeletePage(p.ID)
64
65 os.Remove(filepath.Join(s.config.Root, p.Path+".html"))
66
67 s.log(db, data.Account, nil, fmt.Sprintf("Deleted page #%d", p.ID), "")
68
69 data.Redirect(w, r, "/sriracha/page/")
70 return
71 }
72
73 pageID, err := strconv.Atoi(strings.TrimPrefix(r.URL.Path, "/sriracha/page/"))
74 if err == nil && pageID > 0 {
75 if s.forbidden(w, data, "page.update") {
76 return
77 }
78 p := db.PageByID(pageID)
79 if p == nil {
80 data.ManageError("Invalid page.")
81 return
82 }
83 data.Manage.Page = p
84
85 if r.Method != http.MethodPost {
86 return
87 }
88 oldPath := data.Manage.Page.Path
89 err = s.loadPageForm(db, r, data.Manage.Page)
90 if err != nil {
91 data.ManageError(err.Error())
92 return
93 }
94
95 err := data.Manage.Page.Validate()
96 if err != nil {
97 data.ManageError(err.Error())
98 return
99 }
100
101 if FormString(r, "preview") != "" {
102 buf := &bytes.Buffer{}
103 err = s.writePage(db, nil, nil, data.Manage.Page, buf)
104 if err != nil {
105 data.ManageError(err.Error())
106 return
107 }
108 data.Template = ""
109 io.Copy(w, buf)
110 return
111 }
112
113 if data.Manage.Page.Path != oldPath {
114 match := db.PageByPath(data.Manage.Page.Path)
115 if match != nil {
116 data.ManageError("Page with that path already exists")
117 return
118 }
119
120 os.Remove(filepath.Join(s.config.Root, oldPath+".html"))
121 }
122
123 db.UpdatePage(data.Manage.Page)
124 s.writePages(db, []*Page{data.Manage.Page})
125
126 s.log(db, data.Account, nil, fmt.Sprintf("Updated >>/page/%d", data.Manage.Page.ID), "")
127
128 data.Redirect(w, r, "/sriracha/page/")
129 return
130 }
131
132 if r.Method == http.MethodPost {
133 if s.forbidden(w, data, "page.add") {
134 return
135 }
136 p := &Page{}
137 err = s.loadPageForm(db, r, p)
138 if err != nil {
139 data.ManageError(err.Error())
140 return
141 }
142
143 err := p.Validate()
144 if err != nil {
145 data.ManageError(err.Error())
146 return
147 }
148
149 match := db.PageByPath(p.Path)
150 if match != nil {
151 data.ManageError("Page with that path already exists")
152 return
153 }
154
155 _, err = os.Stat(filepath.Join(s.config.Root, p.Path+".html"))
156 if !os.IsNotExist(err) {
157 data.ManageError("File already exists at that path")
158 return
159 }
160
161 if FormString(r, "preview") != "" {
162 buf := &bytes.Buffer{}
163 err = s.writePage(db, nil, nil, p, buf)
164 if err != nil {
165 data.ManageError(err.Error())
166 return
167 }
168 data.Template = ""
169 io.Copy(w, buf)
170 return
171 }
172
173 db.AddPage(p)
174 s.writePages(db, []*Page{p})
175
176 s.log(db, data.Account, nil, fmt.Sprintf("Added >>/page/%d", p.ID), "")
177
178 data.Redirect(w, r, "/sriracha/page/")
179 return
180 }
181
182 data.Manage.Pages = db.AllPages()
183 data.Page = PathInt(r, "/sriracha/page/p")
184 data.Pages = pageCount(len(data.Manage.Pages), entriesPerPage)
185 data.Manage.Pages = pageSlice(data.Manage.Pages, data.Page, entriesPerPage)
186 }
187
View as plain text