268 lines
6.0 KiB
Go
268 lines
6.0 KiB
Go
package srnd
|
|
|
|
import (
|
|
"encoding/json"
|
|
"io/ioutil"
|
|
"log"
|
|
"net/http"
|
|
"path/filepath"
|
|
"strconv"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
type NullCache struct {
|
|
handler *nullHandler
|
|
}
|
|
|
|
type nullHandler struct {
|
|
database Database
|
|
attachments bool
|
|
requireCaptcha bool
|
|
name string
|
|
prefix string
|
|
translations string
|
|
i18n map[string]*I18N
|
|
access sync.Mutex
|
|
}
|
|
|
|
func (self *nullHandler) GetI18N(r *http.Request) *I18N {
|
|
lang := r.URL.Query().Get("lang")
|
|
if lang == "" {
|
|
lang = I18nProvider.Name
|
|
}
|
|
self.access.Lock()
|
|
i, ok := self.i18n[lang]
|
|
if !ok {
|
|
var err error
|
|
i, err = NewI18n(lang, self.translations)
|
|
if err != nil {
|
|
log.Println(err)
|
|
}
|
|
if i != nil {
|
|
self.i18n[lang] = i
|
|
}
|
|
}
|
|
self.access.Unlock()
|
|
return i
|
|
}
|
|
|
|
func (self *nullHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
|
|
i18n := self.GetI18N(r)
|
|
|
|
path := r.URL.Path
|
|
_, file := filepath.Split(path)
|
|
|
|
isjson := strings.HasSuffix(path, "/json") || strings.HasSuffix(path, "/json/")
|
|
|
|
if strings.HasPrefix(path, "/t/") {
|
|
// thread handler
|
|
parts := strings.Split(path[3:], "/")
|
|
hash := parts[0]
|
|
msg, err := self.database.GetMessageIDByHash(hash)
|
|
if err == nil {
|
|
|
|
if !self.database.HasArticleLocal(msg.MessageID()) {
|
|
goto notfound
|
|
}
|
|
|
|
template.genThread(self.attachments, self.requireCaptcha, msg, self.prefix, self.name, w, self.database, isjson, i18n)
|
|
return
|
|
} else {
|
|
goto notfound
|
|
}
|
|
}
|
|
if strings.Trim(path, "/") == "overboard" {
|
|
// generate ukko aka overboard
|
|
template.genUkko(self.prefix, self.name, w, self.database, isjson, i18n)
|
|
return
|
|
}
|
|
|
|
if strings.HasPrefix(path, "/b/") {
|
|
// board handler
|
|
parts := strings.Split(path[3:], "/")
|
|
page := 0
|
|
group := parts[0]
|
|
if len(parts) > 1 && parts[1] != "" && parts[1] != "json" {
|
|
var err error
|
|
page, err = strconv.Atoi(parts[1])
|
|
if err != nil {
|
|
goto notfound
|
|
}
|
|
}
|
|
hasgroup := self.database.HasNewsgroup(group)
|
|
if !hasgroup {
|
|
goto notfound
|
|
}
|
|
|
|
banned, _ := self.database.NewsgroupBanned(group)
|
|
if banned {
|
|
goto notfound
|
|
}
|
|
|
|
pages := self.database.GetGroupPageCount(group)
|
|
if page >= int(pages) {
|
|
goto notfound
|
|
}
|
|
template.genBoardPage(self.attachments, self.requireCaptcha, self.prefix, self.name, group, page, w, self.database, isjson, i18n)
|
|
return
|
|
}
|
|
|
|
if strings.HasPrefix(path, "/o/") {
|
|
page := 0
|
|
parts := strings.Split(path[3:], "/")
|
|
if parts[0] != "json" && parts[0] != "" {
|
|
var err error
|
|
page, err = strconv.Atoi(parts[0])
|
|
if err != nil {
|
|
goto notfound
|
|
}
|
|
}
|
|
template.genUkkoPaginated(self.prefix, self.name, w, self.database, page, isjson, i18n)
|
|
return
|
|
}
|
|
|
|
if len(file) == 0 || file == "index.html" {
|
|
template.genFrontPage(10, self.prefix, self.name, w, ioutil.Discard, self.database, i18n)
|
|
return
|
|
}
|
|
|
|
if file == "index.json" {
|
|
// TODO: index.json
|
|
goto notfound
|
|
}
|
|
if strings.HasPrefix(file, "history.html") {
|
|
template.genGraphs(self.prefix, w, self.database, i18n)
|
|
return
|
|
}
|
|
if strings.HasPrefix(file, "boards.html") {
|
|
template.genBoardList(self.prefix, self.name, w, self.database, i18n)
|
|
return
|
|
}
|
|
|
|
if strings.HasPrefix(file, "boards.json") {
|
|
b := self.database.GetAllNewsgroups()
|
|
json.NewEncoder(w).Encode(b)
|
|
return
|
|
}
|
|
|
|
if strings.HasPrefix(file, "ukko.html") {
|
|
template.genUkko(self.prefix, self.name, w, self.database, false, i18n)
|
|
return
|
|
}
|
|
if strings.HasPrefix(file, "ukko.json") {
|
|
template.genUkko(self.prefix, self.name, w, self.database, true, i18n)
|
|
return
|
|
}
|
|
|
|
if strings.HasPrefix(file, "ukko-") {
|
|
page := getUkkoPage(file)
|
|
template.genUkkoPaginated(self.prefix, self.name, w, self.database, page, isjson, i18n)
|
|
return
|
|
}
|
|
if strings.HasPrefix(file, "thread-") {
|
|
hash := getThreadHash(file)
|
|
if len(hash) == 0 {
|
|
goto notfound
|
|
}
|
|
|
|
msg, err := self.database.GetMessageIDByHash(hash)
|
|
if err != nil {
|
|
goto notfound
|
|
}
|
|
|
|
if !self.database.HasArticleLocal(msg.MessageID()) {
|
|
goto notfound
|
|
}
|
|
|
|
template.genThread(self.attachments, self.requireCaptcha, msg, self.prefix, self.name, w, self.database, isjson, i18n)
|
|
return
|
|
}
|
|
if strings.HasPrefix(file, "catalog-") {
|
|
group := getGroupForCatalog(file)
|
|
if len(group) == 0 {
|
|
goto notfound
|
|
}
|
|
hasgroup := self.database.HasNewsgroup(group)
|
|
if !hasgroup {
|
|
goto notfound
|
|
}
|
|
template.genCatalog(self.prefix, self.name, group, w, self.database, i18n)
|
|
return
|
|
} else {
|
|
group, page := getGroupAndPage(file)
|
|
if len(group) == 0 || page < 0 {
|
|
goto notfound
|
|
}
|
|
hasgroup := self.database.HasNewsgroup(group)
|
|
if !hasgroup {
|
|
goto notfound
|
|
}
|
|
pages := self.database.GetGroupPageCount(group)
|
|
if page >= int(pages) {
|
|
goto notfound
|
|
}
|
|
template.genBoardPage(self.attachments, self.requireCaptcha, self.prefix, self.name, group, page, w, self.database, isjson, i18n)
|
|
return
|
|
}
|
|
|
|
notfound:
|
|
template.renderNotFound(w, r, self.prefix, self.name, i18n)
|
|
}
|
|
|
|
func (self *NullCache) DeleteBoardMarkup(group string) {
|
|
}
|
|
|
|
// try to delete root post's page
|
|
func (self *NullCache) DeleteThreadMarkup(root_post_id string) {
|
|
}
|
|
|
|
// regen every newsgroup
|
|
func (self *NullCache) RegenAll() {
|
|
}
|
|
|
|
func (self *NullCache) RegenFrontPage() {
|
|
}
|
|
|
|
func (self *NullCache) SetRequireCaptcha(required bool) {
|
|
self.handler.requireCaptcha = required
|
|
}
|
|
|
|
// regen every page of the board
|
|
func (self *NullCache) RegenerateBoard(group string) {
|
|
}
|
|
|
|
// regenerate pages after a mod event
|
|
func (self *NullCache) RegenOnModEvent(newsgroup, msgid, root string, page int) {
|
|
}
|
|
|
|
func (self *NullCache) Start() {
|
|
}
|
|
|
|
func (self *NullCache) Regen(msg ArticleEntry) {
|
|
}
|
|
|
|
func (self *NullCache) GetHandler() CacheHandler {
|
|
return self.handler
|
|
}
|
|
|
|
func (self *NullCache) Close() {
|
|
//nothig to do
|
|
}
|
|
|
|
func NewNullCache(prefix, webroot, name, translations string, attachments bool, db Database, store ArticleStore) CacheInterface {
|
|
cache := new(NullCache)
|
|
cache.handler = &nullHandler{
|
|
prefix: prefix,
|
|
name: name,
|
|
attachments: attachments,
|
|
requireCaptcha: true,
|
|
database: db,
|
|
i18n: make(map[string]*I18N),
|
|
translations: translations,
|
|
}
|
|
|
|
return cache
|
|
}
|