func handleCls(c *Context, w http.ResponseWriter) error { vars := mux.Vars(c.R) bid, err := strconv.Atoi(vars["bid"]) if err != nil { return err } children, err := ptt.GetBoardChildren(bid) if err != nil { return err } boards := make([]pttbbs.Board, 0, 16) for _, bid := range children { if brd, err := ptt.GetBoard(bid); err == nil { if pttbbs.IsValidBrdName(brd.BrdName) && !brd.Over18 && !brd.Hidden { boards = append(boards, brd) } } } return page.ExecutePage(w, &page.Classlist{ Boards: boards, }) }
func internalError(w http.ResponseWriter, err error) { log.Println(err) w.WriteHeader(http.StatusInternalServerError) page.ExecutePage(w, &page.Error{ Title: `500 - Internal Server Error`, ContentHtml: `500 - Internal Server Error / Server Too Busy.`, }) }
func handleManIndex(c *Context, w http.ResponseWriter, brd *pttbbs.Board, path string) error { res, err := mand.List(context.TODO(), &bbspb.ListRequest{ BoardName: brd.BrdName, Path: path, }, grpc.FailFast(true)) if err != nil { return translateMandError(err) } return page.ExecutePage(w, &page.ManIndex{ Board: *brd, Path: path, Entries: res.Entries, }) }
func errorWrapperHandler(f func(*Context, http.ResponseWriter) error) func(http.ResponseWriter, *http.Request) { return func(w http.ResponseWriter, r *http.Request) { setCommonResponseHeaders(w) if err := clarifyRemoteError(handleRequest(w, r, f)); err != nil { if pg, ok := err.(page.Page); ok { if err = page.ExecutePage(w, pg); err != nil { log.Println("Failed to emit error page:", err) } return } internalError(w, err) } } }
func handleManArticle(c *Context, w http.ResponseWriter, brd *pttbbs.Board, path string) error { obj, err := cacheMgr.Get(&ArticleRequest{ Namespace: "man", Brd: *brd, Filename: path, Select: func(m pttbbs.SelectMethod, offset, maxlen int) (*pttbbs.ArticlePart, error) { res, err := mand.Article(context.TODO(), &bbspb.ArticleRequest{ BoardName: brd.BrdName, Path: path, SelectType: manSelectType(m), Offset: int64(offset), MaxLength: int64(maxlen), }, grpc.FailFast(true)) if err != nil { return nil, translateMandError(err) } return &pttbbs.ArticlePart{ CacheKey: res.CacheKey, FileSize: int(res.FileSize), Offset: int(res.SelectedOffset), Length: int(res.SelectedSize), Content: res.Content, }, nil }, }, ZeroArticle, ArticleCacheTimeout, generateArticle) if err != nil { return err } ar := obj.(*Article) if !ar.IsValid { return NewNotFoundError(nil) } if len(ar.ContentHtml) > TruncateSize { log.Println("Large rendered article:", brd.BrdName, path, len(ar.ContentHtml)) } return page.ExecutePage(w, &page.ManArticle{ Title: ar.ParsedTitle, Description: ar.PreviewContent, Board: brd, Path: path, ContentHtml: string(ar.ContentHtml), ContentTailHtml: string(ar.ContentTailHtml), ContentTruncated: ar.IsTruncated, }) }
func handleArticleCommon(c *Context, w http.ResponseWriter, brdname, filename string) error { var err error brd, err := getBoardByName(c, brdname) if err != nil { return err } // Render content obj, err := cacheMgr.Get(&ArticleRequest{ Namespace: "bbs", Brd: *brd, Filename: filename, Select: func(m pttbbs.SelectMethod, offset, maxlen int) (*pttbbs.ArticlePart, error) { return ptt.GetArticleSelect(brd.Bid, m, filename, "", offset, maxlen) }, }, ZeroArticle, ArticleCacheTimeout, generateArticle) // Try older filename when not found. if err == pttbbs.ErrNotFound { if name, ok := oldFilename(filename); ok { if handleArticleCommon(c, w, brdname, name) == nil { return nil } } } if err != nil { return err } ar := obj.(*Article) if !ar.IsValid { return NewNotFoundError(nil) } if len(ar.ContentHtml) > TruncateSize { log.Println("Large rendered article:", brd.BrdName, filename, len(ar.ContentHtml)) } return page.ExecutePage(w, &page.BbsArticle{ Title: ar.ParsedTitle, Description: ar.PreviewContent, Board: brd, FileName: filename, ContentHtml: string(ar.ContentHtml), ContentTailHtml: string(ar.ContentTailHtml), ContentTruncated: ar.IsTruncated, }) }
func handleAskOver18(c *Context, w http.ResponseWriter) error { from := c.R.FormValue("from") if from == "" || !isSafeRedirectURI(from) { from = "/" } if c.R.Method == "POST" { if c.R.PostFormValue("yes") != "" { setOver18Cookie(w) w.Header().Set("Location", from) } else { w.Header().Set("Location", "/") } w.WriteHeader(http.StatusFound) return nil } else { return page.ExecutePage(w, &page.AskOver18{ From: from, }) } }
func handleClsWithBid(c *Context, w http.ResponseWriter, bid int) error { if bid < 1 { return NewNotFoundError(fmt.Errorf("invalid bid: %v", bid)) } children, err := ptt.GetBoardChildren(bid) if err != nil { return err } boards := make([]pttbbs.Board, 0, 16) for _, bid := range children { if brd, err := ptt.GetBoard(bid); err == nil { if pttbbs.IsValidBrdName(brd.BrdName) && !brd.Over18 && !brd.Hidden { boards = append(boards, brd) } } } return page.ExecutePage(w, &page.Classlist{ Boards: boards, }) }
func handleBbs(c *Context, w http.ResponseWriter) error { vars := mux.Vars(c.R) brdname := vars["brdname"] // Note: TODO move timeout into the generating function. // We don't know if it is the last page without entry count. pageNo := 0 timeout := BbsIndexLastPageCacheTimeout if pg, err := strconv.Atoi(vars["page"]); err == nil { pageNo = pg timeout = BbsIndexCacheTimeout } var err error brd, err := getBoardByName(c, brdname) if err != nil { return err } obj, err := cacheMgr.Get(&BbsIndexRequest{ Brd: *brd, Page: pageNo, }, ZeroBbsIndex, timeout, generateBbsIndex) if err != nil { return err } bbsindex := obj.(*BbsIndex) if !bbsindex.IsValid { return NewNotFoundError(fmt.Errorf("not a valid cache.BbsIndex: %v/%v", brd.BrdName, pageNo)) } return page.ExecutePage(w, (*page.BbsIndex)(bbsindex)) }
func handleArticleCommon(c *Context, w http.ResponseWriter, brdname, filename string) error { var err error brd, err := getBoardByName(c, brdname) if err != nil { return err } // Render content obj, err := cacheMgr.Get(&ArticleRequest{ Brd: *brd, Filename: filename, }, ZeroArticle, ArticleCacheTimeout, generateArticle) if err != nil { return err } ar := obj.(*Article) if !ar.IsValid { return NewNotFoundError(nil) } if len(ar.ContentHtml) > TruncateSize { log.Println("Large rendered article:", brd.BrdName, filename, len(ar.ContentHtml)) } return page.ExecutePage(w, &page.BbsArticle{ Title: ar.ParsedTitle, Description: ar.PreviewContent, Board: brd, FileName: filename, ContentHtml: string(ar.ContentHtml), ContentTailHtml: string(ar.ContentTailHtml), ContentTruncated: ar.IsTruncated, }) }