Skip to content

Commit 2fd7d26

Browse files
authored
Merge pull request #9 from Cosr-Backup/dev
Dev
2 parents 0777c98 + 6e897a1 commit 2fd7d26

File tree

22 files changed

+894
-257
lines changed

22 files changed

+894
-257
lines changed

bot/handle_add_task.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ import (
1818
"github.com/krau/SaveAny-Bot/dao"
1919
"github.com/krau/SaveAny-Bot/queue"
2020
"github.com/krau/SaveAny-Bot/types"
21+
"github.com/krau/SaveAny-Bot/userclient"
2122
"gorm.io/gorm"
2223
)
2324

@@ -153,7 +154,14 @@ func AddToQueue(ctx *ext.Context, update *ext.Update) error {
153154
task.StoragePath = path.Join(dir.Path, record.FileName)
154155
}
155156
} else {
156-
file, err := FileFromMessage(ctx, record.ChatID, record.MessageID, record.FileName)
157+
var file *types.File
158+
var err error
159+
if record.UseUserClient && userclient.UC != nil {
160+
uctx := userclient.UC.CreateContext()
161+
file, err = FileFromMessage(uctx, record.ChatID, record.MessageID, record.FileName)
162+
} else {
163+
file, err = FileFromMessage(ctx, record.ChatID, record.MessageID, record.FileName)
164+
}
157165
if err != nil {
158166
common.Log.Errorf("获取消息中的文件失败: %s", err)
159167
ctx.AnswerCallback(&tg.MessagesSetBotCallbackAnswerRequest{
@@ -168,6 +176,7 @@ func AddToQueue(ctx *ext.Context, update *ext.Update) error {
168176
task = types.Task{
169177
Ctx: ctx,
170178
Status: types.Pending,
179+
UseUserClient: record.UseUserClient,
171180
FileDBID: record.ID,
172181
File: file,
173182
StorageName: storageName,

bot/handle_link.go

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
"github.com/krau/SaveAny-Bot/common"
1313
"github.com/krau/SaveAny-Bot/dao"
1414
"github.com/krau/SaveAny-Bot/types"
15+
"github.com/krau/SaveAny-Bot/userclient"
1516
)
1617

1718
var (
@@ -50,6 +51,31 @@ func parseLink(ctx *ext.Context, link string) (chatID int64, messageID int, err
5051
return chatID, messageID, nil
5152
}
5253

54+
// use passed ctx client to fetch file from message,
55+
//
56+
// if failed try using userclient
57+
func tryFetchFileFromMessage(ctx *ext.Context, chatID int64, messageID int, fileName string) (*types.File, bool, error) {
58+
file, err := FileFromMessage(ctx, chatID, messageID, fileName)
59+
if err == nil {
60+
return file, false, nil
61+
}
62+
if (strings.Contains(err.Error(), "peer not found") || strings.Contains(err.Error(), "unexpected message type")) && userclient.UC != nil {
63+
common.Log.Warnf("无法获取文件 %d:%d, 尝试使用 userbot: %s", chatID, messageID, err)
64+
uctx := userclient.GetCtx()
65+
// TODO: 群组支持
66+
file, err = FileFromMessage(uctx, chatID, messageID, fileName)
67+
if err == nil {
68+
return file, true, nil
69+
}
70+
return nil, true, err
71+
}
72+
return nil, false, err
73+
}
74+
75+
func tryFetchMessage(ctx *ext.Context, chatID int64, messageID int) (*tg.Message, error) {
76+
return GetTGMessage(ctx, chatID, messageID)
77+
}
78+
5379
func handleLinkMessage(ctx *ext.Context, update *ext.Update) error {
5480
common.Log.Trace("Got link message")
5581
link := linkRegex.FindString(update.EffectiveMessage.Text)
@@ -70,26 +96,25 @@ func handleLinkMessage(ctx *ext.Context, update *ext.Update) error {
7096
return dispatcher.EndGroups
7197
}
7298

73-
// storages := storage.GetUserStorages(user.ChatID)
74-
// if len(storages) == 0 {
75-
// ctx.Reply(update, ext.ReplyTextString("无可用的存储"), nil)
76-
// return dispatcher.EndGroups
77-
// }
78-
7999
replied, err := ctx.Reply(update, ext.ReplyTextString("正在获取文件..."), nil)
80100
if err != nil {
81101
common.Log.Errorf("回复失败: %s", err)
82102
return dispatcher.EndGroups
83103
}
84104

85-
file, err := FileFromMessage(ctx, linkChatID, messageID, "")
105+
file, useUserClient, err := tryFetchFileFromMessage(ctx, linkChatID, messageID, "")
86106
if err != nil {
87107
common.Log.Errorf("获取文件失败: %s", err)
88108
ctx.Reply(update, ext.ReplyTextString("获取文件失败: "+err.Error()), nil)
89109
return dispatcher.EndGroups
90110
}
91111
if file.FileName == "" {
92-
file.FileName = GenFileNameFromMessage(*update.EffectiveMessage.Message, file)
112+
msg, err := tryFetchMessage(ctx, linkChatID, messageID)
113+
if err != nil {
114+
file.FileName = fmt.Sprintf("%d_%d", linkChatID, messageID)
115+
} else {
116+
file.FileName = GenFileNameFromMessage(*msg, file)
117+
}
93118
}
94119

95120
receivedFile := &dao.ReceivedFile{
@@ -99,6 +124,7 @@ func handleLinkMessage(ctx *ext.Context, update *ext.Update) error {
99124
MessageID: messageID,
100125
ReplyMessageID: replied.ID,
101126
ReplyChatID: update.GetUserChat().GetID(),
127+
UseUserClient: useUserClient,
102128
}
103129
record, err := dao.SaveReceivedFile(receivedFile)
104130
if err != nil {
@@ -116,6 +142,7 @@ func handleLinkMessage(ctx *ext.Context, update *ext.Update) error {
116142
Ctx: ctx,
117143
Status: types.Pending,
118144
FileDBID: record.ID,
145+
UseUserClient: useUserClient,
119146
File: file,
120147
StorageName: user.DefaultStorage,
121148
UserID: user.ChatID,

bot/handle_start.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,6 @@ Save Any Bot - 转存你的 Telegram 文件
3535
`
3636

3737
func help(ctx *ext.Context, update *ext.Update) error {
38-
ctx.Reply(update, ext.ReplyTextString(fmt.Sprintf(helpText, common.Version, common.GitCommit[:7])), nil)
38+
ctx.Reply(update, ext.ReplyTextString(fmt.Sprintf(helpText, common.Version, common.GitCommit)), nil)
3939
return dispatcher.EndGroups
4040
}

bot/handlers.go

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,31 +4,38 @@ import (
44
"github.com/celestix/gotgproto/dispatcher"
55
"github.com/celestix/gotgproto/dispatcher/handlers"
66
"github.com/celestix/gotgproto/dispatcher/handlers/filters"
7+
"github.com/celestix/gotgproto/ext"
78
"github.com/krau/SaveAny-Bot/common"
89
)
910

10-
func RegisterHandlers(dispatcher dispatcher.Dispatcher) {
11-
dispatcher.AddHandler(handlers.NewMessage(filters.Message.All, checkPermission))
12-
dispatcher.AddHandler(handlers.NewCommand("start", start))
13-
dispatcher.AddHandler(handlers.NewCommand("help", help))
14-
dispatcher.AddHandler(handlers.NewCommand("silent", silent))
15-
dispatcher.AddHandler(handlers.NewCommand("storage", storageCmd))
16-
dispatcher.AddHandler(handlers.NewCommand("save", saveCmd))
17-
dispatcher.AddHandler(handlers.NewCommand("dir", dirCmd))
18-
dispatcher.AddHandler(handlers.NewCommand("rule", ruleCmd))
11+
func RegisterHandlers(disp dispatcher.Dispatcher) {
12+
disp.AddHandler(handlers.NewMessage(filters.Message.ChatType(filters.ChatTypeChannel), func(ctx *ext.Context, u *ext.Update) error {
13+
return dispatcher.EndGroups
14+
}))
15+
disp.AddHandler(handlers.NewMessage(filters.Message.ChatType(filters.ChatTypeChat), func(ctx *ext.Context, u *ext.Update) error {
16+
return dispatcher.EndGroups
17+
}))
18+
disp.AddHandler(handlers.NewMessage(filters.Message.All, checkPermission))
19+
disp.AddHandler(handlers.NewCommand("start", start))
20+
disp.AddHandler(handlers.NewCommand("help", help))
21+
disp.AddHandler(handlers.NewCommand("silent", silent))
22+
disp.AddHandler(handlers.NewCommand("storage", storageCmd))
23+
disp.AddHandler(handlers.NewCommand("save", saveCmd))
24+
disp.AddHandler(handlers.NewCommand("dir", dirCmd))
25+
disp.AddHandler(handlers.NewCommand("rule", ruleCmd))
1926
linkRegexFilter, err := filters.Message.Regex(linkRegexString)
2027
if err != nil {
2128
common.Log.Panicf("创建正则表达式过滤器失败: %s", err)
2229
}
23-
dispatcher.AddHandler(handlers.NewMessage(linkRegexFilter, handleLinkMessage))
30+
disp.AddHandler(handlers.NewMessage(linkRegexFilter, handleLinkMessage))
2431
telegraphUrlRegexFilter, err := filters.Message.Regex(TelegraphUrlRegexString)
2532
if err != nil {
2633
common.Log.Panicf("创建 Telegraph URL 正则表达式过滤器失败: %s", err)
2734
}
28-
dispatcher.AddHandler(handlers.NewMessage(telegraphUrlRegexFilter, handleTelegraph))
29-
dispatcher.AddHandler(handlers.NewCallbackQuery(filters.CallbackQuery.Prefix("add"), AddToQueue))
30-
dispatcher.AddHandler(handlers.NewCallbackQuery(filters.CallbackQuery.Prefix("set_default"), setDefaultStorage))
31-
dispatcher.AddHandler(handlers.NewCallbackQuery(filters.CallbackQuery.Prefix("cancel"), cancelTask))
32-
dispatcher.AddHandler(handlers.NewCallbackQuery(filters.CallbackQuery.Prefix("send_here"), sendFileToTelegram))
33-
dispatcher.AddHandler(handlers.NewMessage(filters.Message.Media, handleFileMessage))
35+
disp.AddHandler(handlers.NewMessage(telegraphUrlRegexFilter, handleTelegraph))
36+
disp.AddHandler(handlers.NewCallbackQuery(filters.CallbackQuery.Prefix("add"), AddToQueue))
37+
disp.AddHandler(handlers.NewCallbackQuery(filters.CallbackQuery.Prefix("set_default"), setDefaultStorage))
38+
disp.AddHandler(handlers.NewCallbackQuery(filters.CallbackQuery.Prefix("cancel"), cancelTask))
39+
disp.AddHandler(handlers.NewCallbackQuery(filters.CallbackQuery.Prefix("send_here"), sendFileToTelegram))
40+
disp.AddHandler(handlers.NewMessage(filters.Message.Media, handleFileMessage))
3441
}

cmd/geni18n/main.go

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
// cmd/gen_i18n/main.go
2+
package main
3+
4+
import (
5+
"bufio"
6+
"flag"
7+
"fmt"
8+
"io/fs"
9+
"os"
10+
"path/filepath"
11+
"regexp"
12+
"sort"
13+
"strings"
14+
)
15+
16+
func main() {
17+
dir := flag.String("dir", "./i18n/locale", "Locales directory path")
18+
out := flag.String("out", "i18n/i18nk/keys.go", "Output file path")
19+
pkg := flag.String("pkg", "i18nk", "Package name for generated file")
20+
flag.Parse()
21+
22+
keys := make(map[string]struct{})
23+
re := regexp.MustCompile(`^\s*\[+\s*([^\]\[]+)\s*\]+`)
24+
25+
err := filepath.WalkDir(*dir, func(path string, d fs.DirEntry, err error) error {
26+
if err != nil {
27+
return err
28+
}
29+
if d.IsDir() || !strings.HasSuffix(d.Name(), ".toml") {
30+
return nil
31+
}
32+
f, err := os.Open(path)
33+
if err != nil {
34+
return err
35+
}
36+
defer f.Close()
37+
38+
s := bufio.NewScanner(f)
39+
for s.Scan() {
40+
if m := re.FindStringSubmatch(s.Text()); m != nil {
41+
keys[m[1]] = struct{}{}
42+
}
43+
}
44+
return s.Err()
45+
})
46+
if err != nil {
47+
fmt.Fprintf(os.Stderr, "Error walking directory: %v\n", err)
48+
os.Exit(1)
49+
}
50+
51+
var list []string
52+
for k := range keys {
53+
list = append(list, k)
54+
}
55+
sort.Strings(list)
56+
57+
f, err := os.Create(*out)
58+
if err != nil {
59+
fmt.Fprintf(os.Stderr, "Error creating output file: %v\n", err)
60+
os.Exit(1)
61+
}
62+
defer f.Close()
63+
64+
w := bufio.NewWriter(f)
65+
fmt.Fprintf(w, "// Code generated by cmd/gen_i18n. DO NOT EDIT.\n")
66+
fmt.Fprintf(w, "package %s\n\n", *pkg)
67+
fmt.Fprintf(w, "const (\n")
68+
for _, key := range list {
69+
name := toPascal(key)
70+
fmt.Fprintf(w, "\t%s = %q\n", name, key)
71+
}
72+
fmt.Fprintf(w, ")\n")
73+
w.Flush()
74+
}
75+
76+
func toPascal(key string) string {
77+
parts := strings.Split(key, ".")
78+
for i, p := range parts {
79+
if len(p) > 0 {
80+
parts[i] = strings.ToUpper(string(p[0])) + p[1:]
81+
}
82+
}
83+
return strings.Join(parts, "")
84+
}

cmd/run.go

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package cmd
22

33
import (
4+
"context"
45
"fmt"
56
"os"
67
"os/signal"
@@ -14,7 +15,10 @@ import (
1415
"github.com/krau/SaveAny-Bot/config"
1516
"github.com/krau/SaveAny-Bot/core"
1617
"github.com/krau/SaveAny-Bot/dao"
18+
"github.com/krau/SaveAny-Bot/i18n"
19+
"github.com/krau/SaveAny-Bot/i18n/i18nk"
1720
"github.com/krau/SaveAny-Bot/storage"
21+
"github.com/krau/SaveAny-Bot/userclient"
1822
"github.com/spf13/cobra"
1923
)
2024

@@ -25,43 +29,64 @@ func Run(_ *cobra.Command, _ []string) {
2529
quit := make(chan os.Signal, 1)
2630
signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
2731
sig := <-quit
28-
common.Log.Info(sig, ", exitting...")
29-
defer common.Log.Info("Bye!")
32+
common.Log.Info(sig, i18n.T(i18nk.Exiting))
33+
defer common.Log.Info(i18n.T(i18nk.Bye))
3034
if config.Cfg.NoCleanCache {
3135
return
3236
}
3337
if config.Cfg.Temp.BasePath != "" && !config.Cfg.Stream {
3438
if slices.Contains([]string{"/", ".", "\\", ".."}, filepath.Clean(config.Cfg.Temp.BasePath)) {
35-
common.Log.Error("无效的缓存文件夹: ", config.Cfg.Temp.BasePath)
39+
common.Log.Error(i18n.T(i18nk.InvalidCacheDir, map[string]any{
40+
"Path": config.Cfg.Temp.BasePath,
41+
}))
3642
return
3743
}
3844
currentDir, err := os.Getwd()
3945
if err != nil {
40-
common.Log.Error("获取工作目录失败: ", err)
46+
common.Log.Error(i18n.T(i18nk.GetWorkdirFailed, map[string]any{
47+
"Error": err,
48+
}))
4149
return
4250
}
4351
cachePath := filepath.Join(currentDir, config.Cfg.Temp.BasePath)
4452
cachePath, err = filepath.Abs(cachePath)
4553
if err != nil {
46-
common.Log.Error("获取缓存绝对路径失败: ", err)
54+
common.Log.Error(i18n.T(i18nk.GetCacheAbsPathFailed, map[string]any{
55+
"Error": err,
56+
}))
4757
return
4858
}
49-
common.Log.Info("正在清理缓存文件夹: ", cachePath)
59+
common.Log.Info(i18n.T(i18nk.CleaningCache, map[string]any{
60+
"Path": cachePath,
61+
}))
5062
if err := common.RemoveAllInDir(cachePath); err != nil {
51-
common.Log.Error("清理缓存失败: ", err)
63+
common.Log.Error(i18n.T(i18nk.CleanCacheFailed, map[string]any{
64+
"Error": err,
65+
}))
5266
}
5367
}
5468
}
5569

5670
func InitAll() {
5771
if err := config.Init(); err != nil {
58-
fmt.Println("加载配置文件失败: ", err)
72+
fmt.Println("Failed to load config:", err)
5973
os.Exit(1)
6074
}
6175
common.InitLogger()
62-
common.Log.Info("正在启动 SaveAny-Bot...")
76+
i18n.Init(config.Cfg.Lang)
77+
common.Log.Info(i18n.T(i18nk.Initing))
6378
dao.Init()
6479
storage.LoadStorages()
6580
common.Init()
81+
if config.Cfg.Telegram.Userbot.Enable {
82+
ctx, cancel := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
83+
defer cancel()
84+
uc, err := userclient.Login(ctx)
85+
if err != nil {
86+
common.Log.Errorf("User client login failed: %s", err)
87+
os.Exit(1)
88+
}
89+
common.Log.Infof("User client logged in as %s", uc.Self.FirstName)
90+
}
6691
bot.Init()
6792
}

common/logger.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ func InitLogger() {
1313
if Log != nil {
1414
return
1515
}
16-
slog.DefaultChannelName = "SaveAnyBot"
1716
Log = slog.New()
1817
logLevel := slog.LevelByName(config.Cfg.Log.Level)
1918
logFilePath := config.Cfg.Log.File
@@ -24,14 +23,18 @@ func InitLogger() {
2423
logLevels = append(logLevels, level)
2524
}
2625
}
26+
tem := "[{{datetime}}] [{{level}}] [{{caller}}] {{message}} {{data}} {{extra}}\n"
2727
consoleH := handler.NewConsoleHandler(logLevels)
28+
consoleH.Formatter().(*slog.TextFormatter).SetTemplate(tem)
2829
Log.AddHandler(consoleH)
2930
if logFilePath != "" && logBackupNum > 0 {
3031
fileH, err := handler.NewTimeRotateFile(
3132
logFilePath,
3233
rotatefile.EveryDay,
3334
handler.WithLogLevels(slog.AllLevels),
34-
handler.WithBackupNum(logBackupNum))
35+
handler.WithBackupNum(logBackupNum),
36+
)
37+
fileH.Formatter().(*slog.TextFormatter).SetTemplate(tem)
3538
if err != nil {
3639
panic(err)
3740
}

0 commit comments

Comments
 (0)