mirror of
https://github.com/Eggbertx/gochan.git
synced 2025-08-29 08:56:23 -07:00
Start moving template functions to their respective packages
This commit is contained in:
parent
f16fa39770
commit
4b5ea350eb
10 changed files with 192 additions and 143 deletions
|
@ -92,7 +92,7 @@ func (p Post) TitleText() string {
|
|||
return title
|
||||
}
|
||||
|
||||
func (p Post) ThreadPath() string {
|
||||
func (p *Post) ThreadPath() string {
|
||||
threadID := p.ParentID
|
||||
if threadID == 0 {
|
||||
threadID = p.ID
|
||||
|
@ -100,11 +100,11 @@ func (p Post) ThreadPath() string {
|
|||
return config.WebPath(p.BoardDir, "res", strconv.Itoa(threadID)+".html")
|
||||
}
|
||||
|
||||
func (p Post) WebPath() string {
|
||||
func (p *Post) WebPath() string {
|
||||
return p.ThreadPath() + "#" + strconv.Itoa(p.ID)
|
||||
}
|
||||
|
||||
func (p Post) ThumbnailPath() string {
|
||||
func (p *Post) ThumbnailPath() string {
|
||||
if p.Filename == "" {
|
||||
return ""
|
||||
}
|
||||
|
|
117
pkg/gcsql/templatefuncs.go
Normal file
117
pkg/gcsql/templatefuncs.go
Normal file
|
@ -0,0 +1,117 @@
|
|||
package gcsql
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"text/template"
|
||||
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
"github.com/gochan-org/gochan/pkg/gctemplates"
|
||||
"github.com/gochan-org/gochan/pkg/gcutil"
|
||||
)
|
||||
|
||||
func init() {
|
||||
gctemplates.AddTemplateFuncs(template.FuncMap{
|
||||
"bannedForever": func(ban *IPBan) bool {
|
||||
return ban.IsActive && ban.Permanent && !ban.CanAppeal
|
||||
},
|
||||
"isBanned": func(ban *IPBan, board string) bool {
|
||||
return ban.IsActive && ban.BoardID != nil
|
||||
},
|
||||
"banMask": func(ban IPBan) string {
|
||||
if ban.ID < 1 {
|
||||
if ban.RangeStart == ban.RangeEnd {
|
||||
return ban.RangeStart
|
||||
}
|
||||
return ""
|
||||
}
|
||||
ipn, err := gcutil.GetIPRangeSubnet(ban.RangeStart, ban.RangeEnd)
|
||||
if err != nil {
|
||||
return "?"
|
||||
}
|
||||
return ipn.String()
|
||||
},
|
||||
"getBoardDirFromID": func(id int) string {
|
||||
dir, _ := GetBoardDir(id)
|
||||
return dir
|
||||
},
|
||||
"intPtrToBoardDir": func(id *int, ifNil string, ifErr string) string {
|
||||
if id == nil {
|
||||
return ifNil
|
||||
}
|
||||
dir, err := GetBoardDir(*id)
|
||||
if err != nil {
|
||||
return ifErr
|
||||
}
|
||||
return dir
|
||||
},
|
||||
"getStaffNameFromID": func(id int) string {
|
||||
username, err := GetStaffUsernameFromID(id)
|
||||
if err != nil {
|
||||
return "?"
|
||||
}
|
||||
return username
|
||||
},
|
||||
"getAppealBanIP": func(appealID int) string {
|
||||
ban, err := GetIPBanByID(appealID)
|
||||
if err != nil || ban == nil {
|
||||
return "?"
|
||||
}
|
||||
if ban.RangeStart == ban.RangeEnd {
|
||||
return ban.RangeStart
|
||||
}
|
||||
ipn, err := gcutil.GetIPRangeSubnet(ban.RangeStart, ban.RangeEnd)
|
||||
if err != nil {
|
||||
return "?"
|
||||
}
|
||||
return ipn.String()
|
||||
},
|
||||
"getTopPostID": func(post *Post) int {
|
||||
id, _ := post.TopPostID()
|
||||
return id
|
||||
},
|
||||
"numReplies": func(boardid, opID int) int {
|
||||
num, err := GetThreadReplyCountFromOP(opID)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return num
|
||||
},
|
||||
"getBoardDir": func(id int) string {
|
||||
dir, err := GetBoardDir(id)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return dir
|
||||
},
|
||||
"boardPagePath": func(board *Board, page int) string {
|
||||
return config.WebPath(board.Dir, strconv.Itoa(page)+".html")
|
||||
},
|
||||
"getBoardDefaultStyle": func(dir string) string {
|
||||
boardCfg := config.GetBoardConfig(dir)
|
||||
if !boardCfg.IsGlobal() {
|
||||
// /<board>/board.json exists, overriding the default them and theme set in SQL
|
||||
return boardCfg.DefaultStyle
|
||||
}
|
||||
var defaultStyle string
|
||||
err := QueryRowSQL(`SELECT default_style FROM DBPREFIXboards WHERE dir = ?`,
|
||||
[]any{dir}, []any{&defaultStyle})
|
||||
if err != nil || defaultStyle == "" {
|
||||
gcutil.LogError(err).Caller().
|
||||
Str("board", dir).
|
||||
Msg("Unable to get default style attribute of board")
|
||||
return boardCfg.DefaultStyle
|
||||
}
|
||||
return defaultStyle
|
||||
},
|
||||
"sectionBoards": func(sectionID int) []Board {
|
||||
var boards []Board
|
||||
for _, board := range AllBoards {
|
||||
if board.SectionID == sectionID && !board.IsHidden(false) {
|
||||
boards = append(boards, board)
|
||||
}
|
||||
}
|
||||
return boards
|
||||
},
|
||||
})
|
||||
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package gcsql
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
)
|
||||
|
||||
|
@ -86,3 +87,21 @@ func (p *Post) AttachFile(upload *Upload) error {
|
|||
}
|
||||
return tx.Commit()
|
||||
}
|
||||
|
||||
// GetUploadFilenameAndBoard returns the filename (or an empty string) and
|
||||
// the board of the given post ID
|
||||
func GetUploadFilenameAndBoard(postID int) (string, string, error) {
|
||||
const query = `SELECT filename, dir FROM DBPREFIXfiles
|
||||
JOIN DBPREFIXposts ON post_id = DBPREFIXposts.id
|
||||
JOIN DBPREFIXthreads ON thread_id = DBPREFIXthreads.id
|
||||
JOIN DBPREFIXboards ON DBPREFIXboards.id = board_id
|
||||
WHERE DBPREFIXposts.id = ?`
|
||||
var filename, dir string
|
||||
err := QueryRowSQL(query, []any{postID}, []any{&filename, &dir})
|
||||
if errors.Is(err, sql.ErrNoRows) {
|
||||
return "", "", nil
|
||||
} else if err != nil {
|
||||
return "", "", err
|
||||
}
|
||||
return filename, dir, nil
|
||||
}
|
||||
|
|
|
@ -5,15 +5,12 @@ import (
|
|||
"fmt"
|
||||
"html"
|
||||
"html/template"
|
||||
"path"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
"github.com/gochan-org/gochan/pkg/gcsql"
|
||||
"github.com/gochan-org/gochan/pkg/gcutil"
|
||||
"github.com/gochan-org/gochan/pkg/posting/uploads"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -147,112 +144,9 @@ var funcMap = template.FuncMap{
|
|||
},
|
||||
|
||||
// Imageboard functions
|
||||
"bannedForever": func(ban *gcsql.IPBan) bool {
|
||||
return ban.IsActive && ban.Permanent && !ban.CanAppeal
|
||||
},
|
||||
"isBanned": func(ban *gcsql.IPBan, board string) bool {
|
||||
return ban.IsActive && ban.BoardID != nil
|
||||
},
|
||||
"banMask": func(ban gcsql.IPBan) string {
|
||||
if ban.ID < 1 {
|
||||
if ban.RangeStart == ban.RangeEnd {
|
||||
return ban.RangeStart
|
||||
}
|
||||
return ""
|
||||
}
|
||||
ipn, err := gcutil.GetIPRangeSubnet(ban.RangeStart, ban.RangeEnd)
|
||||
if err != nil {
|
||||
return "?"
|
||||
}
|
||||
return ipn.String()
|
||||
},
|
||||
"customFlagsEnabled": func(board string) bool {
|
||||
return config.GetBoardConfig(board).CustomFlags != nil
|
||||
},
|
||||
"getBoardDirFromID": func(id int) string {
|
||||
dir, _ := gcsql.GetBoardDir(id)
|
||||
return dir
|
||||
},
|
||||
"intPtrToBoardDir": func(id *int, ifNil string, ifErr string) string {
|
||||
if id == nil {
|
||||
return ifNil
|
||||
}
|
||||
dir, err := gcsql.GetBoardDir(*id)
|
||||
if err != nil {
|
||||
return ifErr
|
||||
}
|
||||
return dir
|
||||
},
|
||||
"getStaffNameFromID": func(id int) string {
|
||||
username, err := gcsql.GetStaffUsernameFromID(id)
|
||||
if err != nil {
|
||||
return "?"
|
||||
}
|
||||
return username
|
||||
},
|
||||
"getAppealBanIP": func(appealID int) string {
|
||||
ban, err := gcsql.GetIPBanByID(appealID)
|
||||
if err != nil || ban == nil {
|
||||
return "?"
|
||||
}
|
||||
if ban.RangeStart == ban.RangeEnd {
|
||||
return ban.RangeStart
|
||||
}
|
||||
ipn, err := gcutil.GetIPRangeSubnet(ban.RangeStart, ban.RangeEnd)
|
||||
if err != nil {
|
||||
return "?"
|
||||
}
|
||||
return ipn.String()
|
||||
},
|
||||
"getCatalogThumbnail": func(img string) string {
|
||||
_, catalogThumb := uploads.GetThumbnailFilenames(img)
|
||||
return catalogThumb
|
||||
},
|
||||
"getTopPostID": func(post *gcsql.Post) int {
|
||||
id, _ := post.TopPostID()
|
||||
return id
|
||||
},
|
||||
"getThreadThumbnail": func(img string) string {
|
||||
thumb, _ := uploads.GetThumbnailFilenames(img)
|
||||
return thumb
|
||||
},
|
||||
"getUploadType": func(name string) string {
|
||||
return uploads.GetThumbnailExtension(path.Ext(name))
|
||||
},
|
||||
"numReplies": func(boardid, opID int) int {
|
||||
num, err := gcsql.GetThreadReplyCountFromOP(opID)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return num
|
||||
},
|
||||
"getBoardDir": func(id int) string {
|
||||
dir, err := gcsql.GetBoardDir(id)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
return dir
|
||||
},
|
||||
"getBoardDefaultStyle": func(dir string) string {
|
||||
boardCfg := config.GetBoardConfig(dir)
|
||||
if !boardCfg.IsGlobal() {
|
||||
// /<board>/board.json exists, overriding the default them and theme set in SQL
|
||||
return boardCfg.DefaultStyle
|
||||
}
|
||||
var defaultStyle string
|
||||
err := gcsql.QueryRowSQL(`SELECT default_style FROM DBPREFIXboards WHERE dir = ?`,
|
||||
[]any{dir}, []any{&defaultStyle})
|
||||
if err != nil || defaultStyle == "" {
|
||||
gcutil.LogError(err).Caller().
|
||||
Str("board", dir).
|
||||
Msg("Unable to get default style attribute of board")
|
||||
return boardCfg.DefaultStyle
|
||||
}
|
||||
return defaultStyle
|
||||
},
|
||||
"boardPagePath": func(board *gcsql.Board, page int) string {
|
||||
return config.WebPath(board.Dir, strconv.Itoa(page)+".html")
|
||||
},
|
||||
"webPath": config.WebPath,
|
||||
"webPathDir": func(part ...string) string {
|
||||
dir := config.WebPath(part...)
|
||||
|
@ -261,15 +155,6 @@ var funcMap = template.FuncMap{
|
|||
}
|
||||
return dir
|
||||
},
|
||||
"sectionBoards": func(sectionID int) []gcsql.Board {
|
||||
var boards []gcsql.Board
|
||||
for _, board := range gcsql.AllBoards {
|
||||
if board.SectionID == sectionID && !board.IsHidden(false) {
|
||||
boards = append(boards, board)
|
||||
}
|
||||
}
|
||||
return boards
|
||||
},
|
||||
// Template convenience functions
|
||||
"makeLoop": func(n int, offset int) []int {
|
||||
loopArr := make([]int, n)
|
||||
|
@ -285,3 +170,11 @@ var funcMap = template.FuncMap{
|
|||
return config.GetVersion().String()
|
||||
},
|
||||
}
|
||||
|
||||
// AddTemplateFuncs adds the functions in the given FuncMap (map[string]any, with "any" expected to be a function)
|
||||
// to the map of functions available to templates
|
||||
func AddTemplateFuncs(funcs template.FuncMap) {
|
||||
for key, tFunc := range funcs {
|
||||
funcMap[key] = tFunc
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,7 +8,6 @@ import (
|
|||
"sort"
|
||||
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
"github.com/gochan-org/gochan/pkg/gcsql"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -228,12 +227,7 @@ func ParseTemplate(name, tmplStr string) (*template.Template, error) {
|
|||
|
||||
// InitTemplates loads the given templates by name. If no parameters are given,
|
||||
// all templates are (re)loaded
|
||||
func InitTemplates(which ...string) error {
|
||||
err := gcsql.ResetBoardSectionArrays()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
func InitTemplates(which ...string) (err error) {
|
||||
if which == nil {
|
||||
// no templates specified
|
||||
for t := range templateMap {
|
||||
|
|
|
@ -61,16 +61,7 @@ func checkImageFingerprintBan(img image.Image, _ string) (*gcsql.FileBan, error)
|
|||
}
|
||||
|
||||
func GetPostImageFingerprint(postID int) (string, error) {
|
||||
const query = `SELECT filename, dir
|
||||
FROM DBPREFIXfiles
|
||||
JOIN DBPREFIXposts ON post_id = DBPREFIXposts.id
|
||||
JOIN DBPREFIXthreads ON thread_id = DBPREFIXthreads.id
|
||||
JOIN DBPREFIXboards ON DBPREFIXboards.id = board_id
|
||||
WHERE DBPREFIXposts.id = ?
|
||||
LIMIT 1`
|
||||
var filename, board string
|
||||
err := gcsql.QueryRowSQL(query,
|
||||
[]any{postID}, []any{&filename, &board})
|
||||
filename, board, err := gcsql.GetUploadFilenameAndBoard(postID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
@ -82,7 +73,6 @@ func GetPostImageFingerprint(postID int) (string, error) {
|
|||
return "", ErrVideoThumbFingerprint
|
||||
}
|
||||
filename, _ = GetThumbnailFilenames(filename)
|
||||
subDir = "thumb"
|
||||
}
|
||||
filePath := path.Join(config.GetSystemCriticalConfig().DocumentRoot,
|
||||
board, subDir, filename)
|
||||
|
|
36
pkg/posting/uploads/templatefuncs.go
Normal file
36
pkg/posting/uploads/templatefuncs.go
Normal file
|
@ -0,0 +1,36 @@
|
|||
package uploads
|
||||
|
||||
import (
|
||||
"path"
|
||||
"text/template"
|
||||
|
||||
"github.com/gochan-org/gochan/pkg/config"
|
||||
"github.com/gochan-org/gochan/pkg/gcsql"
|
||||
"github.com/gochan-org/gochan/pkg/gctemplates"
|
||||
"github.com/gochan-org/gochan/pkg/gcutil"
|
||||
)
|
||||
|
||||
func init() {
|
||||
gctemplates.AddTemplateFuncs(template.FuncMap{
|
||||
"getCatalogThumbnail": func(img string) string {
|
||||
_, catalogThumb := GetThumbnailFilenames(img)
|
||||
return catalogThumb
|
||||
},
|
||||
"getThreadThumbnail": func(img string) string {
|
||||
thumb, _ := GetThumbnailFilenames(img)
|
||||
return thumb
|
||||
},
|
||||
"getUploadType": func(name string) string {
|
||||
return GetThumbnailExtension(path.Ext(name))
|
||||
},
|
||||
"getThumbnailWebPath": func(postID int) string {
|
||||
filename, board, err := gcsql.GetUploadFilenameAndBoard(postID)
|
||||
if err != nil {
|
||||
gcutil.LogError(err).Caller().Int("postID", postID).Send()
|
||||
return ""
|
||||
}
|
||||
filename, _ = GetThumbnailFilenames(filename)
|
||||
return config.WebPath(board, "thumb", filename)
|
||||
},
|
||||
})
|
||||
}
|
|
@ -5,7 +5,7 @@
|
|||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
{{with .board -}}
|
||||
{{with $.op -}}
|
||||
<title>{{$.op.TitleText}}</title>
|
||||
<title>{{.TitleText}}</title>
|
||||
{{- else}}
|
||||
<title>/{{$.board.Dir}}/ - {{$.board.Title}}</title>
|
||||
{{end}}
|
||||
|
|
|
@ -15,13 +15,13 @@
|
|||
{{- if ne .post.Email ""}}</a>{{end}}</span>
|
||||
{{- if ne .post.Tripcode ""}}<span class="tripcode">!{{.post.Tripcode}}</span>{{end -}}
|
||||
{{- if ne .post.Country.Flag ""}}{{template "post_flag" .post.Country}}{{end}} {{formatTimestamp .post.Timestamp -}}
|
||||
</label> <a href="{{.post.WebPath}}">No.</a> <a href="javascript:quote({{.post.ID}})" class="backlink-click">{{.post.ID}}</a>
|
||||
</label> <a href="{{.WebPath}}">No.</a> <a href="javascript:quote({{.post.ID}})" class="backlink-click">{{.post.ID}}</a>
|
||||
<span class="status-icons">
|
||||
{{- if $.thread.Locked -}}<img src="{{webPath "/static/lock.png"}}" class="locked-icon" alt="Thread locked" title="Thread locked">{{end -}}
|
||||
{{- if $.thread.Stickied -}}<img src="{{webPath "/static/sticky.png"}}" class="sticky-icon" alt="Sticky" title="Sticky">{{end -}}
|
||||
{{- if $.thread.Locked}}<img src="{{webPath "/static/lock.png"}}" class="locked-icon" alt="Thread locked" title="Thread locked">{{end -}}
|
||||
{{- if $.thread.Stickied}}<img src="{{webPath "/static/sticky.png"}}" class="sticky-icon" alt="Sticky" title="Sticky">{{end -}}
|
||||
</span>
|
||||
{{if $.is_board_page -}}
|
||||
[<a href="{{$.post.ThreadPath}}">View</a>]
|
||||
[<a href="{{.ThreadPath}}">View</a>]
|
||||
{{end}}<br />
|
||||
{{- end -}}
|
||||
{{- if $.post.IsTopPost -}}
|
||||
|
@ -37,7 +37,7 @@
|
|||
<div class="file-deleted-box" style="text-align:center;">File removed</div>
|
||||
{{- else if ne $.post.Filename "" -}}
|
||||
{{- template "uploadinfo" . -}}
|
||||
<a class="upload-container" href="{{.post.UploadPath}}"><img src="{{.post.ThumbnailPath}}" alt="{{.post.UploadPath}}" width="{{.post.ThumbnailWidth}}" height="{{.post.ThumbnailHeight}}" class="upload" /></a>
|
||||
<a class="upload-container" href="{{.post.UploadPath}}"><img src="{{getThumbnailWebPath .post.ID}}" alt="{{.post.UploadPath}}" width="{{.post.ThumbnailWidth}}" height="{{.post.ThumbnailHeight}}" class="upload" /></a>
|
||||
{{- end -}}
|
||||
{{- if $.post.IsTopPost}}{{template "nameline" .}}{{end -}}
|
||||
<div class="post-text">{{.post.Message}}</div>
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
{{- with .upload -}}
|
||||
<tr><th class="postblock">Filename</th><td>{{.Filename}}</td></tr>
|
||||
<tr><th class="postblock">Thumbnail</th><td>
|
||||
<img src="{{webPath $.board.Dir "thumb" (.ThumbnailPath "reply")}}" alt="{{webPath $.board.Dir "src" .Filename}}" width="{{.ThumbnailWidth}}" height="{{.ThumbnailHeight}}" class="upload" />
|
||||
<img src="{{getThumbnailWebPath $.post.ID}}" alt="{{webPath $.board.Dir "src" .Filename}}" width="{{.ThumbnailWidth}}" height="{{.ThumbnailHeight}}" class="upload" />
|
||||
</td></tr>
|
||||
{{- end -}}
|
||||
<tr><th>Spoiler</th><td><input type="checkbox" name="spoiler" id="spoiler" {{with .upload}}{{if .IsSpoilered}}checked{{end}}{{end}}></td></tr>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue