Merge branch 'master' of ssh://github.com/majestrate/nntpchan
This commit is contained in:
commit
15af182415
@ -443,7 +443,7 @@ func (self *NNTPDaemon) persistFeed(conf *FeedConfig, mode string, n int) {
|
|||||||
|
|
||||||
if mode == "sync" {
|
if mode == "sync" {
|
||||||
// yeh, do it
|
// yeh, do it
|
||||||
self.syncPull(conf.proxy_type, conf.proxy_addr, conf.Addr)
|
self.syncPull(conf)
|
||||||
// sleep for the sleep interval and continue
|
// sleep for the sleep interval and continue
|
||||||
log.Println(conf.Name, "waiting for", conf.sync_interval, "before next sync")
|
log.Println(conf.Name, "waiting for", conf.sync_interval, "before next sync")
|
||||||
time.Sleep(conf.sync_interval)
|
time.Sleep(conf.sync_interval)
|
||||||
@ -492,15 +492,16 @@ func (self *NNTPDaemon) persistFeed(conf *FeedConfig, mode string, n int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// do a oneshot pull based sync with another server
|
// do a oneshot pull based sync with another server
|
||||||
func (self *NNTPDaemon) syncPull(proxy_type, proxy_addr, remote_addr string) {
|
func (self *NNTPDaemon) syncPull(conf *FeedConfig) {
|
||||||
c, err := self.dialOut(proxy_type, proxy_addr, remote_addr)
|
c, err := self.dialOut(conf.proxy_type, conf.proxy_addr, conf.Addr)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
conn := textproto.NewConn(c)
|
conn := textproto.NewConn(c)
|
||||||
// we connected
|
// we connected
|
||||||
nntp := createNNTPConnection(remote_addr)
|
nntp := createNNTPConnection(conf.Addr)
|
||||||
nntp.name = remote_addr + "-sync"
|
nntp.name = conf.Addr + "-sync"
|
||||||
|
nntp.feedname = conf.Name
|
||||||
// do handshake
|
// do handshake
|
||||||
_, reader, _, err := nntp.outboundHandshake(conn, nil)
|
_, reader, _, err := nntp.outboundHandshake(conn, conf)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("failed to scrape server", err)
|
log.Println("failed to scrape server", err)
|
||||||
|
@ -197,7 +197,7 @@ func (self *FileCache) regenerateThread(root ArticleEntry, json bool) {
|
|||||||
log.Println("did not write", fname, err)
|
log.Println("did not write", fname, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
template.genThread(self.attachments, self.requireCaptcha, root, self.prefix, self.name, wr, self.database, json, nil)
|
template.genThread(self.attachments, self.requireCaptcha, root, self.prefix, self.name, wr, self.database, json, nil, false)
|
||||||
} else {
|
} else {
|
||||||
log.Println("don't have root post", msgid, "not regenerating thread")
|
log.Println("don't have root post", msgid, "not regenerating thread")
|
||||||
}
|
}
|
||||||
@ -212,7 +212,7 @@ func (self *FileCache) regenerateBoardPage(board string, pages, page int, json b
|
|||||||
log.Println("error generating board page", page, "for", board, err)
|
log.Println("error generating board page", page, "for", board, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
template.genBoardPage(self.attachments, self.requireCaptcha, self.prefix, self.name, board, pages, page, wr, self.database, json, nil, false)
|
template.genBoardPage(self.attachments, self.requireCaptcha, self.prefix, self.name, board, pages, page, wr, self.database, json, nil, false, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// regenerate the catalog for a board
|
// regenerate the catalog for a board
|
||||||
@ -224,7 +224,7 @@ func (self *FileCache) regenerateCatalog(board string) {
|
|||||||
log.Println("error generating catalog for", board, err)
|
log.Println("error generating catalog for", board, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
template.genCatalog(self.prefix, self.name, board, wr, self.database, nil)
|
template.genCatalog(self.prefix, self.name, board, wr, self.database, nil, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
// regenerate the front page
|
// regenerate the front page
|
||||||
@ -264,7 +264,7 @@ func (self *FileCache) regenUkko() {
|
|||||||
log.Println("error generating ukko markup", err)
|
log.Println("error generating ukko markup", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
template.genUkko(self.prefix, self.name, wr, self.database, false, nil, false)
|
template.genUkko(self.prefix, self.name, wr, self.database, false, nil, false, false)
|
||||||
|
|
||||||
// json
|
// json
|
||||||
fname = filepath.Join(self.webroot_dir, "ukko.json")
|
fname = filepath.Join(self.webroot_dir, "ukko.json")
|
||||||
@ -274,7 +274,7 @@ func (self *FileCache) regenUkko() {
|
|||||||
log.Println("error generating ukko json", err)
|
log.Println("error generating ukko json", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
template.genUkko(self.prefix, self.name, wr, self.database, true, nil, false)
|
template.genUkko(self.prefix, self.name, wr, self.database, true, nil, false, false)
|
||||||
i := 0
|
i := 0
|
||||||
for i < 10 {
|
for i < 10 {
|
||||||
fname := fmt.Sprintf("ukko-%d.html", i)
|
fname := fmt.Sprintf("ukko-%d.html", i)
|
||||||
@ -285,14 +285,14 @@ func (self *FileCache) regenUkko() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
template.genUkkoPaginated(self.prefix, self.name, f, self.database, 10, i, false, nil, false)
|
template.genUkkoPaginated(self.prefix, self.name, f, self.database, 10, i, false, nil, false, false)
|
||||||
j, err := os.Create(jname)
|
j, err := os.Create(jname)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("failed to create json ukko", i, err)
|
log.Printf("failed to create json ukko", i, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
defer j.Close()
|
defer j.Close()
|
||||||
template.genUkkoPaginated(self.prefix, self.name, j, self.database, 10, i, true, nil, false)
|
template.genUkkoPaginated(self.prefix, self.name, j, self.database, 10, i, true, nil, false, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,9 @@ import (
|
|||||||
// base model type
|
// base model type
|
||||||
type BaseModel interface {
|
type BaseModel interface {
|
||||||
|
|
||||||
|
// set sfw flag
|
||||||
|
MarkSFW(sfw bool)
|
||||||
|
|
||||||
// site url prefix
|
// site url prefix
|
||||||
Prefix() string
|
Prefix() string
|
||||||
|
|
||||||
@ -185,6 +188,7 @@ type CatalogItemModel interface {
|
|||||||
OP() PostModel
|
OP() PostModel
|
||||||
ReplyCount() string
|
ReplyCount() string
|
||||||
Page() string
|
Page() string
|
||||||
|
MarkSFW(sfw bool)
|
||||||
}
|
}
|
||||||
|
|
||||||
type LinkModel interface {
|
type LinkModel interface {
|
||||||
|
@ -15,6 +15,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type catalogModel struct {
|
type catalogModel struct {
|
||||||
|
SFW bool
|
||||||
frontend string
|
frontend string
|
||||||
prefix string
|
prefix string
|
||||||
board string
|
board string
|
||||||
@ -46,6 +47,13 @@ func (self *thread) I18N(i *I18N) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *boardModel) MarkSFW(sfw bool) {
|
||||||
|
for idx := range self.threads {
|
||||||
|
self.threads[idx].MarkSFW(sfw)
|
||||||
|
}
|
||||||
|
self.SFW = sfw
|
||||||
|
}
|
||||||
|
|
||||||
func (self *boardModel) I18N(i *I18N) {
|
func (self *boardModel) I18N(i *I18N) {
|
||||||
self._i18n = i
|
self._i18n = i
|
||||||
for idx := range self.threads {
|
for idx := range self.threads {
|
||||||
@ -57,13 +65,24 @@ func (self *attachment) I18N(i *I18N) {
|
|||||||
self._i18n = i
|
self._i18n = i
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *catalogModel) MarkSFW(sfw bool) {
|
||||||
|
for idx := range self.threads {
|
||||||
|
self.threads[idx].MarkSFW(sfw)
|
||||||
|
}
|
||||||
|
self.SFW = sfw
|
||||||
|
}
|
||||||
|
|
||||||
func (self *catalogModel) Navbar() string {
|
func (self *catalogModel) Navbar() string {
|
||||||
param := make(map[string]interface{})
|
param := make(map[string]interface{})
|
||||||
param["name"] = fmt.Sprintf("Catalog for %s", self.board)
|
param["name"] = fmt.Sprintf("Catalog for %s", self.board)
|
||||||
param["frontend"] = self.frontend
|
param["frontend"] = self.frontend
|
||||||
var links []LinkModel
|
var links []LinkModel
|
||||||
|
var sfw int
|
||||||
|
if self.SFW {
|
||||||
|
sfw = 1
|
||||||
|
}
|
||||||
links = append(links, linkModel{
|
links = append(links, linkModel{
|
||||||
link: fmt.Sprintf("%sb/%s/?lang=%s", self.prefix, self.board, self._i18n.Name),
|
link: fmt.Sprintf("%sb/%s/?lang=%s&sfw=%d", self.prefix, self.board, self._i18n.Name, sfw),
|
||||||
text: "Board index",
|
text: "Board index",
|
||||||
})
|
})
|
||||||
param["prefix"] = self.prefix
|
param["prefix"] = self.prefix
|
||||||
@ -99,6 +118,10 @@ func (self *catalogItemModel) OP() PostModel {
|
|||||||
return self.op
|
return self.op
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *catalogItemModel) MarkSFW(sfw bool) {
|
||||||
|
self.op.MarkSFW(sfw)
|
||||||
|
}
|
||||||
|
|
||||||
func (self *catalogItemModel) Page() string {
|
func (self *catalogItemModel) Page() string {
|
||||||
return strconv.Itoa(self.page)
|
return strconv.Itoa(self.page)
|
||||||
}
|
}
|
||||||
@ -115,6 +138,7 @@ type boardModel struct {
|
|||||||
board string
|
board string
|
||||||
page int
|
page int
|
||||||
pages int
|
pages int
|
||||||
|
SFW bool
|
||||||
threads []ThreadModel
|
threads []ThreadModel
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -176,6 +200,9 @@ func (self *boardModel) PageList() []LinkModel {
|
|||||||
if i == 0 {
|
if i == 0 {
|
||||||
board = fmt.Sprintf("%sb/%s/?lang=%s", self.prefix, self.board, self._i18n.Name)
|
board = fmt.Sprintf("%sb/%s/?lang=%s", self.prefix, self.board, self._i18n.Name)
|
||||||
}
|
}
|
||||||
|
if self.SFW {
|
||||||
|
board += "&sfw=1"
|
||||||
|
}
|
||||||
links = append(links, linkModel{
|
links = append(links, linkModel{
|
||||||
link: board,
|
link: board,
|
||||||
text: fmt.Sprintf("[ %d ]", i),
|
text: fmt.Sprintf("[ %d ]", i),
|
||||||
@ -239,6 +266,7 @@ func (self *boardModel) Update(db Database) {
|
|||||||
|
|
||||||
type post struct {
|
type post struct {
|
||||||
_i18n *I18N
|
_i18n *I18N
|
||||||
|
SFW bool
|
||||||
truncated bool
|
truncated bool
|
||||||
prefix string
|
prefix string
|
||||||
board string
|
board string
|
||||||
@ -322,6 +350,7 @@ type attachment struct {
|
|||||||
Name string
|
Name string
|
||||||
ThumbWidth int
|
ThumbWidth int
|
||||||
ThumbHeight int
|
ThumbHeight int
|
||||||
|
SFW bool
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *attachment) MarshalJSON() (b []byte, err error) {
|
func (self *attachment) MarshalJSON() (b []byte, err error) {
|
||||||
@ -341,6 +370,10 @@ func (self *attachment) Hash() string {
|
|||||||
return strings.Split(self.Path, ".")[0]
|
return strings.Split(self.Path, ".")[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *attachment) MarkSFW(sfw bool) {
|
||||||
|
self.SFW = sfw
|
||||||
|
}
|
||||||
|
|
||||||
func (self *attachment) ThumbInfo() ThumbInfo {
|
func (self *attachment) ThumbInfo() ThumbInfo {
|
||||||
return ThumbInfo{
|
return ThumbInfo{
|
||||||
Width: self.ThumbWidth,
|
Width: self.ThumbWidth,
|
||||||
@ -353,6 +386,9 @@ func (self *attachment) Prefix() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *attachment) Thumbnail() string {
|
func (self *attachment) Thumbnail() string {
|
||||||
|
if self.SFW {
|
||||||
|
return self.prefix + "static/placeholder.png"
|
||||||
|
}
|
||||||
return self.prefix + "thm/" + self.Path + ".jpg"
|
return self.prefix + "thm/" + self.Path + ".jpg"
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,6 +445,13 @@ func (self *post) ShortHash() string {
|
|||||||
return ShortHashMessageID(self.MessageID())
|
return ShortHashMessageID(self.MessageID())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *post) MarkSFW(sfw bool) {
|
||||||
|
self.SFW = sfw
|
||||||
|
for idx := range self.Files {
|
||||||
|
self.Files[idx].MarkSFW(sfw)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (self *post) PubkeyHex() string {
|
func (self *post) PubkeyHex() string {
|
||||||
return self.Key
|
return self.Key
|
||||||
}
|
}
|
||||||
@ -493,7 +536,12 @@ func (self *post) PostURL() string {
|
|||||||
if i18n == nil {
|
if i18n == nil {
|
||||||
i18n = I18nProvider
|
i18n = I18nProvider
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%st/%s/?lang=%s#%s", self.Prefix(), HashMessageID(self.Parent), i18n.Name, self.PostHash())
|
u := fmt.Sprintf("%st/%s/?lang=%s", self.Prefix(), HashMessageID(self.Parent), i18n.Name)
|
||||||
|
if self.SFW {
|
||||||
|
u += "&sfw=1"
|
||||||
|
}
|
||||||
|
u += "#" + self.PostHash()
|
||||||
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *post) Prefix() string {
|
func (self *post) Prefix() string {
|
||||||
@ -564,6 +612,7 @@ func (self *post) Truncate() PostModel {
|
|||||||
Parent: self.Parent,
|
Parent: self.Parent,
|
||||||
sage: self.sage,
|
sage: self.sage,
|
||||||
Key: self.Key,
|
Key: self.Key,
|
||||||
|
SFW: self.SFW,
|
||||||
// TODO: copy?
|
// TODO: copy?
|
||||||
Files: self.Files,
|
Files: self.Files,
|
||||||
FrontendPublicKey: self.FrontendPublicKey,
|
FrontendPublicKey: self.FrontendPublicKey,
|
||||||
@ -590,13 +639,21 @@ type thread struct {
|
|||||||
_i18n *I18N
|
_i18n *I18N
|
||||||
allowFiles bool
|
allowFiles bool
|
||||||
prefix string
|
prefix string
|
||||||
links []LinkModel
|
links []linkModel
|
||||||
Posts []PostModel
|
Posts []PostModel
|
||||||
|
SFW bool
|
||||||
dirty bool
|
dirty bool
|
||||||
truncatedPostCount int
|
truncatedPostCount int
|
||||||
truncatedImageCount int
|
truncatedImageCount int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self *thread) MarkSFW(sfw bool) {
|
||||||
|
for idx := range self.Posts {
|
||||||
|
self.Posts[idx].MarkSFW(sfw)
|
||||||
|
}
|
||||||
|
self.SFW = sfw
|
||||||
|
}
|
||||||
|
|
||||||
func (self *thread) MarshalJSON() (b []byte, err error) {
|
func (self *thread) MarshalJSON() (b []byte, err error) {
|
||||||
posts := []PostModel{self.OP()}
|
posts := []PostModel{self.OP()}
|
||||||
posts = append(posts, self.Replies()...)
|
posts = append(posts, self.Replies()...)
|
||||||
@ -628,6 +685,11 @@ func (self *thread) Navbar() string {
|
|||||||
param := make(map[string]interface{})
|
param := make(map[string]interface{})
|
||||||
param["name"] = fmt.Sprintf("Thread %s", self.Posts[0].ShortHash())
|
param["name"] = fmt.Sprintf("Thread %s", self.Posts[0].ShortHash())
|
||||||
param["frontend"] = self.Board()
|
param["frontend"] = self.Board()
|
||||||
|
|
||||||
|
for idx := range self.links {
|
||||||
|
self.links[idx].link += "?sfw=1"
|
||||||
|
}
|
||||||
|
|
||||||
param["links"] = self.links
|
param["links"] = self.links
|
||||||
param["prefix"] = self.prefix
|
param["prefix"] = self.prefix
|
||||||
return template.renderTemplate("navbar", param, self._i18n)
|
return template.renderTemplate("navbar", param, self._i18n)
|
||||||
@ -642,7 +704,11 @@ func (self *thread) BoardURL() string {
|
|||||||
if i18n == nil {
|
if i18n == nil {
|
||||||
i18n = I18nProvider
|
i18n = I18nProvider
|
||||||
}
|
}
|
||||||
return fmt.Sprintf("%sb/%s/?lang=%s", self.Prefix(), self.Board(), i18n.Name)
|
u := fmt.Sprintf("%sb/%s/?lang=%s", self.Prefix(), self.Board(), i18n.Name)
|
||||||
|
if self.SFW {
|
||||||
|
u += "&sfw=1"
|
||||||
|
}
|
||||||
|
return u
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *thread) PostCount() int {
|
func (self *thread) PostCount() int {
|
||||||
@ -664,7 +730,7 @@ func createThreadModel(posts ...PostModel) ThreadModel {
|
|||||||
dirty: true,
|
dirty: true,
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
Posts: posts,
|
Posts: posts,
|
||||||
links: []LinkModel{
|
links: []linkModel{
|
||||||
linkModel{
|
linkModel{
|
||||||
text: group,
|
text: group,
|
||||||
link: fmt.Sprintf("%sb/%s/", prefix, group),
|
link: fmt.Sprintf("%sb/%s/", prefix, group),
|
||||||
@ -684,6 +750,7 @@ func (self *thread) Replies() []PostModel {
|
|||||||
for idx, post := range self.Posts[1:] {
|
for idx, post := range self.Posts[1:] {
|
||||||
if post != nil {
|
if post != nil {
|
||||||
post.SetIndex(idx + 1)
|
post.SetIndex(idx + 1)
|
||||||
|
post.MarkSFW(self.SFW)
|
||||||
replies = append(replies, post)
|
replies = append(replies, post)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -715,6 +782,7 @@ func (self *thread) Truncate() ThreadModel {
|
|||||||
for _, p := range t.Posts {
|
for _, p := range t.Posts {
|
||||||
imgs += p.NumAttachments()
|
imgs += p.NumAttachments()
|
||||||
}
|
}
|
||||||
|
t.SFW = self.SFW
|
||||||
t.truncatedPostCount = len(self.Posts) - trunc
|
t.truncatedPostCount = len(self.Posts) - trunc
|
||||||
t.truncatedImageCount = self.ImageCount() - imgs
|
t.truncatedImageCount = self.ImageCount() - imgs
|
||||||
return t
|
return t
|
||||||
@ -748,6 +816,7 @@ func (self *thread) BumpLock() bool {
|
|||||||
func (self *thread) Update(db Database) {
|
func (self *thread) Update(db Database) {
|
||||||
root := self.Posts[0].MessageID()
|
root := self.Posts[0].MessageID()
|
||||||
self.Posts = append([]PostModel{self.Posts[0]}, db.GetThreadReplyPostModels(self.prefix, root, 0, 0)...)
|
self.Posts = append([]PostModel{self.Posts[0]}, db.GetThreadReplyPostModels(self.prefix, root, 0, 0)...)
|
||||||
|
self.MarkSFW(self.SFW)
|
||||||
self.dirty = false
|
self.dirty = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1484,10 +1484,10 @@ func (self *nntpConnection) scrapeServer(daemon *NNTPDaemon, conn *textproto.Con
|
|||||||
line := sc.Text()
|
line := sc.Text()
|
||||||
idx := strings.IndexAny(line, " \t")
|
idx := strings.IndexAny(line, " \t")
|
||||||
if idx > 0 {
|
if idx > 0 {
|
||||||
//log.Println(self.name, "got newsgroup", line[:idx])
|
log.Println(self.name, "got newsgroup", line[:idx])
|
||||||
groups = append(groups, line[:idx])
|
groups = append(groups, line[:idx])
|
||||||
} else if idx < 0 {
|
} else if idx < 0 {
|
||||||
//log.Println(self.name, "got newsgroup", line)
|
log.Println(self.name, "got newsgroup", line)
|
||||||
groups = append(groups, line)
|
groups = append(groups, line)
|
||||||
} else {
|
} else {
|
||||||
// can't have it starting with WS
|
// can't have it starting with WS
|
||||||
|
@ -62,6 +62,7 @@ func (self *nullHandler) GetI18N(r *http.Request) *I18N {
|
|||||||
|
|
||||||
func (self *nullHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (self *nullHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
|
sfw := strings.Count(r.URL.RawQuery, "sfw=1") > 0
|
||||||
i18n := self.GetI18N(r)
|
i18n := self.GetI18N(r)
|
||||||
|
|
||||||
path := r.URL.Path
|
path := r.URL.Path
|
||||||
@ -80,7 +81,7 @@ func (self *nullHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
goto notfound
|
goto notfound
|
||||||
}
|
}
|
||||||
|
|
||||||
template.genThread(self.attachments, self.requireCaptcha, msg, self.prefix, self.name, w, self.database, isjson, i18n)
|
template.genThread(self.attachments, self.requireCaptcha, msg, self.prefix, self.name, w, self.database, isjson, i18n, sfw)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
goto notfound
|
goto notfound
|
||||||
@ -88,7 +89,7 @@ func (self *nullHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
if strings.Trim(path, "/") == "overboard" {
|
if strings.Trim(path, "/") == "overboard" {
|
||||||
// generate ukko aka overboard
|
// generate ukko aka overboard
|
||||||
template.genUkko(self.prefix, self.name, w, self.database, isjson, i18n, self.invertPagination)
|
template.genUkko(self.prefix, self.name, w, self.database, isjson, i18n, self.invertPagination, sfw)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +125,7 @@ func (self *nullHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
goto notfound
|
goto notfound
|
||||||
}
|
}
|
||||||
|
|
||||||
template.genBoardPage(self.attachments, self.requireCaptcha, self.prefix, self.name, group, int(pages), page, w, self.database, isjson, i18n, self.invertPagination)
|
template.genBoardPage(self.attachments, self.requireCaptcha, self.prefix, self.name, group, int(pages), page, w, self.database, isjson, i18n, self.invertPagination, sfw)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,7 +145,7 @@ func (self *nullHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
page = int(pages)
|
page = int(pages)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
template.genUkkoPaginated(self.prefix, self.name, w, self.database, int(pages), page, isjson, i18n, self.invertPagination)
|
template.genUkkoPaginated(self.prefix, self.name, w, self.database, int(pages), page, isjson, i18n, self.invertPagination, sfw)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,18 +174,18 @@ func (self *nullHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(file, "ukko.html") {
|
if strings.HasPrefix(file, "ukko.html") {
|
||||||
template.genUkko(self.prefix, self.name, w, self.database, false, i18n, self.invertPagination)
|
template.genUkko(self.prefix, self.name, w, self.database, false, i18n, self.invertPagination, sfw)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(file, "ukko.json") {
|
if strings.HasPrefix(file, "ukko.json") {
|
||||||
template.genUkko(self.prefix, self.name, w, self.database, true, i18n, self.invertPagination)
|
template.genUkko(self.prefix, self.name, w, self.database, true, i18n, self.invertPagination, sfw)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if strings.HasPrefix(file, "ukko-") {
|
if strings.HasPrefix(file, "ukko-") {
|
||||||
page := getUkkoPage(file)
|
page := getUkkoPage(file)
|
||||||
pages, _ := self.database.GetUkkoPageCount(10)
|
pages, _ := self.database.GetUkkoPageCount(10)
|
||||||
template.genUkkoPaginated(self.prefix, self.name, w, self.database, int(pages), page, isjson, i18n, self.invertPagination)
|
template.genUkkoPaginated(self.prefix, self.name, w, self.database, int(pages), page, isjson, i18n, self.invertPagination, sfw)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(file, "thread-") {
|
if strings.HasPrefix(file, "thread-") {
|
||||||
@ -202,7 +203,7 @@ func (self *nullHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
goto notfound
|
goto notfound
|
||||||
}
|
}
|
||||||
|
|
||||||
template.genThread(self.attachments, self.requireCaptcha, msg, self.prefix, self.name, w, self.database, isjson, i18n)
|
template.genThread(self.attachments, self.requireCaptcha, msg, self.prefix, self.name, w, self.database, isjson, i18n, sfw)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if strings.HasPrefix(file, "catalog-") {
|
if strings.HasPrefix(file, "catalog-") {
|
||||||
@ -214,7 +215,7 @@ func (self *nullHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
if !hasgroup {
|
if !hasgroup {
|
||||||
goto notfound
|
goto notfound
|
||||||
}
|
}
|
||||||
template.genCatalog(self.prefix, self.name, group, w, self.database, i18n)
|
template.genCatalog(self.prefix, self.name, group, w, self.database, i18n, sfw)
|
||||||
return
|
return
|
||||||
} else {
|
} else {
|
||||||
group, page := getGroupAndPage(file)
|
group, page := getGroupAndPage(file)
|
||||||
@ -229,7 +230,7 @@ func (self *nullHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|||||||
if page >= int(pages) {
|
if page >= int(pages) {
|
||||||
goto notfound
|
goto notfound
|
||||||
}
|
}
|
||||||
template.genBoardPage(self.attachments, self.requireCaptcha, self.prefix, self.name, group, int(pages), page, w, self.database, isjson, i18n, self.invertPagination)
|
template.genBoardPage(self.attachments, self.requireCaptcha, self.prefix, self.name, group, int(pages), page, w, self.database, isjson, i18n, self.invertPagination, sfw)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,24 +222,25 @@ func (self *templateEngine) obtainBoard(prefix, frontend, group string, db Datab
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *templateEngine) genCatalog(prefix, frontend, group string, wr io.Writer, db Database, i18n *I18N) {
|
func (self *templateEngine) genCatalog(prefix, frontend, group string, wr io.Writer, db Database, i18n *I18N, sfw bool) {
|
||||||
board := self.obtainBoard(prefix, frontend, group, db)
|
board := self.obtainBoard(prefix, frontend, group, db)
|
||||||
catalog := new(catalogModel)
|
catalog := new(catalogModel)
|
||||||
catalog.prefix = prefix
|
catalog.prefix = prefix
|
||||||
catalog.frontend = frontend
|
catalog.frontend = frontend
|
||||||
catalog.board = group
|
catalog.board = group
|
||||||
catalog.I18N(i18n)
|
catalog.I18N(i18n)
|
||||||
|
catalog.MarkSFW(sfw)
|
||||||
for page, bm := range board {
|
for page, bm := range board {
|
||||||
for _, th := range bm.Threads() {
|
for _, th := range bm.Threads() {
|
||||||
th.Update(db)
|
th.Update(db)
|
||||||
catalog.threads = append(catalog.threads, &catalogItemModel{op: th.OP(), page: page, replycount: len(th.Replies())})
|
catalog.threads = append(catalog.threads, &catalogItemModel{op: th.OP(), page: page, replycount: len(th.Replies())})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
self.writeTemplate("catalog", map[string]interface{}{"board": catalog}, wr, i18n)
|
self.writeTemplate("catalog", map[string]interface{}{"board": catalog, "sfw": sfw}, wr, i18n)
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate a board page
|
// generate a board page
|
||||||
func (self *templateEngine) genBoardPage(allowFiles, requireCaptcha bool, prefix, frontend, newsgroup string, pages, page int, wr io.Writer, db Database, json bool, i18n *I18N, invertPagination bool) {
|
func (self *templateEngine) genBoardPage(allowFiles, requireCaptcha bool, prefix, frontend, newsgroup string, pages, page int, wr io.Writer, db Database, json bool, i18n *I18N, invertPagination, sfw bool) {
|
||||||
// get the board page model
|
// get the board page model
|
||||||
perpage, _ := db.GetThreadsPerPage(newsgroup)
|
perpage, _ := db.GetThreadsPerPage(newsgroup)
|
||||||
var boardPage BoardModel
|
var boardPage BoardModel
|
||||||
@ -250,29 +251,30 @@ func (self *templateEngine) genBoardPage(allowFiles, requireCaptcha bool, prefix
|
|||||||
}
|
}
|
||||||
boardPage.Update(db)
|
boardPage.Update(db)
|
||||||
boardPage.I18N(i18n)
|
boardPage.I18N(i18n)
|
||||||
|
boardPage.MarkSFW(sfw)
|
||||||
// render it
|
// render it
|
||||||
if json {
|
if json {
|
||||||
self.renderJSON(wr, boardPage)
|
self.renderJSON(wr, boardPage)
|
||||||
} else {
|
} else {
|
||||||
form := renderPostForm(prefix, newsgroup, "", allowFiles, requireCaptcha, i18n)
|
form := renderPostForm(prefix, newsgroup, "", allowFiles, requireCaptcha, i18n)
|
||||||
self.writeTemplate("board", map[string]interface{}{"board": boardPage, "page": page, "form": form}, wr, i18n)
|
self.writeTemplate("board", map[string]interface{}{"board": boardPage, "page": page, "form": form, "sfw": sfw}, wr, i18n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *templateEngine) genUkko(prefix, frontend string, wr io.Writer, database Database, json bool, i18n *I18N, invertPagination bool) {
|
func (self *templateEngine) genUkko(prefix, frontend string, wr io.Writer, database Database, json bool, i18n *I18N, invertPagination, sfw bool) {
|
||||||
var page int64
|
var page int64
|
||||||
pages, err := database.GetUkkoPageCount(10)
|
pages, err := database.GetUkkoPageCount(10)
|
||||||
if invertPagination {
|
if invertPagination {
|
||||||
page = pages
|
page = pages
|
||||||
}
|
}
|
||||||
if err == nil {
|
if err == nil {
|
||||||
self.genUkkoPaginated(prefix, frontend, wr, database, int(pages), int(page), json, i18n, invertPagination)
|
self.genUkkoPaginated(prefix, frontend, wr, database, int(pages), int(page), json, i18n, invertPagination, sfw)
|
||||||
} else {
|
} else {
|
||||||
log.Println("genUkko()", err.Error())
|
log.Println("genUkko()", err.Error())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *templateEngine) genUkkoPaginated(prefix, frontend string, wr io.Writer, database Database, pages, page int, json bool, i18n *I18N, invertPagination bool) {
|
func (self *templateEngine) genUkkoPaginated(prefix, frontend string, wr io.Writer, database Database, pages, page int, json bool, i18n *I18N, invertPagination, sfw bool) {
|
||||||
var threads []ThreadModel
|
var threads []ThreadModel
|
||||||
var articles []ArticleEntry
|
var articles []ArticleEntry
|
||||||
if invertPagination {
|
if invertPagination {
|
||||||
@ -285,10 +287,11 @@ func (self *templateEngine) genUkkoPaginated(prefix, frontend string, wr io.Writ
|
|||||||
thread, err := database.GetThreadModel(prefix, root)
|
thread, err := database.GetThreadModel(prefix, root)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
thread.I18N(i18n)
|
thread.I18N(i18n)
|
||||||
|
thread.MarkSFW(sfw)
|
||||||
threads = append(threads, thread)
|
threads = append(threads, thread)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
obj := map[string]interface{}{"prefix": prefix, "threads": threads, "page": page}
|
obj := map[string]interface{}{"prefix": prefix, "threads": threads, "page": page, "sfw": sfw}
|
||||||
if page > 0 {
|
if page > 0 {
|
||||||
obj["prev"] = map[string]interface{}{"no": page - 1}
|
obj["prev"] = map[string]interface{}{"no": page - 1}
|
||||||
}
|
}
|
||||||
@ -310,7 +313,7 @@ func (self *templateEngine) genUkkoPaginated(prefix, frontend string, wr io.Writ
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *templateEngine) genThread(allowFiles, requireCaptcha bool, root ArticleEntry, prefix, frontend string, wr io.Writer, db Database, json bool, i18n *I18N) {
|
func (self *templateEngine) genThread(allowFiles, requireCaptcha bool, root ArticleEntry, prefix, frontend string, wr io.Writer, db Database, json bool, i18n *I18N, sfw bool) {
|
||||||
newsgroup := root.Newsgroup()
|
newsgroup := root.Newsgroup()
|
||||||
msgid := root.MessageID()
|
msgid := root.MessageID()
|
||||||
|
|
||||||
@ -322,12 +325,13 @@ func (self *templateEngine) genThread(allowFiles, requireCaptcha bool, root Arti
|
|||||||
*/
|
*/
|
||||||
t, err := db.GetThreadModel(prefix, msgid)
|
t, err := db.GetThreadModel(prefix, msgid)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
t.MarkSFW(sfw)
|
||||||
if json {
|
if json {
|
||||||
self.renderJSON(wr, t)
|
self.renderJSON(wr, t)
|
||||||
} else {
|
} else {
|
||||||
t.I18N(i18n)
|
t.I18N(i18n)
|
||||||
form := renderPostForm(prefix, newsgroup, msgid, allowFiles, requireCaptcha, i18n)
|
form := renderPostForm(prefix, newsgroup, msgid, allowFiles, requireCaptcha, i18n)
|
||||||
self.writeTemplate("thread", map[string]interface{}{"thread": t, "board": map[string]interface{}{"Name": newsgroup, "Frontend": frontend, "AllowFiles": allowFiles}, "form": form, "prefix": prefix}, wr, i18n)
|
self.writeTemplate("thread", map[string]interface{}{"sfw": sfw, "thread": t, "board": map[string]interface{}{"Name": newsgroup, "Frontend": frontend, "AllowFiles": allowFiles}, "form": form, "prefix": prefix}, wr, i18n)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
log.Println("templates: error getting thread for ", msgid, err.Error())
|
log.Println("templates: error getting thread for ", msgid, err.Error())
|
||||||
@ -476,6 +480,11 @@ func (self *templateEngine) genBoardList(prefix, name string, wr io.Writer, db D
|
|||||||
// for each group
|
// for each group
|
||||||
groups := db.GetAllNewsgroups()
|
groups := db.GetAllNewsgroups()
|
||||||
for _, group := range groups {
|
for _, group := range groups {
|
||||||
|
// exclude banned
|
||||||
|
banned, _ := db.NewsgroupBanned(group)
|
||||||
|
if banned {
|
||||||
|
continue
|
||||||
|
}
|
||||||
// posts this hour
|
// posts this hour
|
||||||
hour := db.CountPostsInGroup(group, 3600)
|
hour := db.CountPostsInGroup(group, 3600)
|
||||||
// posts today
|
// posts today
|
||||||
|
@ -800,3 +800,8 @@ func storeMessage(daemon *NNTPDaemon, hdr textproto.MIMEHeader, body io.Reader)
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func hasAtLeastNWords(str string, n int) bool {
|
||||||
|
parts := strings.Split(str, " ")
|
||||||
|
return len(parts) > n
|
||||||
|
}
|
||||||
|
@ -30,7 +30,7 @@
|
|||||||
{{#post.Attachments}}
|
{{#post.Attachments}}
|
||||||
<a href="{{Source}}" class="image_link" target="_blank" title="{{Filename}}"><img src="{{Thumbnail}}" class="image" /></a>
|
<a href="{{Source}}" class="image_link" target="_blank" title="{{Filename}}"><img src="{{Thumbnail}}" class="image" /></a>
|
||||||
{{/post.Attachments}}
|
{{/post.Attachments}}
|
||||||
<a name="{{post.PostHash}}"></a><span class="topicline"><b data-subject="{{post.Subject}}" class="subject">{{post.Subject}}</b> {{post.Name}} <span title="Posted from {{post.Frontend}}" class="published">{{post.Date}}</span> {{{post.Pubkey}}} <a href="{{post.PostURL}}">№</a>
|
<a name="{{post.PostHash}}"></a><span class="topicline"><b data-subject="{{post.Subject}}" class="subject">{{post.Subject}}</b> {{post.Name}} <span class="published">Posted from {{post.Frontend}} on {{post.Date}}</span> {{{post.Pubkey}}} <a href="{{post.PostURL}}">№</a>
|
||||||
<a href="#" onclick="return quickreply('{{post.ShortHash}}', '{{post.PostHash}}', '{{post.PostURL}}');"> {{post.ShortHash}}</a>
|
<a href="#" onclick="return quickreply('{{post.ShortHash}}', '{{post.PostHash}}', '{{post.PostURL}}');"> {{post.ShortHash}}</a>
|
||||||
</span>
|
</span>
|
||||||
<br /><br />
|
<br /><br />
|
||||||
|
@ -25,7 +25,12 @@
|
|||||||
<meta property="og:type" content="website"/>
|
<meta property="og:type" content="website"/>
|
||||||
<meta property="og:title" content="{{board.Board}}"/>
|
<meta property="og:title" content="{{board.Board}}"/>
|
||||||
<meta property="og:description" content="thread no. {{thread.OP.PostHash}} on changolia"/>
|
<meta property="og:description" content="thread no. {{thread.OP.PostHash}} on changolia"/>
|
||||||
|
{{#sfw}}
|
||||||
|
<meta property="og:url" content="{{prefix}}t/{{thread.OP.PostHash}}/?lang={{i18n.Name}}&sfw=1"/>
|
||||||
|
{{/sfw}}
|
||||||
|
{{^sfw}}
|
||||||
<meta property="og:url" content="{{prefix}}t/{{thread.OP.PostHash}}/?lang={{i18n.Name}}"/>
|
<meta property="og:url" content="{{prefix}}t/{{thread.OP.PostHash}}/?lang={{i18n.Name}}"/>
|
||||||
|
{{/sfw}}
|
||||||
<meta property="og:image"
|
<meta property="og:image"
|
||||||
content="{{prefix}}static/changolia-logo.png"/>
|
content="{{prefix}}static/changolia-logo.png"/>
|
||||||
</head>
|
</head>
|
||||||
@ -33,7 +38,12 @@
|
|||||||
{{{thread.Navbar}}}
|
{{{thread.Navbar}}}
|
||||||
<hr />
|
<hr />
|
||||||
<div class="sitetitle">
|
<div class="sitetitle">
|
||||||
|
{{#sfw}}
|
||||||
|
<h2><a href="{{thread.Prefix}}?lang={{i18n.Name}}&sfw=1">CHANGOLIA</a></h2>
|
||||||
|
{{/sfw}}
|
||||||
|
{{^sfw}}
|
||||||
<h2><a href="{{thread.Prefix}}?lang={{i18n.Name}}">CHANGOLIA</a></h2>
|
<h2><a href="{{thread.Prefix}}?lang={{i18n.Name}}">CHANGOLIA</a></h2>
|
||||||
|
{{/sfw}}
|
||||||
<b>Most of the rest of the wild west.</b>
|
<b>Most of the rest of the wild west.</b>
|
||||||
</div>
|
</div>
|
||||||
<center><b><a href="{{thread.BoardURL}}">{{thread.Board}}</a></b></center>
|
<center><b><a href="{{thread.BoardURL}}">{{thread.Board}}</a></b></center>
|
||||||
|
Reference in New Issue
Block a user