package node import ( "encoding/json" "net/http" "regexp" "strings" "time" "strconv" "gitea.difrex.ru/Umbrella/fetcher/i2es" "github.com/gorilla/mux" log "github.com/sirupsen/logrus" ) const ( quotesRE = `^(\w+)?>(.*)$` ) type ssr struct { es ESConf templatesDir string } func newSSR(templatesDir string, es ESConf) *ssr { return &ssr{ es: es, templatesDir: templatesDir, } } type PageData struct { Echoes []echo CurrentPage string PageNum int Posts []i2es.ESDoc ShowPaginator bool } func (p *PageData) GetDate(date string) string { d, err := strconv.ParseInt(date, 0, 64) if err != nil { return err.Error() } return time.Unix(d, 0).UTC().Format("02 Jan 06 15:04 MST") } func (p *PageData) Inc() int { return p.PageNum + 1 } func (p *PageData) Dec() int { return p.PageNum - 1 } func (p *PageData) RenderMessage(message string) (msg string) { return parseQuotes(message) } func parseQuotes(message string) string { var parsed []string r, err := regexp.Compile(quotesRE) if err != nil { log.Error(err) return message } for _, line := range strings.Split(message, "\n") { if r.MatchString(line) { author := r.FindAllStringSubmatch(line, 1) quote := "
" + author[0][2] + "
" if len(author) > 0 && author[0][1] != "" { quote += `` } quote += "
" parsed = append(parsed, quote) } else { parsed = append(parsed, line) } } return strings.Join(parsed, "\n") } func (s *ssr) newPageData(page string, posts []i2es.ESDoc, num int, showPaginator bool) *PageData { return &PageData{ Echoes: s.es.GetEchoesList(), Posts: posts, CurrentPage: page, PageNum: num, ShowPaginator: showPaginator, } } func (s *ssr) ssrRootHandler(w http.ResponseWriter, r *http.Request) { tpl, err := s.getTemplate("root") if err != nil { log.Error(err) return } posts := s.es.GetLatestPosts(50) for i := range posts { posts[i].Message = parseQuotes(posts[i].Message) } if err := tpl.Execute(w, s.newPageData("feed", posts, 1, true)); err != nil { log.Error(err) } } func (s *ssr) ssrForumHandler(w http.ResponseWriter, r *http.Request) { tpl, err := s.getTemplate("forum") if err != nil { log.Error(err) return } vars := mux.Vars(r) var num int if _, ok := vars["page"]; ok { num = getPageNum(mux.Vars(r)["page"]) } bcVal := r.URL.Query().Get("year") bc, _ := strconv.ParseBool(bcVal) if bc { if err := tpl.Execute(w, s.newPageData("forum", s.es.GetThreadsYear(num), num, false)); err != nil { log.Error(err) } return } if err := tpl.Execute(w, s.newPageData("forum", s.es.GetThreads(num), num, true)); err != nil { log.Error(err) } } func (s *ssr) threadViewHandler(w http.ResponseWriter, r *http.Request) { tpl, err := s.getTemplate("thread") if err != nil { log.Error(err) return } topicid, ok := mux.Vars(r)["topicid"] if !ok { log.Warn("empty topicid") w.WriteHeader(http.StatusBadRequest) w.Write([]byte("error: empty topicid")) return } posts := s.es.GetTopic(topicid) thread := "nil" if len(posts) > 0 { thread = posts[0].Subg } for i := range posts { posts[i].Message = parseQuotes(posts[i].Message) } if err := tpl.Execute(w, s.newPageData(thread, posts, 1, true)); err != nil { log.Error(err) } } func getPageNum(page string) int { i, err := strconv.ParseInt(page, 0, 64) if err != nil { log.Error(err) return 1 } if i < 1 { return 1 } return int(i) } func (s *ssr) echoViewHandler(w http.ResponseWriter, r *http.Request) { tpl, err := s.getTemplate("echo") if err != nil { log.Error(err) return } vars := mux.Vars(r) echo, ok := vars["echo"] if !ok { log.Warn("empty echo") w.WriteHeader(http.StatusBadRequest) w.Write([]byte("error: empty echo")) return } page := 1 if _, ok := vars["page"]; ok { page = getPageNum(vars["page"]) } bcVal := r.URL.Query().Get("year") bc, _ := strconv.ParseBool(bcVal) if bc { if err := tpl.Execute(w, s.newPageData("forum", s.es.GetThreadsYear(page, echo), page, false)); err != nil { log.Error(err) } return } if err := tpl.Execute(w, s.newPageData(echo, s.es.GetThreads(page, echo), page, true)); err != nil { log.Error(err) } } func (s *ssr) docsFormattingHandler(w http.ResponseWriter, r *http.Request) { tpl, err := s.getTemplate("docs_formatting") if err != nil { log.Error(err) return } if err := tpl.Execute(w, s.newPageData("docs: formatting", nil, 1, false)); err != nil { log.Error(err) } } func (s *ssr) singleMessageHandler(w http.ResponseWriter, r *http.Request) { tpl, err := s.getTemplate("message") if err != nil { log.Error(err) return } msgid, ok := mux.Vars(r)["msgid"] if !ok { log.Warn("empty msgid") w.WriteHeader(http.StatusBadRequest) w.Write([]byte("error: empty msgid")) return } if err := tpl.Execute(w, s.newPageData(msgid, s.es.GetMessage(msgid), 1, false)); err != nil { log.Error(err) } } func (s *ssr) searchHandler(w http.ResponseWriter, r *http.Request) { tpl, err := s.getTemplate("search") if err != nil { log.Error(err) return } q := r.URL.Query().Get("query") if q != "" { m, err := json.Marshal(q) if err != nil { log.Error(err) m = []byte("") } posts := s.es.DoSearch(string(m)) for i := range posts { posts[i].Date = parseTime(posts[i].Date) } if err := tpl.Execute(w, s.newPageData("search", posts, 1, false)); err != nil { log.Error(err) } } }