From 5fa24f5014887f34744d4a12f348afa689571ac3 Mon Sep 17 00:00:00 2001 From: Hugefiver Date: Thu, 26 Dec 2024 16:03:01 +0800 Subject: [PATCH 01/12] fix(sticker): remove illegal filename chars (#508) --- base/sticker.go | 26 +++++++++++++++++++++++--- go.mod | 4 ++-- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/base/sticker.go b/base/sticker.go index a9a039c..043d29c 100644 --- a/base/sticker.go +++ b/base/sticker.go @@ -7,7 +7,6 @@ import ( "context" "errors" "fmt" - "golang.org/x/sync/errgroup" "image" "image/gif" "image/jpeg" @@ -15,12 +14,15 @@ import ( "io" "os" "path" + "regexp" "runtime" "slices" "strings" "sync" "time" + "golang.org/x/sync/errgroup" + ffmpeg_go "github.com/u2takey/ffmpeg-go" // nolint: revive _ "golang.org/x/image/webp" @@ -36,6 +38,22 @@ import ( "csust-got/util/ffconv" ) +// var illegalFilenameChars = []string{"\\", "/", ":", "*", "?", "\"", "'", "<", ">", "|", "\t", "\n", "\r", "\u0000", "\ufffd"} +var illegalFilenameCharsPatt = regexp.MustCompile(`[\\/:*?"'<>|\t\n\r\x00\xfffd]+`) + +func replaceIllegalFilenameChars(s string, replacer func(in string) string) string { + if illegalFilenameCharsPatt.FindStringIndex(s) == nil { + return s + } + return illegalFilenameCharsPatt.ReplaceAllStringFunc(s, replacer) +} + +func replaceIllegalFilenameCharsWithString(s string, r string) string { + return replaceIllegalFilenameChars(s, func(in string) string { + return r + }) +} + type stickerOpts struct { format string pack bool @@ -198,7 +216,7 @@ func GetSticker(ctx tb.Context) error { } if !opt.pack { - filename := sticker.SetName + filename := replaceIllegalFilenameCharsWithString(sticker.SetName, "_") emoji := sticker.Emoji if sticker.CustomEmoji != "" { emoji += " " + sticker.CustomEmoji @@ -660,8 +678,10 @@ loop: _ = packFile.Close() cpFile := tb.FromDisk(packFile.Name()) + setName := replaceIllegalFilenameCharsWithString(stickerSet.Name, "_") + setTitle := replaceIllegalFilenameCharsWithString(stickerSet.Title, "_") err = ctx.Reply(&tb.Document{ - FileName: fmt.Sprintf("%s-%s%s", stickerSet.Name, stickerSet.Title, ".zip"), + FileName: fmt.Sprintf("%s-%s%s", setName, setTitle, ".zip"), File: cpFile, }) if errors.Is(err, tb.ErrTooLarge) { diff --git a/go.mod b/go.mod index 6ce3e97..7724856 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( go.uber.org/zap v1.27.0 golang.org/x/image v0.23.0 golang.org/x/net v0.33.0 + golang.org/x/sync v0.10.0 golang.org/x/text v0.21.0 golang.org/x/time v0.8.0 gopkg.in/telebot.v3 v3.3.8 @@ -24,7 +25,6 @@ require ( require ( github.com/andybalholm/brotli v1.1.0 // indirect github.com/go-task/slim-sprig/v3 v3.0.0 // indirect - golang.org/x/sync v0.10.0 // indirect ) require ( @@ -72,5 +72,5 @@ require ( golang.org/x/tools v0.26.0 // indirect google.golang.org/protobuf v1.35.2 // indirect gopkg.in/ini.v1 v1.67.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + gopkg.in/yaml.v3 v3.0.1 ) From b529e06cc8f5a454955b8237ffbb4e944b514f21 Mon Sep 17 00:00:00 2001 From: Hugefiver Date: Thu, 26 Dec 2024 16:33:10 +0800 Subject: [PATCH 02/12] fix: not log to stderr issue --- config/config.go | 4 +--- log/log.go | 21 +++++++++++++++------ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/config/config.go b/config/config.go index 8530697..1ac90ae 100644 --- a/config/config.go +++ b/config/config.go @@ -153,9 +153,7 @@ func checkConfig() { if BotConfig.SkipDuration < 0 { BotConfig.SkipDuration = 0 } - if BotConfig.LogFileDir == "" { - BotConfig.LogFileDir = "logs" - } + BotConfig.LogFileDir = strings.TrimRight(BotConfig.LogFileDir, "/") BotConfig.RedisConfig.checkConfig() diff --git a/log/log.go b/log/log.go index 2dbd187..4b57fe2 100644 --- a/log/log.go +++ b/log/log.go @@ -5,6 +5,7 @@ import ( "csust-got/prom" "os" + "github.com/samber/lo" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) @@ -21,8 +22,10 @@ func InitLogger() { func NewLogger() *zap.Logger { var logConfig zap.Config // create log dir if not exists - if err := os.MkdirAll(config.BotConfig.LogFileDir, 0755); err != nil { - zap.L().Fatal("Create log dir failed", zap.Error(err)) + if config.BotConfig.LogFileDir != "" { + if err := os.MkdirAll(config.BotConfig.LogFileDir, 0755); err != nil { + zap.L().Fatal("Create log dir failed", zap.Error(err)) + } } if config.BotConfig.DebugMode { logConfig = devConfig() @@ -39,6 +42,9 @@ func NewLogger() *zap.Logger { } func devConfig() zap.Config { + logPath := lo.FilterMap([]string{config.BotConfig.LogFileDir}, func(p string, _ int) (string, bool) { + return p, p != "" + }) return zap.Config{ Level: zap.NewAtomicLevelAt(zap.DebugLevel), Development: true, @@ -57,12 +63,15 @@ func devConfig() zap.Config { EncodeDuration: zapcore.StringDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder, }, - OutputPaths: []string{"stderr", config.BotConfig.LogFileDir + "/got.log"}, - ErrorOutputPaths: []string{"stderr", config.BotConfig.LogFileDir + "/got_err.log"}, + OutputPaths: append(lo.Map(logPath, func(p string, _ int) string { return p + "/got.log" }), "stderr"), + ErrorOutputPaths: append(lo.Map(logPath, func(p string, _ int) string { return p + "/got_err.log" }), "stderr"), } } func prodConfig() zap.Config { + logPath := lo.FilterMap([]string{config.BotConfig.LogFileDir}, func(p string, _ int) (string, bool) { + return p, p != "" + }) return zap.Config{ Level: zap.NewAtomicLevelAt(zap.InfoLevel), Development: false, @@ -85,8 +94,8 @@ func prodConfig() zap.Config { EncodeDuration: zapcore.SecondsDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder, }, - OutputPaths: []string{"stderr", config.BotConfig.LogFileDir + "/got.log"}, - ErrorOutputPaths: []string{"stderr", config.BotConfig.LogFileDir + "/got_err.log"}, + OutputPaths: append(lo.Map(logPath, func(p string, _ int) string { return p + "/got.log" }), "stderr"), + ErrorOutputPaths: append(lo.Map(logPath, func(p string, _ int) string { return p + "/got_err.log" }), "stderr"), } } From 61943aac627c84d1740d8473263e86905f92ec97 Mon Sep 17 00:00:00 2001 From: Hugefiver Date: Thu, 26 Dec 2024 16:43:40 +0800 Subject: [PATCH 03/12] dockerfile: use ghcr ffmpeg image --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index c3653b4..afa1746 100644 --- a/Dockerfile +++ b/Dockerfile @@ -23,7 +23,7 @@ RUN make deploy FROM --platform=$BUILDPLATFORM alpine RUN apk add --no-cache tzdata -COPY --from=hugefiver/ffmpeg:7.1 /ffmpeg /usr/local/bin/ffmpeg +COPY --from=ghcr.io/hugefiver/static-ffmpeg:latest /ffmpeg /usr/local/bin/ffmpeg # COPY --from=hugefiver/ffmpeg:7.0.1 /ffprobe /usr/local/bin/ffprobe WORKDIR /app From 543ac558a0fd5845a5efd64c1f3b1ae5f69d0c66 Mon Sep 17 00:00:00 2001 From: Hugefiver Date: Thu, 26 Dec 2024 16:48:40 +0800 Subject: [PATCH 04/12] add logs --- base/sticker.go | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/base/sticker.go b/base/sticker.go index 043d29c..7ee6d87 100644 --- a/base/sticker.go +++ b/base/sticker.go @@ -43,9 +43,12 @@ var illegalFilenameCharsPatt = regexp.MustCompile(`[\\/:*?"'<>|\t\n\r\x00\xfffd] func replaceIllegalFilenameChars(s string, replacer func(in string) string) string { if illegalFilenameCharsPatt.FindStringIndex(s) == nil { + log.Debug("no illegal filename chars found in string", zap.String("s", s)) return s } - return illegalFilenameCharsPatt.ReplaceAllStringFunc(s, replacer) + r := illegalFilenameCharsPatt.ReplaceAllStringFunc(s, replacer) + log.Debug("replace illegal filename chars", zap.String("s", s), zap.String("ret", r)) + return r } func replaceIllegalFilenameCharsWithString(s string, r string) string { From f2c03af424645aa2733506121350df40f80e2263 Mon Sep 17 00:00:00 2001 From: Hugefiver Date: Thu, 26 Dec 2024 17:05:05 +0800 Subject: [PATCH 05/12] fix regexp bug & normalize `iwant` options --- base/sticker.go | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/base/sticker.go b/base/sticker.go index 7ee6d87..7424783 100644 --- a/base/sticker.go +++ b/base/sticker.go @@ -39,7 +39,7 @@ import ( ) // var illegalFilenameChars = []string{"\\", "/", ":", "*", "?", "\"", "'", "<", ">", "|", "\t", "\n", "\r", "\u0000", "\ufffd"} -var illegalFilenameCharsPatt = regexp.MustCompile(`[\\/:*?"'<>|\t\n\r\x00\xfffd]+`) +var illegalFilenameCharsPatt = regexp.MustCompile(`[\\/:*?"'<>|\t\n\r\x00\x{fffd}]+`) func replaceIllegalFilenameChars(s string, replacer func(in string) string) string { if illegalFilenameCharsPatt.FindStringIndex(s) == nil { @@ -714,14 +714,15 @@ func parseOpts(text string) (map[string]string, error) { switch strings.ToLower(k) { case "format", "f": f := strings.ToLower(v) + // check available formats if slices.Contains([]string{"", "webp", "jpg", "jpeg", "png", "apng", "mp4", "gif", "webm"}, f) { ret[k] = v } case "pack", "p": - if slices.Contains([]string{"", "true", "1"}, strings.ToLower(v)) { - ret[k] = "true" - } else if strings.ToLower(v) == "false" { + if v == "false" { ret[k] = "false" + } else { + ret[k] = "true" } case "vf", "videoformat": f := strings.ToLower(v) @@ -743,12 +744,22 @@ func normalizeParams(k, v string) (bool, string, string) { switch k { case "format", "f": k = "format" + case "!pack", "!p", "nopack", "pack!", "p!": + v = "false" + fallthrough case "pack", "p": k = "pack" + if strings.ToLower(v) == "false" { + v = "false" + } else { + v = "true" + } case "vf", "videoformat": k = "videoformat" case "sf", "stickerformat": k = "stickerformat" + case "pf", "packformat": + k = "packformat" default: return false, k, v } From fe8fd47949059b16799a4952bcebd09c666b066e Mon Sep 17 00:00:00 2001 From: Hugefiver Date: Thu, 26 Dec 2024 18:12:39 +0800 Subject: [PATCH 06/12] feat(sticker): add file cache --- .golangci.yaml | 1 + base/sticker.go | 152 +++++++++++++++++++++++++++++++++++++++--------- orm/redis.go | 49 ++++++++++++++++ 3 files changed, 174 insertions(+), 28 deletions(-) diff --git a/.golangci.yaml b/.golangci.yaml index 2ef7749..81f03e7 100644 --- a/.golangci.yaml +++ b/.golangci.yaml @@ -495,6 +495,7 @@ linters-settings: - github.com/gabriel-vasile/mimetype - github.com/u2takey/ffmpeg-go - github.com/samber/lo + - github.com/cespare/xxhash/v2 # Packages that are not allowed where the value is a suggestion. deny: # - pkg: "github.com/sirupsen/logrus" diff --git a/base/sticker.go b/base/sticker.go index 7424783..68717cc 100644 --- a/base/sticker.go +++ b/base/sticker.go @@ -5,6 +5,7 @@ import ( "archive/zip" "bytes" "context" + "encoding/json" "errors" "fmt" "image" @@ -23,7 +24,9 @@ import ( "golang.org/x/sync/errgroup" + "github.com/cespare/xxhash/v2" ffmpeg_go "github.com/u2takey/ffmpeg-go" + // nolint: revive _ "golang.org/x/image/webp" @@ -58,19 +61,21 @@ func replaceIllegalFilenameCharsWithString(s string, r string) string { } type stickerOpts struct { - format string - pack bool - vf string - sf string + Format string `json:"format"` + Pack bool `json:"pack"` + Vf string `json:"videoformat"` + Sf string `json:"stickerformat"` // pack format pf string + + nocache bool } func defaultOpts() stickerOpts { return stickerOpts{ - format: "", - pack: false, + Format: "", + Pack: false, } } @@ -80,6 +85,7 @@ func defaultOptsWithConfig(m map[string]string) stickerOpts { return o } +// nolint: gocritic func (o stickerOpts) merge(m map[string]string, final bool) stickerOpts { if final { sets := make(map[string]struct{}, len(m)) @@ -92,11 +98,11 @@ func (o stickerOpts) merge(m map[string]string, final bool) stickerOpts { if _, ok := sets["format"]; ok { if _, ok = sets["videoformat"]; !ok { - o.vf = "" + o.Vf = "" } if _, ok = sets["stickerformat"]; !ok { - o.sf = "" + o.Sf = "" } } } @@ -105,39 +111,49 @@ func (o stickerOpts) merge(m map[string]string, final bool) stickerOpts { k = strings.ToLower(k) switch k { case "format", "f": - o.format = v + o.Format = v case "pack", "p": if slices.Contains([]string{"", "true", "1"}, strings.ToLower(v)) { - o.pack = true + o.Pack = true } else if strings.ToLower(v) == "false" { - o.pack = false + o.Pack = false } case "vf", "videoformat": - o.vf = v + o.Vf = v case "sf", "stickerformat": - o.sf = v + o.Sf = v case "pf", "packformat": o.pf = v + case "nocache": + if strings.ToLower(v) == "false" { + o.nocache = false + } else if final { + // only final can do + o.nocache = true + } } } return o } +// nolint: gocritic func (o stickerOpts) VideoFormat() string { - if o.vf != "" { - return o.vf + if o.Vf != "" { + return o.Vf } - return o.format + return o.Format } +// nolint: gocritic func (o stickerOpts) StickerFormat() string { - if o.sf != "" { - return o.sf + if o.Sf != "" { + return o.Sf } - return o.format + return o.Format } +// nolint: gocritic func (o stickerOpts) FileExt(video bool) string { if video { f := o.VideoFormat() @@ -156,6 +172,7 @@ func (o stickerOpts) FileExt(video bool) string { return "." + f } +// nolint: gocritic func (o stickerOpts) NotConvert(s *tb.Sticker) bool { if s.Video { switch o.VideoFormat() { @@ -218,7 +235,7 @@ func GetSticker(ctx tb.Context) error { opt = opt.merge(o, true) } - if !opt.pack { + if !opt.Pack { filename := replaceIllegalFilenameCharsWithString(sticker.SetName, "_") emoji := sticker.Emoji if sticker.CustomEmoji != "" { @@ -227,15 +244,15 @@ func GetSticker(ctx tb.Context) error { // send video is sticker is video if sticker.Video { - return sendVideoSticker(ctx, sticker, filename, emoji, opt) + return sendVideoSticker(ctx, sticker, filename, emoji, &opt) } - return sendImageSticker(ctx, sticker, filename, emoji, opt) + return sendImageSticker(ctx, sticker, filename, emoji, &opt) } - return sendStickerPack(ctx, sticker, opt) + return sendStickerPack(ctx, sticker, &opt) } -func sendImageSticker(ctx tb.Context, sticker *tb.Sticker, filename string, emoji string, opt stickerOpts) error { +func sendImageSticker(ctx tb.Context, sticker *tb.Sticker, filename string, emoji string, opt *stickerOpts) error { f := opt.StickerFormat() reader, err := ctx.Bot().File(&sticker.File) @@ -309,7 +326,7 @@ func sendImageSticker(ctx tb.Context, sticker *tb.Sticker, filename string, emoj return ctx.Reply(sendFile) } -func sendVideoSticker(ctx tb.Context, sticker *tb.Sticker, filename string, emoji string, opt stickerOpts) error { +func sendVideoSticker(ctx tb.Context, sticker *tb.Sticker, filename string, emoji string, opt *stickerOpts) error { f := opt.VideoFormat() reader, err := ctx.Bot().File(&sticker.File) @@ -422,13 +439,43 @@ func sendVideoSticker(ctx tb.Context, sticker *tb.Sticker, filename string, emoj } } -func sendStickerPack(ctx tb.Context, sticker *tb.Sticker, opt stickerOpts) error { +func sendStickerPack(ctx tb.Context, sticker *tb.Sticker, opt *stickerOpts) error { stickerSet, err := ctx.Bot().StickerSet(sticker.SetName) if err != nil { err2 := ctx.Reply("failed to get sticker set") return errors.Join(err, err2) } + if !opt.nocache { + keys, err := getFileCacheKeys(stickerSet.Name, opt) + if err != nil { + log.Error("failed to get file cache keys", zap.Error(err)) + goto process + } + + fileCache, err := orm.GetFileCache(keys, time.Hour*24*7) + if err == nil && fileCache != nil && fileCache.FileId != "" { + file, err := ctx.Bot().FileByID(fileCache.FileId) + if err != nil { + log.Error("failed to get file by id", zap.Error(err)) + goto process + } + err = ctx.Reply(&tb.Document{ + FileName: fileCache.Filename, + File: file, + }) + if err != nil { + log.Error("failed to send file", zap.Error(err)) + return ctx.Reply("failed to send file") + } + + return nil + } + log.Error("failed to get file cache, continue process", zap.Error(err)) + } + +process: + // TODO support other compression format // pf := opt.pf // if pf == "" { @@ -683,19 +730,61 @@ loop: cpFile := tb.FromDisk(packFile.Name()) setName := replaceIllegalFilenameCharsWithString(stickerSet.Name, "_") setTitle := replaceIllegalFilenameCharsWithString(stickerSet.Title, "_") - err = ctx.Reply(&tb.Document{ + respMsg, err := ctx.Bot().Send(ctx.Recipient(), &tb.Document{ FileName: fmt.Sprintf("%s-%s%s", setName, setTitle, ".zip"), File: cpFile, - }) + }, &tb.SendOptions{ReplyTo: ctx.Message(), AllowWithoutReply: true}) if errors.Is(err, tb.ErrTooLarge) { if fileInfo != nil { return ctx.Reply(fmt.Sprintf("太...太大了...有%.2fMB辣么大", float64(fileInfo.Size())/1024/1024)) } return ctx.Reply("太大了,反正就是大") } + if doc := respMsg.Document; doc != nil { + fileCache := &orm.FileCache{ + FileId: doc.FileID, + Filename: doc.FileName, + } + + keys, err := getFileCacheKeys(setName, opt) + if err != nil { + log.Error("failed to get file cache keys", zap.Error(err)) + return err + } + + err = orm.SetFileCache(keys, fileCache, time.Hour*24*7) + if err != nil { + log.Error("failed to set file cache", zap.Error(err)) + return err + } + } else { + log.Info("cannot get file of sent document", zap.Any("respMsg", respMsg)) + } return err } +func getFileCacheKeys(setName string, opt *stickerOpts) ([]string, error) { + keys := make([]string, 0, 2) + + // key 1: sticker id + keys = append(keys, setName) + + // key 2: hash of opt json string + hash := xxhash.New() + optStr, err := json.MarshalIndent(opt, "", "") + if err != nil { + log.Error("failed to marshal opt", zap.Error(err)) + return nil, err + } + _, err = hash.Write(optStr) + if err != nil { + log.Error("failed to write to hasher", zap.Error(err)) + return nil, err + } + keys = append(keys, fmt.Sprintf("%x", hash.Sum64())) + return keys, nil +} + func parseOpts(text string) (map[string]string, error) { cmd, _, err := entities.CommandFromText(text, -1) if err != nil { @@ -760,6 +849,13 @@ func normalizeParams(k, v string) (bool, string, string) { k = "stickerformat" case "pf", "packformat": k = "packformat" + case "nocache": + k = "nocache" + if strings.ToLower(v) == "false" { + v = "false" + } else { + v = "true" + } default: return false, k, v } diff --git a/orm/redis.go b/orm/redis.go index 8f3161f..30220de 100644 --- a/orm/redis.go +++ b/orm/redis.go @@ -869,3 +869,52 @@ func ClearIWantConfig(userID int64) error { } return nil } + +// FileCache file cache in redis. +type FileCache struct { + FileId string `redis:"file_id"` + Filename string `redis:"filename"` +} + +// SetFileCache set file cache to redis. +func SetFileCache(keys []string, file *FileCache, expire time.Duration) error { + keys = append([]string{"file_cache"}, keys...) + key := wrapKey(strings.Join(keys, ":")) + + err := rc.HSet(context.TODO(), key, file, expire).Err() + if err != nil { + log.Error("set file cache to redis failed", zap.String("key", key), zap.Any("file", file), zap.Error(err)) + return err + } + err = rc.Expire(context.TODO(), key, expire).Err() + if err != nil { + log.Error("set file cache expire to redis failed", zap.String("key", key), zap.Error(err)) + } + return nil +} + +// GetFileCache get file cache from redis. +func GetFileCache(keys []string, expire ...time.Duration) (*FileCache, error) { + keys = append([]string{"file_cache"}, keys...) + key := wrapKey(strings.Join(keys, ":")) + + file := new(FileCache) + ret := rc.HGetAll(context.TODO(), key) + if err := ret.Err(); err != nil && errors.Is(err, redis.Nil) { + log.Debug("file cache not found in redis", zap.String("key", key), zap.Error(err)) + return nil, nil + } + err := ret.Scan(file) + if err != nil { + log.Error("get file cache from redis failed", zap.String("key", key), zap.Error(err)) + return nil, err + } + + if len(expire) > 0 { + err = rc.Expire(context.TODO(), key, expire[0]).Err() + if err != nil { + log.Error("set file cache expire to redis failed", zap.String("key", key), zap.Error(err)) + } + } + return file, nil +} From d4e5315ae9672e85e0bbce7a7ae2adcc0232f1cd Mon Sep 17 00:00:00 2001 From: Hugefiver Date: Thu, 26 Dec 2024 14:10:21 +0000 Subject: [PATCH 07/12] gh action: push to ghcr.io --- .github/workflows/push.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/push.yml b/.github/workflows/push.yml index d2674ff..990497e 100644 --- a/.github/workflows/push.yml +++ b/.github/workflows/push.yml @@ -23,13 +23,13 @@ jobs: steps: - name: Get source - uses: actions/checkout@v3 + uses: actions/checkout@v3 - name: Build Image id: build-image uses: redhat-actions/buildah-build@v2 with: - image: csust/csust-got-hoo + image: csusters/csust-got tags: | latest-${{ github.ref_name }} containerfiles: | @@ -42,9 +42,9 @@ jobs: with: image: ${{ steps.build-image.outputs.image }} tags: ${{ steps.build-image.outputs.tags }} - registry: ${{ secrets.HARBOR_URL }} - username: ${{ secrets.HARBOR_USERNAME }} - password: ${{ secrets.HARBOR_PASSWD }} + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} retry: 1000 - name: Restart Kubernetes Deployment From 87457c2998a50ba11ba01124f5ebe508cfaeccad Mon Sep 17 00:00:00 2001 From: Hugefiver Date: Fri, 27 Dec 2024 14:36:04 +0800 Subject: [PATCH 08/12] fix: some mistake --- orm/redis.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/orm/redis.go b/orm/redis.go index 30220de..f847460 100644 --- a/orm/redis.go +++ b/orm/redis.go @@ -881,7 +881,7 @@ func SetFileCache(keys []string, file *FileCache, expire time.Duration) error { keys = append([]string{"file_cache"}, keys...) key := wrapKey(strings.Join(keys, ":")) - err := rc.HSet(context.TODO(), key, file, expire).Err() + err := rc.HSet(context.TODO(), key, file).Err() if err != nil { log.Error("set file cache to redis failed", zap.String("key", key), zap.Any("file", file), zap.Error(err)) return err From ce6c553d41daae8b40b82da38df9c7375b0cadeb Mon Sep 17 00:00:00 2001 From: Hugefiver Date: Fri, 27 Dec 2024 15:01:00 +0800 Subject: [PATCH 09/12] fix: send file on cloud --- base/sticker.go | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/base/sticker.go b/base/sticker.go index 68717cc..8bf90dc 100644 --- a/base/sticker.go +++ b/base/sticker.go @@ -455,18 +455,19 @@ func sendStickerPack(ctx tb.Context, sticker *tb.Sticker, opt *stickerOpts) erro fileCache, err := orm.GetFileCache(keys, time.Hour*24*7) if err == nil && fileCache != nil && fileCache.FileId != "" { - file, err := ctx.Bot().FileByID(fileCache.FileId) - if err != nil { - log.Error("failed to get file by id", zap.Error(err)) - goto process - } + // file, err := ctx.Bot().FileByID(fileCache.FileId) + // if err != nil { + // log.Error("failed to get file by id", zap.Error(err)) + // goto process + // } + file := tb.File{FileID: fileCache.FileId} err = ctx.Reply(&tb.Document{ FileName: fileCache.Filename, File: file, }) if err != nil { - log.Error("failed to send file", zap.Error(err)) - return ctx.Reply("failed to send file") + log.Error("failed to send cloud file", zap.Error(err)) + goto process } return nil From 7320c81245b999484b3d20c143ce267e19c369ac Mon Sep 17 00:00:00 2001 From: Hugefiver Date: Fri, 27 Dec 2024 15:46:33 +0800 Subject: [PATCH 10/12] impr file cache --- base/sticker.go | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/base/sticker.go b/base/sticker.go index 8bf90dc..0c8f45d 100644 --- a/base/sticker.go +++ b/base/sticker.go @@ -447,7 +447,7 @@ func sendStickerPack(ctx tb.Context, sticker *tb.Sticker, opt *stickerOpts) erro } if !opt.nocache { - keys, err := getFileCacheKeys(stickerSet.Name, opt) + keys, err := getFileCacheKeys(stickerSet, opt) if err != nil { log.Error("failed to get file cache keys", zap.Error(err)) goto process @@ -747,7 +747,7 @@ loop: Filename: doc.FileName, } - keys, err := getFileCacheKeys(setName, opt) + keys, err := getFileCacheKeys(stickerSet, opt) if err != nil { log.Error("failed to get file cache keys", zap.Error(err)) return err @@ -764,7 +764,18 @@ loop: return err } -func getFileCacheKeys(setName string, opt *stickerOpts) ([]string, error) { +func getFileCacheKeys(set *tb.StickerSet, opt *stickerOpts) ([]string, error) { + setName := set.Name + + o := *opt + if set.Video { + o.Format = o.VideoFormat() + } else { + o.Format = o.StickerFormat() + } + o.Sf = "" + o.Vf = "" + keys := make([]string, 0, 2) // key 1: sticker id @@ -772,11 +783,12 @@ func getFileCacheKeys(setName string, opt *stickerOpts) ([]string, error) { // key 2: hash of opt json string hash := xxhash.New() - optStr, err := json.MarshalIndent(opt, "", "") + optStr, err := json.MarshalIndent(o, "", "") if err != nil { log.Error("failed to marshal opt", zap.Error(err)) return nil, err } + log.Debug("opt json", zap.ByteString("opt", optStr)) _, err = hash.Write(optStr) if err != nil { log.Error("failed to write to hasher", zap.Error(err)) From 69ddea755aac4b55b39e37d595a7b4ade51d65bc Mon Sep 17 00:00:00 2001 From: Hugefiver Date: Fri, 27 Dec 2024 16:15:18 +0800 Subject: [PATCH 11/12] fix some bug --- base/sticker.go | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/base/sticker.go b/base/sticker.go index 0c8f45d..9edb792 100644 --- a/base/sticker.go +++ b/base/sticker.go @@ -112,11 +112,14 @@ func (o stickerOpts) merge(m map[string]string, final bool) stickerOpts { switch k { case "format", "f": o.Format = v + case "!pack", "!p", "nopack", "pack!", "p!": + v = "false" + fallthrough case "pack", "p": - if slices.Contains([]string{"", "true", "1"}, strings.ToLower(v)) { - o.Pack = true - } else if strings.ToLower(v) == "false" { + if v == "false" { o.Pack = false + } else { + o.Pack = true } case "vf", "videoformat": o.Vf = v From 9e364b07c08a8ad2f3d49cff2a5e2846442ff994 Mon Sep 17 00:00:00 2001 From: Hugefiver Date: Fri, 27 Dec 2024 16:25:36 +0800 Subject: [PATCH 12/12] make YAN happy --- base/sticker.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/base/sticker.go b/base/sticker.go index 9edb792..732da14 100644 --- a/base/sticker.go +++ b/base/sticker.go @@ -475,7 +475,7 @@ func sendStickerPack(ctx tb.Context, sticker *tb.Sticker, opt *stickerOpts) erro return nil } - log.Error("failed to get file cache, continue process", zap.Error(err)) + log.Info("failed to get file cache, continue process", zap.Error(err)) } process: