1
0
Fork 0
mirror of https://github.com/Eggbertx/gochan.git synced 2025-09-06 11:46:24 -07:00

Add fixthumbnails manage function

This commit is contained in:
Eggbertx 2023-07-12 10:56:03 -07:00
parent 6c0926b4ec
commit c573e26399
6 changed files with 132 additions and 66 deletions

View file

@ -132,6 +132,9 @@ func GetBoardFromDir(dir string) (*Board, error) {
func GetBoardIDFromDir(dir string) (id int, err error) {
const query = `SELECT id FROM DBPREFIXboards WHERE dir = ?`
err = QueryRowSQL(query, interfaceSlice(dir), interfaceSlice(&id))
if errors.Is(err, sql.ErrNoRows) {
return 0, ErrBoardDoesNotExist
}
return id, err
}

View file

@ -11,34 +11,35 @@ import (
)
var (
Banpage *template.Template
Captcha *template.Template
Catalog *template.Template
ErrorPage *template.Template
FrontPage *template.Template
BoardPage *template.Template
JsConsts *template.Template
ManageAppeals *template.Template
ManageBans *template.Template
ManageBoards *template.Template
ManageThreadAttrs *template.Template
ManageSections *template.Template
ManageConfig *template.Template
ManageDashboard *template.Template
ManageFileBans *template.Template
ManageNameBans *template.Template
ManageIPSearch *template.Template
ManageRecentPosts *template.Template
ManageWordfilters *template.Template
ManageLogin *template.Template
ManageReports *template.Template
ManageStaff *template.Template
ManageViewLog *template.Template
MoveThreadPage *template.Template
PageHeader *template.Template
PageFooter *template.Template
PostEdit *template.Template
ThreadPage *template.Template
Banpage *template.Template
Captcha *template.Template
Catalog *template.Template
ErrorPage *template.Template
FrontPage *template.Template
BoardPage *template.Template
JsConsts *template.Template
ManageAppeals *template.Template
ManageBans *template.Template
ManageBoards *template.Template
ManageConfig *template.Template
ManageDashboard *template.Template
ManageFileBans *template.Template
ManageFixThumbnails *template.Template
ManageIPSearch *template.Template
ManageLogin *template.Template
ManageNameBans *template.Template
ManageRecentPosts *template.Template
ManageReports *template.Template
ManageSections *template.Template
ManageStaff *template.Template
ManageThreadAttrs *template.Template
ManageWordfilters *template.Template
ManageViewLog *template.Template
MoveThreadPage *template.Template
PageHeader *template.Template
PageFooter *template.Template
PostEdit *template.Template
ThreadPage *template.Template
)
func LoadTemplate(files ...string) (*template.Template, error) {
@ -236,6 +237,12 @@ func templateLoading(t string, buildAll bool) error {
return templateError("manage_viewlog.html", err)
}
}
if buildAll || t == "managefixthumbnails" {
ManageFixThumbnails, err = LoadTemplate("manage_fixthumbnails.html")
if err != nil {
return templateError("manage_viewlog.html", err)
}
}
if buildAll || t == "movethreadpage" {
MoveThreadPage, err = LoadTemplate("movethreadpage.html", "page_header.html", "topbar.html", "page_footer.html")
if err != nil {

View file

@ -26,6 +26,17 @@ var (
ErrInsufficientPermission = errors.New("insufficient account permission")
)
type uploadInfo struct {
PostID int
OpID int
Filename string
Spoilered bool
Width int
Height int
ThumbWidth int
ThumbHeight int
}
// manage actions that require admin-level permission go here
func registerAdminPages() {
@ -377,6 +388,52 @@ func registerAdminPages() {
output = pageBuffer.String()
return
}},
Action{
ID: "fixthumbnails",
Title: "Regenerate thumbnails",
Permissions: AdminPerms,
Callback: func(writer http.ResponseWriter, request *http.Request, staff *gcsql.Staff, wantsJSON bool, infoEv, errEv *zerolog.Event) (output interface{}, err error) {
board := request.FormValue("board")
var uploads []uploadInfo
if board != "" {
const query = `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,
filename, is_spoilered, width, height, thumbnail_width, thumbnail_height
FROM DBPREFIXposts p1
JOIN DBPREFIXthreads t ON t.id = p1.thread_id
JOIN DBPREFIXboards b ON b.id = t.board_id
LEFT JOIN DBPREFIXfiles f ON f.post_id = p1.id
WHERE dir = ? AND p1.is_deleted = FALSE AND filename IS NOT NULL AND filename != 'deleted'
ORDER BY created_on DESC`
rows, err := gcsql.QuerySQL(query, board)
if err != nil {
return "", err
}
defer rows.Close()
for rows.Next() {
var info uploadInfo
if err = rows.Scan(
&info.PostID, &info.OpID, &info.Filename, &info.Spoilered, &info.Width, &info.Height,
&info.ThumbWidth, &info.ThumbHeight,
); err != nil {
errEv.Err(err).Caller().Send()
return "", err
}
uploads = append(uploads, info)
}
}
buffer := bytes.NewBufferString("")
err = serverutil.MinifyTemplate(gctemplates.ManageFixThumbnails, map[string]any{
"allBoards": gcsql.AllBoards,
"board": board,
"uploads": uploads,
}, buffer, "text/html")
if err != nil {
errEv.Err(err).Str("template", "manage_fixthumbnails.html").Caller().Send()
return "", err
}
return buffer.String(), nil
},
},
Action{
ID: "rebuildfront",
Title: "Rebuild front page",

View file

@ -13,7 +13,15 @@ import (
"github.com/gochan-org/gochan/pkg/gcutil"
)
func createImageThumbnail(imageObj image.Image, boardDir string, thumbType string) image.Image {
type ThumbnailCategory int
const (
ThumbnailOP ThumbnailCategory = iota
ThumbnailReply
ThumbnailCatalog
)
func createImageThumbnail(imageObj image.Image, boardDir string, thumbType ThumbnailCategory) image.Image {
thumbWidth, thumbHeight := getBoardThumbnailSize(boardDir, thumbType)
oldRect := imageObj.Bounds()
@ -39,14 +47,14 @@ func createVideoThumbnail(video, thumb string, size int) error {
return err
}
func getBoardThumbnailSize(boardDir string, thumbType string) (int, int) {
func getBoardThumbnailSize(boardDir string, thumbType ThumbnailCategory) (int, int) {
boardCfg := config.GetBoardConfig(boardDir)
switch thumbType {
case "op":
case ThumbnailOP:
return boardCfg.ThumbWidth, boardCfg.ThumbHeight
case "reply":
case ThumbnailReply:
return boardCfg.ThumbWidthReply, boardCfg.ThumbHeightReply
case "catalog":
case ThumbnailCatalog:
return boardCfg.ThumbWidth, boardCfg.ThumbHeight
}
// todo: use reflect package to print location to error log, because this shouldn't happen
@ -54,7 +62,7 @@ func getBoardThumbnailSize(boardDir string, thumbType string) (int, int) {
}
// find out what out thumbnail's width and height should be, partially ripped from Kusaba X
func getThumbnailSize(uploadWidth, uploadHeight int, boardDir string, thumbType string) (newWidth, newHeight int) {
func getThumbnailSize(uploadWidth, uploadHeight int, boardDir string, thumbType ThumbnailCategory) (newWidth, newHeight int) {
thumbWidth, thumbHeight := getBoardThumbnailSize(boardDir, thumbType)
if uploadWidth < thumbWidth && uploadHeight < thumbHeight {
newWidth = uploadWidth
@ -74,7 +82,7 @@ func getThumbnailSize(uploadWidth, uploadHeight int, boardDir string, thumbType
}
return
}
func shouldCreateThumbnail(imgPath string, imgWidth int, imgHeight int, thumbWidth int, thumbHeight int) bool {
func ShouldCreateThumbnail(imgPath string, imgWidth int, imgHeight int, thumbWidth int, thumbHeight int) bool {
ext := strings.ToLower(path.Ext(imgPath))
if ext == ".gif" {
numFrames, err := numImageFrames(imgPath)

View file

@ -201,9 +201,9 @@ func AttachUploadFromRequest(request *http.Request, writer http.ResponseWriter,
upload.FileSize = value
}
}
thumbType := "reply"
thumbType := ThumbnailReply
if post.ThreadID == 0 {
thumbType = "op"
thumbType = ThumbnailOP
}
upload.ThumbnailWidth, upload.ThumbnailHeight = getThumbnailSize(
upload.Width, upload.Height, postBoard.Dir, thumbType)
@ -279,9 +279,9 @@ func AttachUploadFromRequest(request *http.Request, writer http.ResponseWriter,
// Get image width and height, as well as thumbnail width and height
upload.Width = img.Bounds().Max.X
upload.Height = img.Bounds().Max.Y
thumbType := "reply"
thumbType := ThumbnailReply
if post.ThreadID == 0 {
thumbType = "op"
thumbType = ThumbnailOP
}
upload.ThumbnailWidth, upload.ThumbnailHeight = getThumbnailSize(
upload.Width, upload.Height, postBoard.Dir, thumbType)
@ -308,15 +308,15 @@ func AttachUploadFromRequest(request *http.Request, writer http.ResponseWriter,
}
}
shouldThumb := shouldCreateThumbnail(filePath,
shouldThumb := ShouldCreateThumbnail(filePath,
upload.Width, upload.Height, upload.ThumbnailWidth, upload.ThumbnailHeight)
if shouldThumb {
var thumbnail image.Image
var catalogThumbnail image.Image
if post.ThreadID == 0 {
// If this is a new thread, generate thumbnail and catalog thumbnail
thumbnail = createImageThumbnail(img, postBoard.Dir, "op")
catalogThumbnail = createImageThumbnail(img, postBoard.Dir, "catalog")
thumbnail = createImageThumbnail(img, postBoard.Dir, ThumbnailOP)
catalogThumbnail = createImageThumbnail(img, postBoard.Dir, ThumbnailCatalog)
if err = imaging.Save(catalogThumbnail, catalogThumbPath); err != nil {
errEv.Err(err).Caller().
Str("thumbPath", catalogThumbPath).
@ -327,7 +327,7 @@ func AttachUploadFromRequest(request *http.Request, writer http.ResponseWriter,
return nil, true
}
} else {
thumbnail = createImageThumbnail(img, postBoard.Dir, "reply")
thumbnail = createImageThumbnail(img, postBoard.Dir, ThumbnailReply)
}
if err = imaging.Save(thumbnail, thumbPath); err != nil {
errEv.Err(err).Caller().
@ -353,7 +353,7 @@ func AttachUploadFromRequest(request *http.Request, writer http.ResponseWriter,
}
if post.ThreadID == 0 {
// Generate catalog thumbnail
catalogThumbnail := createImageThumbnail(img, postBoard.Dir, "catalog")
catalogThumbnail := createImageThumbnail(img, postBoard.Dir, ThumbnailCatalog)
if err = imaging.Save(catalogThumbnail, catalogThumbPath); err != nil {
errEv.Err(err).Caller().
Str("thumbPath", catalogThumbPath).
@ -386,30 +386,9 @@ func stripImageMetadata(filePath string, boardConfig *config.BoardConfig) (err e
return
}
// func getVideoInfo(path string) (map[string]int, error) {
// vidInfo := make(map[string]int)
// outputBytes, err := exec.Command("ffprobe", "-v quiet", "-show_format", "-show_streams", path).CombinedOutput()
// if err == nil && outputBytes != nil {
// outputStringArr := strings.Split(string(outputBytes), "\n")
// for _, line := range outputStringArr {
// lineArr := strings.Split(line, "=")
// if len(lineArr) < 2 {
// continue
// }
// if lineArr[0] == "width" || lineArr[0] == "height" || lineArr[0] == "size" {
// value, _ := strconv.Atoi(lineArr[1])
// vidInfo[lineArr[0]] = value
// }
// }
// }
// return vidInfo, err
// }
func getNewFilename() string {
now := time.Now().Unix()
rand.Seed(now)
// rand.Seed(now)
return strconv.Itoa(int(now)) + strconv.Itoa(rand.Intn(98)+1)
}

View file

@ -0,0 +1,12 @@
<form action="{{webPath "manage/fixthumbnails"}}" method="GET">
<select name="board">
{{- range $b, $board := $.allBoards -}}
<option value="{{$board.Dir}}" {{if eq $.board $board.Dir}}selected{{end}}>/{{$board.Dir}}/ - {{$board.Title}}</option>
{{- end -}}
</select>
<input type="submit" value="Select board"/>
</form>
{{range $_, $upload := $.uploads}}
Post: <a href="{{webPath $.board "res" (intToString $upload.OpID)}}.html#{{$upload.PostID}}">/{{$.board}}/{{$upload.PostID}}</a>, Filename: {{$upload.Filename}}, Spoiler: {{$upload.Spoilered}}, Image size: {{$upload.Width}}x{{$upload.Height}}, Thumb size: {{$upload.ThumbWidth}}x{{$upload.ThumbHeight}}<br/>
{{end}}