2023-05-25 16:08:56 -06:00
|
|
|
package main
|
|
|
|
|
|
|
|
import "sync"
|
|
|
|
import "path"
|
|
|
|
import "net/http"
|
|
|
|
import "html/template"
|
|
|
|
import "hnakra/service"
|
|
|
|
|
|
|
|
type Post struct {
|
|
|
|
Author, Content string
|
|
|
|
Next *Post
|
|
|
|
}
|
|
|
|
|
|
|
|
type Board struct {
|
2023-05-29 15:03:27 -06:00
|
|
|
*service.Service
|
2023-05-26 18:27:59 -06:00
|
|
|
|
2023-05-25 16:08:56 -06:00
|
|
|
root string
|
|
|
|
mux *http.ServeMux
|
|
|
|
template *template.Template
|
|
|
|
|
|
|
|
postsMutex sync.RWMutex
|
|
|
|
posts *Post
|
|
|
|
}
|
|
|
|
|
|
|
|
func main () {
|
|
|
|
board := Board { root: "/board/" }
|
|
|
|
board.mux = http.NewServeMux()
|
2023-05-29 15:03:27 -06:00
|
|
|
board.Service = service.NewService (
|
|
|
|
"Board",
|
|
|
|
"A board where you can post things.",
|
|
|
|
service.NewHTTP("@", board.root, board.mux))
|
|
|
|
|
2023-05-25 16:08:56 -06:00
|
|
|
handle := func (pattern string, handler func (http.ResponseWriter, *http.Request)) {
|
|
|
|
board.mux.HandleFunc(pattern, handler)
|
|
|
|
}
|
|
|
|
handle(board.root, board.serveHome)
|
|
|
|
handle(path.Join(board.root, "actionPost"), board.serveActionPost)
|
|
|
|
board.template = template.Must(template.New("board").Parse(tem))
|
|
|
|
|
2023-05-26 18:27:59 -06:00
|
|
|
board.Run()
|
2023-05-25 16:08:56 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
func (board *Board) getPosts (max int) []*Post {
|
|
|
|
board.postsMutex.RLock()
|
|
|
|
defer board.postsMutex.RUnlock()
|
|
|
|
|
|
|
|
posts := make([]*Post, max)
|
|
|
|
count := 0
|
|
|
|
current := board.posts
|
|
|
|
for current != nil && count < max {
|
|
|
|
posts[count] = current
|
|
|
|
count ++
|
|
|
|
current = current.Next
|
|
|
|
}
|
|
|
|
return posts[:count]
|
|
|
|
}
|
|
|
|
|
|
|
|
func (board *Board) serveHome (res http.ResponseWriter, req *http.Request) {
|
|
|
|
if req.URL.Path != board.root {
|
|
|
|
http.NotFoundHandler().ServeHTTP(res, req)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
res.Header().Add("content-type", "text/html")
|
|
|
|
res.WriteHeader(http.StatusOK)
|
|
|
|
board.template.ExecuteTemplate(res, "pageHome", board.getPosts(16))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (board *Board) serveActionPost (res http.ResponseWriter, req *http.Request) {
|
|
|
|
if req.Method != "POST" {
|
|
|
|
res.Header().Add("content-type", "text/plain")
|
|
|
|
res.WriteHeader(http.StatusMethodNotAllowed)
|
|
|
|
res.Write([]byte("Method not allowed"))
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
defer http.Redirect(res, req, board.root, http.StatusSeeOther)
|
|
|
|
|
|
|
|
req.ParseForm()
|
|
|
|
author := req.PostFormValue("author")
|
|
|
|
content := req.PostFormValue("content")
|
|
|
|
|
|
|
|
board.posts = &Post {
|
|
|
|
Author: author,
|
|
|
|
Content: content,
|
|
|
|
Next: board.posts,
|
|
|
|
}
|
|
|
|
}
|