1
0
Fork 0
mirror of https://github.com/Eggbertx/gochan.git synced 2025-09-03 21:46:22 -07:00

Show link to embed video on recent posts page, show thumbnail on front page

This commit is contained in:
Eggbertx 2025-03-29 23:39:42 -07:00
parent 407eeb1a08
commit 37c73fae0d
8 changed files with 159 additions and 66 deletions

View file

@ -48,6 +48,16 @@ table#recentposts, table.filterhitslist {
}
}
table#recentposts {
td.post-upload {
text-align: center;
* {
display: inline-block;
float: none;
}
}
}
input.config-text {
-moz-box-sizing: border-box;
box-sizing: border-box;

View file

@ -420,6 +420,14 @@ table#recentposts td, table.filterhitslist td {
border: 1px solid;
}
table#recentposts td.post-upload {
text-align: center;
}
table#recentposts td.post-upload * {
display: inline-block;
float: none;
}
input.config-text {
-moz-box-sizing: border-box;
box-sizing: border-box;

View file

@ -18,8 +18,8 @@ import (
"github.com/gochan-org/gochan/pkg/gcsql"
"github.com/gochan-org/gochan/pkg/gctemplates"
"github.com/gochan-org/gochan/pkg/gcutil"
"github.com/gochan-org/gochan/pkg/posting/uploads"
"github.com/gochan-org/gochan/pkg/server/serverutil"
"github.com/rs/zerolog"
)
var (
@ -30,57 +30,108 @@ type frontPagePost struct {
Board string
URL string
ThumbURL string
Filename string
FileDeleted bool
MessageSample string
PostUploadBase
}
func getFrontPagePosts() ([]frontPagePost, error) {
func (fp *frontPagePost) HasEmbed() bool {
return strings.HasPrefix(fp.Filename, "embed:")
}
func (p *frontPagePost) GetEmbedThumbURL(board string) error {
if !p.HasEmbed() {
return nil
}
filenameParts := strings.SplitN(p.Filename, ":", 2)
if len(filenameParts) != 2 {
return fmt.Errorf("invalid embed filename: %s", p.Filename)
}
boardConfig := config.GetBoardConfig(board)
_, thumbURLTmpl, err := boardConfig.GetEmbedTemplates(filenameParts[1])
if err != nil {
return err
}
if thumbURLTmpl == nil {
return nil
}
templateData := config.EmbedTemplateData{
MediaID: p.OriginalFilename,
}
var buf bytes.Buffer
if err = thumbURLTmpl.Execute(&buf, templateData); err != nil {
return err
}
p.ThumbURL = buf.String()
return nil
}
func getFrontPagePosts(errEv *zerolog.Event) ([]frontPagePost, error) {
siteCfg := config.GetSiteConfig()
var query string
if siteCfg.RecentPostsWithNoFile {
// get recent posts, including those with no file
query = "SELECT id, message_raw, dir, filename, op_id FROM DBPREFIXv_front_page_posts"
query = "SELECT id, message_raw, dir, filename, original_filename, op_id FROM DBPREFIXv_front_page_posts"
} else {
query = "SELECT id, message_raw, dir, filename, op_id FROM DBPREFIXv_front_page_posts_with_file"
query = "SELECT id, message_raw, dir, filename, original_filename, op_id FROM DBPREFIXv_front_page_posts_with_file"
}
query += " ORDER BY id DESC LIMIT " + strconv.Itoa(siteCfg.MaxRecentPosts)
rows, cancel, err := gcsql.QueryTimeoutSQL(nil, query)
defer cancel()
if err != nil {
errEv.Err(err).Caller().Send()
return nil, err
}
defer rows.Close()
var recentPosts []frontPagePost
boardConfig := config.GetBoardConfig("")
for rows.Next() {
var post frontPagePost
var id, topPostID string
var message, boardDir, filename string
err = rows.Scan(&id, &message, &boardDir, &filename, &topPostID)
var message, boardDir, filename, originalFilename string
err = rows.Scan(&id, &message, &boardDir, &filename, &originalFilename, &topPostID)
if err != nil {
errEv.Err(err).Caller().Send()
return nil, err
}
message = bbcodeTagRE.ReplaceAllString(message, "")
if len(message) > 40 {
message = message[:37] + "..."
}
thumbnail, _ := uploads.GetThumbnailFilenames(filename)
post = frontPagePost{
Board: boardDir,
URL: config.WebPath(boardDir, "res", topPostID+".html") + "#" + id,
FileDeleted: filename == "deleted",
MessageSample: message,
}
if thumbnail != "" && !strings.HasPrefix(thumbnail, "embed:") {
post.ThumbURL = config.WebPath(boardDir, "thumb", thumbnail)
post.Filename = filename
PostUploadBase: PostUploadBase{
Filename: filename,
OriginalFilename: originalFilename,
ThumbnailWidth: boardConfig.ThumbWidthReply,
ThumbnailHeight: boardConfig.ThumbHeightReply,
},
}
if post.HasEmbed() {
if err = post.GetEmbedThumbURL(boardDir); err != nil {
errEv.Err(err).Caller().Send()
return nil, err
}
post.Filename = post.ThumbURL
}
recentPosts = append(recentPosts, post)
}
return recentPosts, rows.Close()
if err = rows.Close(); err != nil {
errEv.Err(err).Caller().Send()
return nil, err
}
return recentPosts, nil
}
// BuildFrontPage builds the front page using templates/front.html
@ -107,7 +158,7 @@ func BuildFrontPage() error {
var recentPostsArr []frontPagePost
siteCfg := config.GetSiteConfig()
recentPostsArr, err = getFrontPagePosts()
recentPostsArr, err = getFrontPagePosts(errEv)
if err != nil {
errEv.Err(err).Caller().Send()
return fmt.Errorf("failed loading recent posts: %w", err)

View file

@ -26,26 +26,59 @@ func truncateString(msg string, limit int, ellipsis bool) string {
return msg
}
type PostUploadBase struct {
Filename string `json:"tim"`
OriginalFilename string `json:"filename"`
ThumbnailWidth int `json:"tn_w"`
ThumbnailHeight int `json:"tn_h"`
uploadPath string
}
func (p *PostUploadBase) HasEmbed() bool {
return strings.HasPrefix(p.Filename, "embed:")
}
func (p *PostUploadBase) GetEmbedURL(boardDir string) string {
if !p.HasEmbed() {
return ""
}
filenameParts := strings.SplitN(p.Filename, ":", 2)
if len(filenameParts) != 2 {
p.uploadPath = "#invalid-embed-ID"
return p.uploadPath
}
linkTmpl, err := config.GetBoardConfig(boardDir).GetLinkTemplate(filenameParts[1])
if err != nil {
p.uploadPath = "#invalid-template"
return p.uploadPath
}
var buf bytes.Buffer
if err = linkTmpl.Execute(&buf, &config.EmbedTemplateData{MediaID: p.OriginalFilename}); err != nil {
p.uploadPath = "#template-error"
return p.uploadPath
}
p.uploadPath = buf.String()
return p.uploadPath
}
// Post represents a post in a thread for building (hence why ParentID is used instead of ThreadID)
type Post struct {
gcsql.Post
ParentID int `json:"resto"`
BoardID int `json:"-"`
BoardDir string `json:"-"`
IP net.IP `json:"-"`
Filename string `json:"tim"`
OriginalFilename string `json:"filename"`
Checksum string `json:"md5"`
Extension string `json:"extension"`
Filesize int `json:"fsize"`
UploadWidth int `json:"w"`
UploadHeight int `json:"h"`
ThumbnailWidth int `json:"tn_w"`
ThumbnailHeight int `json:"tn_h"`
LastModified string `json:"last_modified"`
Country geoip.Country `json:"-"`
thread gcsql.Thread
uploadPath string
ParentID int `json:"resto"`
BoardID int `json:"-"`
BoardDir string `json:"-"`
IP net.IP `json:"-"`
PostUploadBase
Checksum string `json:"md5"`
Extension string `json:"extension"`
Filesize int `json:"fsize"`
UploadWidth int `json:"w"`
UploadHeight int `json:"h"`
LastModified string `json:"last_modified"`
Country geoip.Country `json:"-"`
thread gcsql.Thread
uploadPath string
}
// TitleText returns the text to be used for the title of the page
@ -79,10 +112,6 @@ func (p *Post) WebPath() string {
return p.ThreadPath() + "#" + strconv.Itoa(p.ID)
}
func (p *Post) HasEmbed() bool {
return strings.HasPrefix(p.Filename, "embed:")
}
func (p *Post) ThumbnailPath() string {
if p.Filename == "" || p.HasEmbed() {
return ""
@ -99,22 +128,7 @@ func (p *Post) UploadPath() string {
return p.uploadPath
}
if p.HasEmbed() {
filenameParts := strings.SplitN(p.Filename, ":", 2)
if len(filenameParts) != 2 {
p.uploadPath = "#invalid-embed-ID"
return p.uploadPath
}
linkTmpl, err := config.GetBoardConfig(p.BoardDir).GetLinkTemplate(filenameParts[1])
if err != nil {
p.uploadPath = "#invalid-template"
return p.uploadPath
}
var buf bytes.Buffer
if err = linkTmpl.Execute(&buf, &config.EmbedTemplateData{MediaID: p.OriginalFilename}); err != nil {
p.uploadPath = "#template-error"
return p.uploadPath
}
p.uploadPath = buf.String()
return p.GetEmbedURL(p.BoardDir)
} else {
p.uploadPath = config.WebPath(p.BoardDir, "src", p.Filename)
}

View file

@ -80,7 +80,9 @@ func recentPostsCallback(_ http.ResponseWriter, request *http.Request, _ *gcsql.
if limitStr != "" {
limit, err = strconv.Atoi(limitStr)
if err != nil {
errEv.Err(err).Caller().Send()
errEv.Err(err).Caller().
Str("limit", limitStr).
Msg("Invalid limit value")
return "", err
}
}
@ -89,7 +91,9 @@ func recentPostsCallback(_ http.ResponseWriter, request *http.Request, _ *gcsql.
var boardid int
if boardidStr != "" {
if boardid, err = strconv.Atoi(boardidStr); err != nil {
errEv.Err(err).Caller().Send()
errEv.Err(err).Caller().
Str("boardid", boardidStr).
Msg("Invalid boardid value")
return "", err
}
}
@ -101,17 +105,17 @@ func recentPostsCallback(_ http.ResponseWriter, request *http.Request, _ *gcsql.
if wantsJSON {
return recentposts, nil
}
manageRecentsBuffer := bytes.NewBufferString("")
var buf bytes.Buffer
if err = serverutil.MinifyTemplate(gctemplates.ManageRecentPosts, map[string]any{
"recentposts": recentposts,
"allBoards": gcsql.AllBoards,
"boardid": boardid,
"limit": limit,
}, manageRecentsBuffer, "text/html"); err != nil {
}, &buf, "text/html"); err != nil {
errEv.Err(err).Caller().Send()
return "", fmt.Errorf("failed executing ban management page template: %w", err)
}
return manageRecentsBuffer.String(), nil
return buf.String(), nil
}
func announcementsCallback(_ http.ResponseWriter, _ *http.Request, _ *gcsql.Staff, _ bool, _ *zerolog.Event, _ *zerolog.Event) (output any, err error) {

View file

@ -67,16 +67,17 @@ WHERE p.is_deleted = 0 AND d.is_top_post = 0 and t.cyclical = 1;
CREATE VIEW DBPREFIXv_front_page_posts AS
SELECT DBPREFIXposts.id, DBPREFIXposts.message_raw,
(SELECT dir FROM DBPREFIXboards WHERE id = t.board_id) as dir,
COALESCE(f.filename, '') as filename, op.id as op_id
COALESCE(f.filename, '') as filename, op.id as op_id,
COALESCE(f.original_filename, '') as original_filename
FROM DBPREFIXposts
LEFT JOIN DBPREFIXv_thread_board_ids t ON t.id = DBPREFIXposts.thread_id
LEFT JOIN (SELECT post_id, filename FROM DBPREFIXfiles) f on f.post_id = DBPREFIXposts.id
LEFT JOIN (SELECT post_id, filename, original_filename FROM DBPREFIXfiles) f on f.post_id = DBPREFIXposts.id
INNER JOIN DBPREFIXv_top_post_thread_ids op ON op.thread_id = DBPREFIXposts.thread_id
WHERE DBPREFIXposts.is_deleted = FALSE;
CREATE VIEW DBPREFIXv_front_page_posts_with_file AS
SELECT * FROM DBPREFIXv_front_page_posts
WHERE filename IS NOT NULL AND filename <> '' AND filename <> 'deleted' and filename not like 'embed:%';
WHERE filename IS NOT NULL AND filename <> '' AND filename <> 'deleted';
CREATE VIEW DBPREFIXv_upload_info AS
SELECT p1.id as id, (SELECT id FROM DBPREFIXposts p2 WHERE p2.is_top_post AND p1.thread_id = p2.thread_id LIMIT 1) AS op,

View file

@ -33,9 +33,11 @@
<div id="recent-posts">
{{- range $i, $post := $.recentPosts}}
<div class="recent-post">
{{if and (not $post.FileDeleted) (ne $post.Filename "") -}}
<a href="{{$post.URL}}" class="front-reply" target="_blank"><img src="{{$post.ThumbURL}}" alt="post thumbnail"/></a><br />
{{else}}
{{if $post.HasEmbed -}}
<div class="file-deleted-box"><a href="{{$post.URL}}" class="front-reply" target="_blank">Post Embed</a></div>
{{- else if and (not $post.FileDeleted) (ne $post.Filename "") -}}
<a href="{{$post.URL}}" class="front-reply" target="_blank"><img src="{{$post.ThumbURL}}" alt="post thumbnail" {{if gt $post.ThumbnailWidth 0}}width="{{$post.ThumbnailWidth}}" height="{{$post.ThumbnailHeight}}"{{end}}/></a><br />
{{- else -}}
<div class="file-deleted-box"><a href="{{$post.URL}}" class="front-reply" target="_blank">No file</a></div>
{{- end}}<br />
<a href="{{webPathDir $post.Board}}">/{{$post.Board}}/</a><hr />

View file

@ -22,10 +22,13 @@
<b>Board: </b>/{{$post.BoardDir}}/
</td>
<td>{{$post.Message}}</td>
<td>
<td class="post-upload">
{{- if eq $post.Filename "deleted" -}}
<div class="file-deleted-box centered" style="text-align:center;">File removed</div>
<div class="file-deleted-box" style="float:none;">File removed</div>
{{- else if $post.HasEmbed -}}
<div class="file-deleted-box"><a href="{{$post.UploadPath}}" target="_blank">Embed</a></div>
{{- else if ne $post.Filename "" -}}
<a href="{{$post.UploadPath}}" target="_blank" class="centered"><img src="{{$post.ThumbnailPath}}"></a>
{{end}}</td></tr>{{end}}
<a href="{{$post.UploadPath}}" target="_blank" class="centered"><img src="{{$post.ThumbnailPath}}"></a>
{{- end -}}
</td></tr>{{end}}
</table>