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
58 s.log(db, data.Account, nil, fmt.Sprintf("Deleted news #%d", deleteNewsID), "")
59
60 http.Redirect(w, r, "/sriracha/news/", http.StatusFound)
61 return
62 }
63
64 newsID, err := strconv.Atoi(strings.TrimPrefix(r.URL.Path, "/sriracha/news/"))
65 if err == nil && newsID > 0 {
66 data.Manage.News = db.NewsByID(newsID)
67
68 if data.Manage.News != nil && r.Method == http.MethodPost {
69 if !data.Manage.News.MayUpdate(data.Account) {
70 data.ManageError("Access denied.")
71 return
72 }
73 oldNews := *data.Manage.News
74 err = s.loadNewsForm(db, r, data.Manage.News, data.Account)
75 if err != nil {
76 data.ManageError(err.Error())
77 return
78 }
79
80 err := data.Manage.News.Validate()
81 if err != nil {
82 data.ManageError(err.Error())
83 return
84 }
85
86 db.UpdateNews(data.Manage.News)
87
88 if data.Manage.News.Timestamp == 0 || data.Manage.News.Timestamp > time.Now().Unix() {
89 os.Remove(filepath.Join(s.config.Root, fmt.Sprintf("news-%d.html", data.Manage.News.ID)))
90 s.writeNewsIndexes(db)
91 } else {
92 s.rebuildNewsItem(db, data.Manage.News)
93 }
94
95 changes := printChanges(oldNews, *data.Manage.News)
96 s.log(db, data.Account, nil, fmt.Sprintf("Updated >>/news/%d", data.Manage.News.ID), changes)
97
98 http.Redirect(w, r, "/sriracha/news/", http.StatusFound)
99 return
100 }
101 return
102 }
103
104 if r.Method == http.MethodPost {
105 n := &News{}
106 n.Account = data.Account
107 err = s.loadNewsForm(db, r, n, data.Account)
108 if err != nil {
109 data.ManageError(err.Error())
110 return
111 }
112
113 err := n.Validate()
114 if err != nil {
115 data.ManageError(err.Error())
116 return
117 }
118
119 db.AddNews(n)
120 if n.Timestamp != 0 && n.Timestamp <= time.Now().Unix() {
121 s.rebuildNewsItem(db, n)
122 }
123
124 s.log(db, data.Account, nil, fmt.Sprintf("Added >>/news/%d", n.ID), "")
125
126 http.Redirect(w, r, "/sriracha/news/", http.StatusFound)
127 return
128 }
129
130 data.Manage.AllNews = db.AllNews(false)
131 }
132
View as plain text