1 package server
2
3 import (
4 "fmt"
5 "net/http"
6 "os"
7 "path/filepath"
8 "strconv"
9 "strings"
10 "time"
11
12 "codeberg.org/tslocum/sriracha/internal/database"
13 . "codeberg.org/tslocum/sriracha/model"
14 . "codeberg.org/tslocum/sriracha/util"
15 )
16
17 func (s *Server) loadNewsForm(db *database.DB, r *http.Request, n *News, a *Account) error {
18 ts := FormString(r, "timestamp")
19 if ts == "" {
20 n.Timestamp = 0
21 } else {
22 timestamp, err := time.ParseInLocation("2006/01/02 15:04", ts, time.Local)
23 if err != nil {
24 return fmt.Errorf("failed to parse publish date and time (format: YYYY/MM/DD HH:MM)")
25 }
26 n.Timestamp = timestamp.Unix()
27 }
28 if n.Account != nil && n.Account.ID == a.ID {
29 n.Share = FormBool(r, "share")
30 }
31 n.Name = FormString(r, "name")
32 n.Subject = FormString(r, "subject")
33 n.Message = FormString(r, "message")
34 return nil
35 }
36
37 func (s *Server) serveNews(data *templateData, db *database.DB, w http.ResponseWriter, r *http.Request) {
38 var err error
39 data.Template = "manage_news"
40 data.Boards = db.AllBoards()
41
42 deleteNewsID := PathInt(r, "/sriracha/news/delete/")
43 if deleteNewsID > 0 {
44 news := db.NewsByID(deleteNewsID)
45 if news == nil {
46 data.ManageError("Invalid news item.")
47 return
48 } else if !news.MayDelete(data.Account) {
49 data.ManageError("Access denied.")
50 return
51 }
52
53 db.DeleteNews(deleteNewsID)
54 os.Remove(filepath.Join(s.config.Root, fmt.Sprintf("news-%d.html", news.ID)))
55
56 s.writeNewsIndexes(db)
57 s.writeSiteIndex(db)
58
59 s.log(db, data.Account, nil, fmt.Sprintf("Deleted news #%d", deleteNewsID), "")
60
61 data.Redirect(w, r, "/sriracha/news/")
62 return
63 }
64
65 newsID, err := strconv.Atoi(strings.TrimPrefix(r.URL.Path, "/sriracha/news/"))
66 if err == nil && newsID > 0 {
67 data.Manage.News = db.NewsByID(newsID)
68
69 if data.Manage.News != nil && r.Method == http.MethodPost {
70 if !data.Manage.News.MayUpdate(data.Account) {
71 data.ManageError("Access denied.")
72 return
73 }
74 oldNews := *data.Manage.News
75 err = s.loadNewsForm(db, r, data.Manage.News, data.Account)
76 if err != nil {
77 data.ManageError(err.Error())
78 return
79 }
80
81 err := data.Manage.News.Validate()
82 if err != nil {
83 data.ManageError(err.Error())
84 return
85 }
86
87 db.UpdateNews(data.Manage.News)
88
89 if data.Manage.News.Timestamp == 0 || data.Manage.News.Timestamp > time.Now().Unix() {
90 os.Remove(filepath.Join(s.config.Root, fmt.Sprintf("news-%d.html", data.Manage.News.ID)))
91 s.writeNewsIndexes(db)
92 } else {
93 s.rebuildNewsItem(db, data.Manage.News)
94 }
95 s.writeSiteIndex(db)
96
97 changes := printChanges(oldNews, *data.Manage.News)
98 s.log(db, data.Account, nil, fmt.Sprintf("Updated >>/news/%d", data.Manage.News.ID), changes)
99
100 data.Redirect(w, r, "/sriracha/news/")
101 return
102 }
103 return
104 }
105
106 if r.Method == http.MethodPost {
107 n := &News{}
108 n.Account = data.Account
109 err = s.loadNewsForm(db, r, n, data.Account)
110 if err != nil {
111 data.ManageError(err.Error())
112 return
113 }
114
115 err := n.Validate()
116 if err != nil {
117 data.ManageError(err.Error())
118 return
119 }
120
121 db.AddNews(n)
122 if n.Timestamp != 0 && n.Timestamp <= time.Now().Unix() {
123 s.rebuildNewsItem(db, n)
124 s.writeSiteIndex(db)
125 }
126
127 s.log(db, data.Account, nil, fmt.Sprintf("Added >>/news/%d", n.ID), "")
128
129 data.Redirect(w, r, "/sriracha/news/")
130 return
131 }
132
133 data.Manage.AllNews = db.AllNews(false)
134 data.Page = PathInt(r, "/sriracha/news/p")
135 data.Pages = pageCount(len(data.Manage.AllNews), entriesPerPage)
136 data.Manage.AllNews = pageSlice(data.Manage.AllNews, data.Page, entriesPerPage)
137 }
138
View as plain text