From b85b91c04de5d885c136582abcd7ab85fc7754d2 Mon Sep 17 00:00:00 2001 From: Eggbertx Date: Mon, 29 Jul 2024 21:05:03 -0700 Subject: [PATCH] Don't write file thumbnail if spoiler (otherwise it overwrites /spoiler.png) Also add spoilering for videos and non-video non-image uploads --- html/{ => static}/spoiler.png | Bin pkg/posting/uploads/attach.go | 2 ++ pkg/posting/uploads/processimage.go | 20 ++++++-------------- pkg/posting/uploads/processother.go | 9 ++++++--- pkg/posting/uploads/processvideo.go | 9 ++++++++- pkg/posting/uploads/thumbnails.go | 19 +++++++++++++++++++ 6 files changed, 41 insertions(+), 18 deletions(-) rename html/{ => static}/spoiler.png (100%) diff --git a/html/spoiler.png b/html/static/spoiler.png similarity index 100% rename from html/spoiler.png rename to html/static/spoiler.png diff --git a/pkg/posting/uploads/attach.go b/pkg/posting/uploads/attach.go index ea7af041..a09eadbb 100644 --- a/pkg/posting/uploads/attach.go +++ b/pkg/posting/uploads/attach.go @@ -178,6 +178,7 @@ func AttachUploadFromRequest(request *http.Request, writer http.ResponseWriter, Str("referer", request.Referer()) upload.IsSpoilered = request.FormValue("spoiler") == "on" + gcutil.LogBool("isSpoiler", upload.IsSpoilered, infoEv, accessEv, errEv) uploadHandler, ok := uploadHandlers[ext] if !ok { @@ -187,6 +188,7 @@ func AttachUploadFromRequest(request *http.Request, writer http.ResponseWriter, } if err = uploadHandler(upload, post, postBoard.Dir, filePath, thumbPath, catalogThumbPath, infoEv, accessEv, errEv); err != nil { + // uploadHandler is assumed to handle logging return nil, errors.New("error processing upload: " + err.Error()) } diff --git a/pkg/posting/uploads/processimage.go b/pkg/posting/uploads/processimage.go index 08e4e59d..e9c4c6ed 100644 --- a/pkg/posting/uploads/processimage.go +++ b/pkg/posting/uploads/processimage.go @@ -7,7 +7,6 @@ import ( "os" "os/exec" "path" - "syscall" "github.com/disintegration/imaging" "github.com/gochan-org/gochan/pkg/config" @@ -67,6 +66,7 @@ func processImage(upload *gcsql.Upload, post *gcsql.Post, board string, filePath Str("filePath", filePath).Send() return err } + accessEv.Str("handler", "image") // Get image width and height, as well as thumbnail width and height upload.Width = img.Bounds().Max.X @@ -77,19 +77,12 @@ func processImage(upload *gcsql.Upload, post *gcsql.Post, board string, filePath } upload.ThumbnailWidth, upload.ThumbnailHeight = getThumbnailSize(upload.Width, upload.Height, board, thumbType) - documentRoot := config.GetSystemCriticalConfig().DocumentRoot if upload.IsSpoilered { - // If spoiler is enabled, symlink thumbnail to spoiler image - if _, err := os.Stat(path.Join(documentRoot, "spoiler.png")); err != nil { - errEv.Err(err).Caller().Send() - return err - } - if err = syscall.Symlink(path.Join(documentRoot, "spoiler.png"), thumbPath); err != nil { - errEv.Err(err).Caller(). - Str("thumbPath", thumbPath). - Msg("Error creating symbolic link to thumbnail path") - return err + if err = createSpoilerThumbnail(upload, board, post.IsTopPost, thumbPath); err != nil { + errEv.Err(err).Caller().Msg("Unable to create spoiler thumbnail") + return ErrUnableToCreateSpoiler } + return nil } shouldThumb := ShouldCreateThumbnail(filePath, @@ -121,7 +114,7 @@ func processImage(upload *gcsql.Upload, post *gcsql.Post, board string, filePath // If image fits in thumbnail size, symlink thumbnail to original upload.ThumbnailWidth = img.Bounds().Max.X upload.ThumbnailHeight = img.Bounds().Max.Y - if err := syscall.Symlink(filePath, thumbPath); err != nil { + if err := os.Symlink(filePath, thumbPath); err != nil { errEv.Err(err).Caller(). Str("thumbPath", thumbPath). Msg("Couldn't generate catalog thumbnail") @@ -138,6 +131,5 @@ func processImage(upload *gcsql.Upload, post *gcsql.Post, board string, filePath } } } - accessEv.Str("handler", "image") return nil } diff --git a/pkg/posting/uploads/processother.go b/pkg/posting/uploads/processother.go index 001efe68..2c73027f 100644 --- a/pkg/posting/uploads/processother.go +++ b/pkg/posting/uploads/processother.go @@ -17,11 +17,14 @@ var ( func processOther(upload *gcsql.Upload, post *gcsql.Post, board string, filePath string, thumbPath string, catalogThumbPath string, infoEv *zerolog.Event, accessEv *zerolog.Event, errEv *zerolog.Event) error { boardConfig := config.GetBoardConfig(board) ext := path.Ext(filePath) - cfgThumb, ok := boardConfig.AllowOtherExtensions[ext] + thumbnailFilename, ok := boardConfig.AllowOtherExtensions[ext] if !ok { errEv.Err(ErrUnsupportedFileExt).Str("ext", ext).Caller().Send() return ErrUnsupportedFileExt } + if upload.IsSpoilered { + thumbnailFilename = "spoiler.png" + } infoEv.Str("post", "withOther") if post.ThreadID == 0 { @@ -33,8 +36,8 @@ func processOther(upload *gcsql.Upload, post *gcsql.Post, board string, filePath upload.ThumbnailWidth = boardConfig.ThumbWidthReply upload.ThumbnailHeight = boardConfig.ThumbHeightReply } - staticThumbPath := path.Join("static/", cfgThumb) - originalThumbPath := path.Join(config.GetSystemCriticalConfig().DocumentRoot, staticThumbPath) + originalThumbPath := path.Join(config.GetSystemCriticalConfig().DocumentRoot, "static", thumbnailFilename) + _, err := os.Stat(originalThumbPath) if err != nil { errEv.Err(err).Str("originalThumbPath", originalThumbPath).Send() diff --git a/pkg/posting/uploads/processvideo.go b/pkg/posting/uploads/processvideo.go index 1a537f3e..779ebac5 100644 --- a/pkg/posting/uploads/processvideo.go +++ b/pkg/posting/uploads/processvideo.go @@ -14,7 +14,15 @@ import ( func processVideo(upload *gcsql.Upload, post *gcsql.Post, board string, filePath string, thumbPath string, catalogThumbPath string, infoEv *zerolog.Event, accessEv *zerolog.Event, errEv *zerolog.Event) error { boardConfig := config.GetBoardConfig(board) infoEv.Str("post", "withVideo") + accessEv.Str("handler", "video") var err error + if upload.IsSpoilered { + if err = createSpoilerThumbnail(upload, board, post.IsTopPost, thumbPath); err != nil { + errEv.Err(err).Caller().Msg("Unable to create spoiler thumbnail") + return ErrUnableToCreateSpoiler + } + return nil + } if post.ThreadID == 0 { if err = createVideoThumbnail(filePath, thumbPath, boardConfig.ThumbWidth); err != nil { errEv.Err(err).Caller(). @@ -67,6 +75,5 @@ func processVideo(upload *gcsql.Upload, post *gcsql.Post, board string, filePath upload.ThumbnailWidth, upload.ThumbnailHeight = getThumbnailSize( upload.Width, upload.Height, board, thumbType) } - accessEv.Str("handler", "video") return nil } diff --git a/pkg/posting/uploads/thumbnails.go b/pkg/posting/uploads/thumbnails.go index 61347d89..cfa5f158 100644 --- a/pkg/posting/uploads/thumbnails.go +++ b/pkg/posting/uploads/thumbnails.go @@ -3,6 +3,7 @@ package uploads import ( "errors" "image" + "os" "os/exec" "path" "strconv" @@ -12,6 +13,7 @@ import ( "github.com/disintegration/imaging" "github.com/gochan-org/gochan/pkg/config" + "github.com/gochan-org/gochan/pkg/gcsql" "github.com/gochan-org/gochan/pkg/gcutil" ) @@ -32,6 +34,7 @@ var ( ".jfif": ".jpg", ".jpeg": ".jpg", } + ErrUnableToCreateSpoiler = errors.New("unable to create spoiler thumbnail") ) func GetThumbnailExtension(fileExt string) string { @@ -83,6 +86,22 @@ func createVideoThumbnail(video, thumb string, size int) error { return err } +func createSpoilerThumbnail(upload *gcsql.Upload, board string, isOP bool, thumbnailPath string) error { + boardCfg := config.GetBoardConfig(board) + spoilerPath := path.Join(config.GetSystemCriticalConfig().DocumentRoot, "static/spoiler.png") + if _, err := os.Stat(spoilerPath); err != nil { + return err + } + if isOP { + upload.ThumbnailWidth = boardCfg.ThumbWidth + upload.ThumbnailHeight = boardCfg.ThumbHeight + } else { + upload.ThumbnailWidth = boardCfg.ThumbWidthReply + upload.ThumbnailHeight = boardCfg.ThumbHeightReply + } + return os.Symlink(spoilerPath, thumbnailPath) +} + func getBoardThumbnailSize(boardDir string, thumbType ThumbnailCategory) (int, int) { boardCfg := config.GetBoardConfig(boardDir) switch thumbType {