bf851bd9fc
Added support for dyntmpl to the template system. The Account Dashboard now sort of uses dyntmpl, more work needed here. Renamed the pre_render_view_topic hook to pre_render_topic. Added the GetCurrentLangPack() function. Added the alerts_no_new_alerts phrase. Added the account_level_list phrase. Refactored the route rename logic in the patcher to cut down on the amount of boilerplate. Added more route renames to the patcher. You will need to run the patcher / updater in this commit.
146 lines
3.7 KiB
Go
146 lines
3.7 KiB
Go
package common
|
|
|
|
import (
|
|
"image"
|
|
"image/gif"
|
|
"image/jpeg"
|
|
_ "image/png"
|
|
"os"
|
|
"strconv"
|
|
|
|
"github.com/Azareal/Gosora/query_gen"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
func ThumbTask(thumbChan chan bool) {
|
|
for {
|
|
// Put this goroutine to sleep until we have work to do
|
|
<-thumbChan
|
|
|
|
// TODO: Use a real queue
|
|
acc := qgen.NewAcc()
|
|
err := acc.Select("users_avatar_queue").Columns("uid").Limit("0,5").EachInt(func(uid int) error {
|
|
// TODO: Do a bulk user fetch instead?
|
|
user, err := Users.Get(uid)
|
|
if err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
// Has the avatar been removed or already been processed by the thumbnailer?
|
|
if len(user.RawAvatar) < 2 || user.RawAvatar[1] == '.' {
|
|
_, _ = acc.Delete("users_avatar_queue").Where("uid = ?").Run(uid)
|
|
return nil
|
|
}
|
|
// This means it's an external image, they aren't currently implemented, but this is here for when they are
|
|
if user.RawAvatar[0] != '.' {
|
|
return nil
|
|
}
|
|
/*if user.RawAvatar == ".gif" {
|
|
return nil
|
|
}*/
|
|
if user.RawAvatar != ".png" && user.RawAvatar != ".jpg" && user.RawAvatar != ".jpeg" && user.RawAvatar != ".gif" {
|
|
return nil
|
|
}
|
|
|
|
err = Thumbnailer.Resize(user.RawAvatar[1:], "./uploads/avatar_"+strconv.Itoa(user.ID)+user.RawAvatar, "./uploads/avatar_"+strconv.Itoa(user.ID)+"_tmp"+user.RawAvatar, "./uploads/avatar_"+strconv.Itoa(user.ID)+"_w48"+user.RawAvatar, 48)
|
|
if err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
|
|
err = user.ChangeAvatar("." + user.RawAvatar)
|
|
if err != nil {
|
|
return errors.WithStack(err)
|
|
}
|
|
_, err = acc.Delete("users_avatar_queue").Where("uid = ?").Run(uid)
|
|
return errors.WithStack(err)
|
|
})
|
|
if err != nil {
|
|
LogError(err)
|
|
}
|
|
if err = acc.FirstError(); err != nil {
|
|
LogError(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
var Thumbnailer ThumbnailerInt
|
|
|
|
type ThumbnailerInt interface {
|
|
Resize(format string, inPath string, tmpPath string, outPath string, width int) error
|
|
}
|
|
|
|
type RezThumbnailer struct {
|
|
}
|
|
|
|
func (thumb *RezThumbnailer) Resize(format string, inPath string, tmpPath string, outPath string, width int) error {
|
|
// TODO: Sniff the aspect ratio of the image and calculate the dest height accordingly, bug make sure it isn't excessively high
|
|
return nil
|
|
}
|
|
|
|
func (thumb *RezThumbnailer) resize(format string, inPath string, outPath string, width int, height int) error {
|
|
return nil
|
|
}
|
|
|
|
// ! Note: CaireThumbnailer can't handle gifs, so we'll have to either cap their sizes or have another resizer deal with them
|
|
type CaireThumbnailer struct {
|
|
}
|
|
|
|
func NewCaireThumbnailer() *CaireThumbnailer {
|
|
return &CaireThumbnailer{}
|
|
}
|
|
|
|
func precodeImage(format string, inPath string, tmpPath string) error {
|
|
imageFile, err := os.Open(inPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer imageFile.Close()
|
|
|
|
img, _, err := image.Decode(imageFile)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
outFile, err := os.Create(tmpPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer outFile.Close()
|
|
|
|
// TODO: Make sure animated gifs work after being encoded
|
|
if format == "gif" {
|
|
return gif.Encode(outFile, img, nil)
|
|
}
|
|
return jpeg.Encode(outFile, img, nil)
|
|
}
|
|
|
|
func (thumb *CaireThumbnailer) Resize(format string, inPath string, tmpPath string, outPath string, width int) error {
|
|
err := precodeImage(format, inPath, tmpPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
|
|
// TODO: Caire doesn't work. Try something else. Or get them to fix the index out of range. We get enough wins from re-encoding as jpeg anyway
|
|
/*imageFile, err := os.Open(tmpPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer imageFile.Close()
|
|
|
|
outFile, err := os.Create(outPath)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer outFile.Close()
|
|
|
|
p := &caire.Processor{NewWidth: width, Scale: true}
|
|
return p.Process(imageFile, outFile)*/
|
|
}
|
|
|
|
/*
|
|
type LilliputThumbnailer struct {
|
|
|
|
}
|
|
*/
|