mirror of
https://github.com/krau/SaveAny-Bot.git
synced 2026-09-04 23:26:39 +08:00
feat: Refactor bot handlers to utilize i18n for internationalization
- Updated silent.go to replace hardcoded strings with i18n keys for user feedback. - Enhanced telegraph.go to use i18n for error messages and prompts. - Modified update.go to implement i18n for version update notifications and errors. - Refactored dir.go to utilize i18n for help messages related to directory operations. - Updated parse.go to replace static text with i18n keys for parsed text entities. - Enhanced rule.go to use i18n for rule management help messages. - Refactored storage.go to implement i18n for storage selection prompts. - Updated task.go to utilize i18n for task addition notifications. - Added new i18n keys in keys.go for various messages. - Updated Chinese localization in zh-Hans.yaml to reflect new i18n keys and messages.
This commit is contained in:
@@ -8,19 +8,21 @@ import (
|
|||||||
"github.com/celestix/gotgproto/dispatcher"
|
"github.com/celestix/gotgproto/dispatcher"
|
||||||
"github.com/celestix/gotgproto/ext"
|
"github.com/celestix/gotgproto/ext"
|
||||||
"github.com/gotd/td/tg"
|
"github.com/gotd/td/tg"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/database"
|
"github.com/krau/SaveAny-Bot/database"
|
||||||
"github.com/krau/SaveAny-Bot/pkg/enums/fnamest"
|
"github.com/krau/SaveAny-Bot/pkg/enums/fnamest"
|
||||||
"github.com/krau/SaveAny-Bot/pkg/tcbdata"
|
"github.com/krau/SaveAny-Bot/pkg/tcbdata"
|
||||||
)
|
)
|
||||||
|
|
||||||
func handleConfigCmd(ctx *ext.Context, update *ext.Update) error {
|
func handleConfigCmd(ctx *ext.Context, update *ext.Update) error {
|
||||||
ctx.Reply(update, ext.ReplyTextString("请选择要配置的选项"), &ext.ReplyOpts{
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgConfigPromptSelectOption)), &ext.ReplyOpts{
|
||||||
Markup: &tg.ReplyInlineMarkup{
|
Markup: &tg.ReplyInlineMarkup{
|
||||||
Rows: []tg.KeyboardButtonRow{
|
Rows: []tg.KeyboardButtonRow{
|
||||||
{
|
{
|
||||||
Buttons: []tg.KeyboardButtonClass{
|
Buttons: []tg.KeyboardButtonClass{
|
||||||
&tg.KeyboardButtonCallback{
|
&tg.KeyboardButtonCallback{
|
||||||
Text: "文件名策略",
|
Text: i18n.T(i18nk.BotMsgConfigButtonFilenameStrategy),
|
||||||
Data: fmt.Appendf(nil, "%s %s", tcbdata.TypeConfig, "fnamest"),
|
Data: fmt.Appendf(nil, "%s %s", tcbdata.TypeConfig, "fnamest"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -37,7 +39,7 @@ func handleConfigCallback(ctx *ext.Context, update *ext.Update) error {
|
|||||||
ctx.AnswerCallback(&tg.MessagesSetBotCallbackAnswerRequest{
|
ctx.AnswerCallback(&tg.MessagesSetBotCallbackAnswerRequest{
|
||||||
QueryID: update.CallbackQuery.GetQueryID(),
|
QueryID: update.CallbackQuery.GetQueryID(),
|
||||||
Alert: true,
|
Alert: true,
|
||||||
Message: "无效的回调数据",
|
Message: i18n.T(i18nk.BotMsgConfigErrorInvalidCallbackData),
|
||||||
CacheTime: 5,
|
CacheTime: 5,
|
||||||
})
|
})
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
@@ -72,7 +74,9 @@ func handleConfigFnameSTCallback(ctx *ext.Context, update *ext.Update) error {
|
|||||||
}
|
}
|
||||||
ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{
|
ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{
|
||||||
ID: update.CallbackQuery.GetMsgID(),
|
ID: update.CallbackQuery.GetMsgID(),
|
||||||
Message: fmt.Sprintf("已将文件名策略设置为: %s", fnamest.FnameSTDisplay[st]),
|
Message: i18n.T(i18nk.BotMsgConfigInfoFilenameStrategySet, map[string]any{
|
||||||
|
"Strategy": fnamest.FnameSTDisplay[st],
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
@@ -97,7 +101,9 @@ func handleConfigFnameSTCallback(ctx *ext.Context, update *ext.Update) error {
|
|||||||
}
|
}
|
||||||
ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{
|
ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{
|
||||||
ID: update.CallbackQuery.GetMsgID(),
|
ID: update.CallbackQuery.GetMsgID(),
|
||||||
Message: fmt.Sprintf("请选择文件名策略, 当前策略: %s", fnamest.FnameSTDisplay[currentSt]),
|
Message: i18n.T(i18nk.BotMsgConfigPromptSelectFilenameStrategy, map[string]any{
|
||||||
|
"Strategy": fnamest.FnameSTDisplay[currentSt],
|
||||||
|
}),
|
||||||
ReplyMarkup: markup,
|
ReplyMarkup: markup,
|
||||||
})
|
})
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
@@ -111,34 +117,27 @@ func handleConfigFnameTmpl(ctx *ext.Context, update *ext.Update) error {
|
|||||||
}
|
}
|
||||||
args := strings.Fields(string(update.EffectiveMessage.Text))
|
args := strings.Fields(string(update.EffectiveMessage.Text))
|
||||||
if len(args) <= 1 {
|
if len(args) <= 1 {
|
||||||
text := `使用该命令设置文件名模板, 示例:
|
text := i18n.T(i18nk.BotMsgConfigFnametmplHelp, nil)
|
||||||
/fnametmpl 图片_{{.msgid}}_{{.msgdate}}.jpg
|
|
||||||
|
|
||||||
可用变量:
|
|
||||||
- {{.msgid}}: 消息ID
|
|
||||||
- {{.msgtags}}: 消息中的标签, 将以下划线分隔输出
|
|
||||||
- {{.msggen}}: 根据消息生成的文件名
|
|
||||||
- {{.msgdate}}: 消息日期, 格式 YYYY-MM-DD_HH-MM-SS
|
|
||||||
- {{.origname}}: 媒体的原始文件名 (如果有)
|
|
||||||
- {{.chatid}}: 消息的聊天ID
|
|
||||||
`
|
|
||||||
if user.FilenameTemplate != "" {
|
if user.FilenameTemplate != "" {
|
||||||
text += fmt.Sprintf("\n\n当前模板: %s", user.FilenameTemplate)
|
text += "\n\n" + i18n.T(i18nk.BotMsgConfigInfoCurrentTemplatePrefix, map[string]any{
|
||||||
|
"Template": user.FilenameTemplate,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
text += "\n\n模板仅在文件名策略设置为 '自定义模板' 时生效, 且模板解析错误时会回退到默认文件名"
|
|
||||||
ctx.Reply(update, ext.ReplyTextString(text), nil)
|
ctx.Reply(update, ext.ReplyTextString(text), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
newTmpl := strings.Join(args[1:], " ")
|
newTmpl := strings.Join(args[1:], " ")
|
||||||
_, err = template.New("filename").Parse(newTmpl)
|
_, err = template.New("filename").Parse(newTmpl)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Reply(update, ext.ReplyTextString("无效的模板, 请检查语法\n"+err.Error()), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgConfigErrorInvalidTemplate, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
user.FilenameTemplate = newTmpl
|
user.FilenameTemplate = newTmpl
|
||||||
if err := database.UpdateUser(ctx, user); err != nil {
|
if err := database.UpdateUser(ctx, user); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ctx.Reply(update, ext.ReplyTextString("已更新文件名模板"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgConfigInfoTemplateUpdated, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import (
|
|||||||
"github.com/celestix/gotgproto/ext"
|
"github.com/celestix/gotgproto/ext"
|
||||||
"github.com/charmbracelet/log"
|
"github.com/charmbracelet/log"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/database"
|
"github.com/krau/SaveAny-Bot/database"
|
||||||
"github.com/krau/SaveAny-Bot/storage"
|
"github.com/krau/SaveAny-Bot/storage"
|
||||||
)
|
)
|
||||||
@@ -19,7 +21,7 @@ func handleDirCmd(ctx *ext.Context, update *ext.Update) error {
|
|||||||
dirs, err := database.GetUserDirsByChatID(ctx, userChatID)
|
dirs, err := database.GetUserDirsByChatID(ctx, userChatID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Failed to get user directories: %s", err)
|
logger.Errorf("Failed to get user directories: %s", err)
|
||||||
ctx.Reply(update, ext.ReplyTextString("获取用户文件夹失败"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgDirErrorGetUserDirsFailed)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
@@ -29,7 +31,7 @@ func handleDirCmd(ctx *ext.Context, update *ext.Update) error {
|
|||||||
user, err := database.GetUserByChatID(ctx, update.GetUserChat().GetID())
|
user, err := database.GetUserByChatID(ctx, update.GetUserChat().GetID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Failed to get user: %s", err)
|
logger.Errorf("Failed to get user: %s", err)
|
||||||
ctx.Reply(update, ext.ReplyTextString("获取用户失败"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgDirErrorGetUserFailed)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
switch args[1] {
|
switch args[1] {
|
||||||
@@ -46,10 +48,10 @@ func handleDirCmd(ctx *ext.Context, update *ext.Update) error {
|
|||||||
|
|
||||||
if err := database.CreateDirForUser(ctx, user.ID, args[2], args[3]); err != nil {
|
if err := database.CreateDirForUser(ctx, user.ID, args[2], args[3]); err != nil {
|
||||||
logger.Errorf("Failed to create directory: %s", err)
|
logger.Errorf("Failed to create directory: %s", err)
|
||||||
ctx.Reply(update, ext.ReplyTextString("创建文件夹失败"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgDirErrorCreateDirFailed)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
ctx.Reply(update, ext.ReplyTextString("文件夹添加成功"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgDirInfoCreateDirSuccess)), nil)
|
||||||
case "del":
|
case "del":
|
||||||
// /dir del 3
|
// /dir del 3
|
||||||
if len(args) < 3 {
|
if len(args) < 3 {
|
||||||
@@ -58,17 +60,17 @@ func handleDirCmd(ctx *ext.Context, update *ext.Update) error {
|
|||||||
}
|
}
|
||||||
dirID, err := strconv.Atoi(args[2])
|
dirID, err := strconv.Atoi(args[2])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Reply(update, ext.ReplyTextString("文件夹ID无效"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgDirErrorInvalidDirId)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
if err := database.DeleteDirByID(ctx, uint(dirID)); err != nil {
|
if err := database.DeleteDirByID(ctx, uint(dirID)); err != nil {
|
||||||
logger.Errorf("Failed to delete directory: %s", err)
|
logger.Errorf("Failed to delete directory: %s", err)
|
||||||
ctx.Reply(update, ext.ReplyTextString("删除文件夹失败"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgDirErrorDeleteDirFailed)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
ctx.Reply(update, ext.ReplyTextString("文件夹删除成功"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgDirInfoDeleteDirSuccess)), nil)
|
||||||
default:
|
default:
|
||||||
ctx.Reply(update, ext.ReplyTextString("未知操作"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgDirErrorUnknownOperation)), nil)
|
||||||
}
|
}
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"net/url"
|
"net/url"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -9,6 +8,8 @@ import (
|
|||||||
"github.com/charmbracelet/log"
|
"github.com/charmbracelet/log"
|
||||||
"github.com/duke-git/lancet/v2/slice"
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/pkg/enums/tasktype"
|
"github.com/krau/SaveAny-Bot/pkg/enums/tasktype"
|
||||||
"github.com/krau/SaveAny-Bot/pkg/tcbdata"
|
"github.com/krau/SaveAny-Bot/pkg/tcbdata"
|
||||||
"github.com/krau/SaveAny-Bot/storage"
|
"github.com/krau/SaveAny-Bot/storage"
|
||||||
@@ -18,7 +19,7 @@ func handleDlCmd(ctx *ext.Context, update *ext.Update) error {
|
|||||||
logger := log.FromContext(ctx)
|
logger := log.FromContext(ctx)
|
||||||
args := strings.Split(update.EffectiveMessage.Text, " ")
|
args := strings.Split(update.EffectiveMessage.Text, " ")
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
ctx.Reply(update, ext.ReplyTextString("用法: /dl <链接1> <链接2> ..."), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgDlUsage)), nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
links := args[1:]
|
links := args[1:]
|
||||||
@@ -32,7 +33,7 @@ func handleDlCmd(ctx *ext.Context, update *ext.Update) error {
|
|||||||
}
|
}
|
||||||
links = slice.Compact(links)
|
links = slice.Compact(links)
|
||||||
if len(links) == 0 {
|
if len(links) == 0 {
|
||||||
ctx.Reply(update, ext.ReplyTextString("没有有效的链接可供下载"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgDlErrorNoValidLinks)), nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
markup, err := msgelem.BuildAddSelectStorageKeyboard(storage.GetUserStorages(ctx, update.GetUserChat().GetID()), tcbdata.Add{
|
markup, err := msgelem.BuildAddSelectStorageKeyboard(storage.GetUserStorages(ctx, update.GetUserChat().GetID()), tcbdata.Add{
|
||||||
@@ -42,7 +43,9 @@ func handleDlCmd(ctx *ext.Context, update *ext.Update) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
ctx.Reply(update, ext.ReplyTextString(fmt.Sprintf("共 %d 个文件, 请选择存储位置", len(links))), &ext.ReplyOpts{
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgDlInfoFilesSelectStorage, map[string]any{
|
||||||
|
"Count": len(links),
|
||||||
|
})), &ext.ReplyOpts{
|
||||||
Markup: markup,
|
Markup: markup,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -1,14 +1,14 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"github.com/celestix/gotgproto/dispatcher"
|
"github.com/celestix/gotgproto/dispatcher"
|
||||||
"github.com/celestix/gotgproto/ext"
|
"github.com/celestix/gotgproto/ext"
|
||||||
"github.com/charmbracelet/log"
|
"github.com/charmbracelet/log"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/dirutil"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/dirutil"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/shortcut"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/shortcut"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/pkg/tcbdata"
|
"github.com/krau/SaveAny-Bot/pkg/tcbdata"
|
||||||
"github.com/krau/SaveAny-Bot/storage"
|
"github.com/krau/SaveAny-Bot/storage"
|
||||||
)
|
)
|
||||||
@@ -25,7 +25,9 @@ func handleMessageLink(ctx *ext.Context, update *ext.Update) error {
|
|||||||
req, err := msgelem.BuildAddOneSelectStorageMessage(ctx, stors, files[0], replied.ID)
|
req, err := msgelem.BuildAddOneSelectStorageMessage(ctx, stors, files[0], replied.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Failed to build storage selection message: %s", err)
|
logger.Errorf("Failed to build storage selection message: %s", err)
|
||||||
editReplied("构建存储选择消息失败: "+err.Error(), nil)
|
editReplied(i18n.T(i18nk.BotMsgCommonErrorBuildStorageSelectMessageFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
}), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
ctx.EditMessage(update.EffectiveChat().GetID(), req)
|
ctx.EditMessage(update.EffectiveChat().GetID(), req)
|
||||||
@@ -36,10 +38,14 @@ func handleMessageLink(ctx *ext.Context, update *ext.Update) error {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Failed to build storage selection keyboard: %s", err)
|
logger.Errorf("Failed to build storage selection keyboard: %s", err)
|
||||||
editReplied("构建存储选择键盘失败: "+err.Error(), nil)
|
editReplied(i18n.T(i18nk.BotMsgCommonErrorBuildStorageSelectKeyboardFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
}), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
editReplied(fmt.Sprintf("找到 %d 个文件, 请选择存储位置", len(files)), markup)
|
editReplied(i18n.T(i18nk.BotMsgCommonInfoFoundFilesSelectStorage, map[string]any{
|
||||||
|
"Count": len(files),
|
||||||
|
}), markup)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ import (
|
|||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/mediautil"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/mediautil"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/shortcut"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/shortcut"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/database"
|
"github.com/krau/SaveAny-Bot/database"
|
||||||
"github.com/krau/SaveAny-Bot/storage"
|
"github.com/krau/SaveAny-Bot/storage"
|
||||||
)
|
)
|
||||||
@@ -35,7 +37,9 @@ func handleMediaMessage(ctx *ext.Context, update *ext.Update) error {
|
|||||||
req, err := msgelem.BuildAddOneSelectStorageMessage(ctx, stors, file, msg.ID)
|
req, err := msgelem.BuildAddOneSelectStorageMessage(ctx, stors, file, msg.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Failed to build storage selection message: %s", err)
|
logger.Errorf("Failed to build storage selection message: %s", err)
|
||||||
ctx.Reply(update, ext.ReplyTextString("构建存储选择消息失败: "+err.Error()), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgCommonErrorBuildStorageSelectMessageFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
ctx.EditMessage(update.EffectiveChat().GetID(), req)
|
ctx.EditMessage(update.EffectiveChat().GetID(), req)
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -12,6 +11,8 @@ import (
|
|||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/mediautil"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/mediautil"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/shortcut"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/shortcut"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/common/utils/tgutil"
|
"github.com/krau/SaveAny-Bot/common/utils/tgutil"
|
||||||
"github.com/krau/SaveAny-Bot/config"
|
"github.com/krau/SaveAny-Bot/config"
|
||||||
"github.com/krau/SaveAny-Bot/pkg/tcbdata"
|
"github.com/krau/SaveAny-Bot/pkg/tcbdata"
|
||||||
@@ -89,7 +90,7 @@ func processMediaGroup(ctx *ext.Context, update *ext.Update, groupID int64) {
|
|||||||
logger.Debugf("Processing media group %d with %d items", groupID, len(items))
|
logger.Debugf("Processing media group %d with %d items", groupID, len(items))
|
||||||
|
|
||||||
userId := update.GetUserChat().GetID()
|
userId := update.GetUserChat().GetID()
|
||||||
msg, err := ctx.Reply(update, ext.ReplyTextString("正在保存文件..."), nil)
|
msg, err := ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgMediaGroupInfoSavingFiles, nil)), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Failed to reply: %s", err)
|
logger.Errorf("Failed to reply: %s", err)
|
||||||
return
|
return
|
||||||
@@ -114,13 +115,17 @@ func processMediaGroup(ctx *ext.Context, update *ext.Update, groupID int64) {
|
|||||||
logger.Errorf("Failed to build storage selection keyboard: %s", err)
|
logger.Errorf("Failed to build storage selection keyboard: %s", err)
|
||||||
ctx.EditMessage(userId, &tg.MessagesEditMessageRequest{
|
ctx.EditMessage(userId, &tg.MessagesEditMessageRequest{
|
||||||
ID: msg.ID,
|
ID: msg.ID,
|
||||||
Message: "构建存储选择键盘失败: " + err.Error(),
|
Message: i18n.T(i18nk.BotMsgMediaGroupErrorBuildStorageSelectKeyboardFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
ctx.EditMessage(userId, &tg.MessagesEditMessageRequest{
|
ctx.EditMessage(userId, &tg.MessagesEditMessageRequest{
|
||||||
ID: msg.ID,
|
ID: msg.ID,
|
||||||
Message: fmt.Sprintf("共 %d 个文件, 请选择存储位置", len(items)),
|
Message: i18n.T(i18nk.BotMsgMediaGroupInfoGroupFoundFilesSelectStorage, map[string]any{
|
||||||
|
"Count": len(items),
|
||||||
|
}),
|
||||||
ReplyMarkup: markup,
|
ReplyMarkup: markup,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import (
|
|||||||
"github.com/celestix/gotgproto/ext"
|
"github.com/celestix/gotgproto/ext"
|
||||||
"github.com/duke-git/lancet/v2/slice"
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/dirutil"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/dirutil"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/config"
|
"github.com/krau/SaveAny-Bot/config"
|
||||||
"github.com/krau/SaveAny-Bot/database"
|
"github.com/krau/SaveAny-Bot/database"
|
||||||
"github.com/krau/SaveAny-Bot/storage"
|
"github.com/krau/SaveAny-Bot/storage"
|
||||||
@@ -13,11 +15,7 @@ import (
|
|||||||
func checkPermission(ctx *ext.Context, update *ext.Update) error {
|
func checkPermission(ctx *ext.Context, update *ext.Update) error {
|
||||||
userID := update.GetUserChat().GetID()
|
userID := update.GetUserChat().GetID()
|
||||||
if !slice.Contain(config.C().GetUsersID(), userID) {
|
if !slice.Contain(config.C().GetUsersID(), userID) {
|
||||||
const noPermissionText string = `
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgCommonErrorNoPermission, nil)), nil)
|
||||||
您不在白名单中, 无法使用此 Bot.
|
|
||||||
您可以部署自己的实例: https://github.com/krau/SaveAny-Bot
|
|
||||||
`
|
|
||||||
ctx.Reply(update, ext.ReplyTextString(noPermissionText), nil)
|
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -29,25 +27,31 @@ func handleSilentMode(next func(*ext.Context, *ext.Update) error, handler func(*
|
|||||||
userID := update.GetUserChat().GetID()
|
userID := update.GetUserChat().GetID()
|
||||||
user, err := database.GetUserByChatID(ctx, userID)
|
user, err := database.GetUserByChatID(ctx, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Reply(update, ext.ReplyTextString("获取用户信息失败: "+err.Error()), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgCommonErrorGetUserInfoFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
if !user.Silent {
|
if !user.Silent {
|
||||||
return next(ctx, update)
|
return next(ctx, update)
|
||||||
}
|
}
|
||||||
if user.DefaultStorage == "" {
|
if user.DefaultStorage == "" {
|
||||||
ctx.Reply(update, ext.ReplyTextString("您已开启静默模式, 但未设置默认存储端, 请先使用 /storage 设置"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgCommonErrorDefaultStorageNotSet, nil)), nil)
|
||||||
return next(ctx, update)
|
return next(ctx, update)
|
||||||
}
|
}
|
||||||
stor, err := storage.GetStorageByUserIDAndName(ctx, userID, user.DefaultStorage)
|
stor, err := storage.GetStorageByUserIDAndName(ctx, userID, user.DefaultStorage)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Reply(update, ext.ReplyTextString("获取默认存储失败: "+err.Error()), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgCommonErrorGetStorageFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
if user.DefaultDir != 0 {
|
if user.DefaultDir != 0 {
|
||||||
dir, err := database.GetDirByID(ctx, user.DefaultDir)
|
dir, err := database.GetDirByID(ctx, user.DefaultDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Reply(update, ext.ReplyTextString("获取默认文件夹失败: "+err.Error()), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgCommonErrorGetDirFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return next(ctx, update)
|
return next(ctx, update)
|
||||||
}
|
}
|
||||||
ctx.Context = dirutil.WithContext(ctx.Context, dir)
|
ctx.Context = dirutil.WithContext(ctx.Context, dir)
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ import (
|
|||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/dirutil"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/dirutil"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/shortcut"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/shortcut"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/common/utils/fsutil"
|
"github.com/krau/SaveAny-Bot/common/utils/fsutil"
|
||||||
"github.com/krau/SaveAny-Bot/common/utils/tgutil"
|
"github.com/krau/SaveAny-Bot/common/utils/tgutil"
|
||||||
"github.com/krau/SaveAny-Bot/parsers"
|
"github.com/krau/SaveAny-Bot/parsers"
|
||||||
@@ -33,7 +35,7 @@ func handleTextMessage(ctx *ext.Context, u *ext.Update) error {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
msg, err := ctx.Reply(u, ext.ReplyTextString("正在解析..."), nil)
|
msg, err := ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParseInfoParsing, nil)), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@@ -44,7 +46,9 @@ func handleTextMessage(ctx *ext.Context, u *ext.Update) error {
|
|||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("Failed to parse text", "error", err)
|
logger.Error("Failed to parse text", "error", err)
|
||||||
ctx.Reply(u, ext.ReplyTextString("Failed to parse text: "+err.Error()), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParseErrorParseTextFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
logger.Debug("Parsed item from text message", "title", item.Title, "url", item.URL)
|
logger.Debug("Parsed item from text message", "title", item.Title, "url", item.URL)
|
||||||
@@ -55,13 +59,17 @@ func handleTextMessage(ctx *ext.Context, u *ext.Update) error {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Failed to build storage selection keyboard: %s", err)
|
logger.Errorf("Failed to build storage selection keyboard: %s", err)
|
||||||
ctx.Reply(u, ext.ReplyTextString("Failed to build storage selection keyboard: "+err.Error()), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParseErrorBuildStorageSelectKeyboardFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
text, entities, err := msgelem.BuildParsedTextEntity(*item)
|
text, entities, err := msgelem.BuildParsedTextEntity(*item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Failed to build parsed text entity: %s", err)
|
logger.Errorf("Failed to build parsed text entity: %s", err)
|
||||||
ctx.Reply(u, ext.ReplyTextString("Failed to build parsed text entity: "+err.Error()), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParseErrorBuildParsedTextEntityFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{
|
ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{
|
||||||
@@ -87,7 +95,9 @@ func handleSilentSaveText(ctx *ext.Context, u *ext.Update) error {
|
|||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Error("Failed to parse text", "error", err)
|
logger.Error("Failed to parse text", "error", err)
|
||||||
ctx.Reply(u, ext.ReplyTextString("Failed to parse text: "+err.Error()), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParseErrorParseTextFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
logger.Debug("Parsed item from text message", "title", item.Title, "url", item.URL)
|
logger.Debug("Parsed item from text message", "title", item.Title, "url", item.URL)
|
||||||
@@ -95,7 +105,9 @@ func handleSilentSaveText(ctx *ext.Context, u *ext.Update) error {
|
|||||||
text, entities, err := msgelem.BuildParsedTextEntity(*item)
|
text, entities, err := msgelem.BuildParsedTextEntity(*item)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Failed to build parsed text entity: %s", err)
|
logger.Errorf("Failed to build parsed text entity: %s", err)
|
||||||
ctx.Reply(u, ext.ReplyTextString("Failed to build parsed text entity: "+err.Error()), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParseErrorBuildParsedTextEntityFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
msg, err := ctx.SendMessage(userID, &tg.MessagesSendMessageRequest{
|
msg, err := ctx.SendMessage(userID, &tg.MessagesSendMessageRequest{
|
||||||
|
|||||||
@@ -7,17 +7,15 @@ import (
|
|||||||
"github.com/celestix/gotgproto/dispatcher"
|
"github.com/celestix/gotgproto/dispatcher"
|
||||||
"github.com/celestix/gotgproto/ext"
|
"github.com/celestix/gotgproto/ext"
|
||||||
"github.com/gotd/td/tg"
|
"github.com/gotd/td/tg"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/config"
|
"github.com/krau/SaveAny-Bot/config"
|
||||||
"github.com/krau/SaveAny-Bot/parsers"
|
"github.com/krau/SaveAny-Bot/parsers"
|
||||||
)
|
)
|
||||||
|
|
||||||
func handleParserCmd(ctx *ext.Context, u *ext.Update) error {
|
func handleParserCmd(ctx *ext.Context, u *ext.Update) error {
|
||||||
args := strings.Split(u.EffectiveMessage.Text, " ")
|
args := strings.Split(u.EffectiveMessage.Text, " ")
|
||||||
help := `
|
help := i18n.T(i18nk.BotMsgParserHelpText, nil)
|
||||||
用法:
|
|
||||||
|
|
||||||
/parser install <回复一个文件> - 安装解析器
|
|
||||||
`
|
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
ctx.Reply(u, ext.ReplyTextString(help), nil)
|
ctx.Reply(u, ext.ReplyTextString(help), nil)
|
||||||
return nil
|
return nil
|
||||||
@@ -36,35 +34,35 @@ func handleParserCmd(ctx *ext.Context, u *ext.Update) error {
|
|||||||
|
|
||||||
func handleParserInstallCmd(ctx *ext.Context, u *ext.Update) error {
|
func handleParserInstallCmd(ctx *ext.Context, u *ext.Update) error {
|
||||||
if !config.C().Parser.PluginEnable {
|
if !config.C().Parser.PluginEnable {
|
||||||
ctx.Reply(u, ext.ReplyTextString("解析器插件功能未启用"), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParserPluginNotEnabled, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
if u.EffectiveMessage.ReplyToMessage == nil || u.EffectiveMessage.ReplyToMessage.Media == nil {
|
if u.EffectiveMessage.ReplyToMessage == nil || u.EffectiveMessage.ReplyToMessage.Media == nil {
|
||||||
ctx.Reply(u, ext.ReplyTextString("请回复一个包含解析器文件的消息"), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParserPromptReplyWithParserFile, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
media := u.EffectiveMessage.ReplyToMessage.Media
|
media := u.EffectiveMessage.ReplyToMessage.Media
|
||||||
document, ok := media.(*tg.MessageMediaDocument)
|
document, ok := media.(*tg.MessageMediaDocument)
|
||||||
if !ok {
|
if !ok {
|
||||||
ctx.Reply(u, ext.ReplyTextString("回复的消息不包含有效的文件"), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParserErrorNoValidFileInReply, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
value, ok := document.GetDocument()
|
value, ok := document.GetDocument()
|
||||||
if !ok {
|
if !ok {
|
||||||
ctx.Reply(u, ext.ReplyTextString("回复的消息不包含有效的文件"), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParserErrorNoValidFileInReply, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
doc, ok := value.AsNotEmpty()
|
doc, ok := value.AsNotEmpty()
|
||||||
if !ok {
|
if !ok {
|
||||||
ctx.Reply(u, ext.ReplyTextString("回复的消息不包含有效的文件"), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParserErrorNoValidFileInReply, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
if !strings.HasPrefix(doc.MimeType, "text/") {
|
if !strings.HasPrefix(doc.MimeType, "text/") {
|
||||||
ctx.Reply(u, ext.ReplyTextString("错误的文件类型"), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParserErrorWrongFileType, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
if doc.Size > 1024*1024*10 {
|
if doc.Size > 1024*1024*10 {
|
||||||
ctx.Reply(u, ext.ReplyTextString("文件过大"), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParserErrorFileTooLarge, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
var fileName string
|
var fileName string
|
||||||
@@ -75,23 +73,29 @@ func handleParserInstallCmd(ctx *ext.Context, u *ext.Update) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if fileName == "" {
|
if fileName == "" {
|
||||||
ctx.Reply(u, ext.ReplyTextString("无法获取文件名"), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParserErrorGetFilenameFailed, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
if !strings.HasSuffix(fileName, ".js") {
|
if !strings.HasSuffix(fileName, ".js") {
|
||||||
ctx.Reply(u, ext.ReplyTextString("仅支持 .js 文件作为解析器"), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParserErrorOnlyJsSupported, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
data := bytes.NewBuffer(nil)
|
data := bytes.NewBuffer(nil)
|
||||||
_, err := ctx.DownloadMedia(media, ext.DownloadOutputStream{Writer: data}, nil)
|
_, err := ctx.DownloadMedia(media, ext.DownloadOutputStream{Writer: data}, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Reply(u, ext.ReplyTextString("文件下载失败: "+err.Error()), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParserErrorDownloadFileFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
if err := parsers.AddPlugin(ctx, data.String(), fileName); err != nil {
|
if err := parsers.AddPlugin(ctx, data.String(), fileName); err != nil {
|
||||||
ctx.Reply(u, ext.ReplyTextString("插件安装失败: "+err.Error()), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParserErrorInstallPluginFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
ctx.Reply(u, ext.ReplyTextString("插件安装成功: "+fileName), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgParserInfoInstallPluginSuccess, map[string]any{
|
||||||
|
"Name": fileName,
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
|
|||||||
+19
-10
@@ -10,6 +10,8 @@ import (
|
|||||||
"github.com/charmbracelet/log"
|
"github.com/charmbracelet/log"
|
||||||
"github.com/duke-git/lancet/v2/slice"
|
"github.com/duke-git/lancet/v2/slice"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/common/utils/strutil"
|
"github.com/krau/SaveAny-Bot/common/utils/strutil"
|
||||||
"github.com/krau/SaveAny-Bot/database"
|
"github.com/krau/SaveAny-Bot/database"
|
||||||
"github.com/krau/SaveAny-Bot/pkg/rule"
|
"github.com/krau/SaveAny-Bot/pkg/rule"
|
||||||
@@ -22,7 +24,7 @@ func handleRuleCmd(ctx *ext.Context, update *ext.Update) error {
|
|||||||
user, err := database.GetUserByChatID(ctx, userChatID)
|
user, err := database.GetUserByChatID(ctx, userChatID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Failed to get user rules: %s", err)
|
logger.Errorf("Failed to get user rules: %s", err)
|
||||||
ctx.Reply(update, ext.ReplyTextString("获取用户规则失败"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgRuleErrorGetUserRulesFailed, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
if len(args) < 2 {
|
if len(args) < 2 {
|
||||||
@@ -35,10 +37,14 @@ func handleRuleCmd(ctx *ext.Context, update *ext.Update) error {
|
|||||||
applyRule := !user.ApplyRule
|
applyRule := !user.ApplyRule
|
||||||
if err := database.UpdateUserApplyRule(ctx, user.ChatID, applyRule); err != nil {
|
if err := database.UpdateUserApplyRule(ctx, user.ChatID, applyRule); err != nil {
|
||||||
logger.Errorf("更新用户失败: %s", err)
|
logger.Errorf("更新用户失败: %s", err)
|
||||||
ctx.Reply(update, ext.ReplyTextString("更新用户失败"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgRuleErrorUpdateUserFailed, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
ctx.Reply(update, ext.ReplyTextString(fmt.Sprintf("已%s规则模式", map[bool]string{true: "启用", false: "禁用"}[applyRule])), nil)
|
if applyRule {
|
||||||
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgRuleInfoRuleModeEnabled, nil)), nil)
|
||||||
|
} else {
|
||||||
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgRuleInfoRuleModeDisabled, nil)), nil)
|
||||||
|
}
|
||||||
case "add":
|
case "add":
|
||||||
// /rule add <type> <data> <storage> <dirpath>
|
// /rule add <type> <data> <storage> <dirpath>
|
||||||
if len(args) < 6 {
|
if len(args) < 6 {
|
||||||
@@ -55,7 +61,10 @@ func handleRuleCmd(ctx *ext.Context, update *ext.Update) error {
|
|||||||
return rule.RuleType(""), fmt.Errorf("无效的规则类型: %s\n可用: %v", ruleTypeArg, slice.Join(rule.Values(), ", "))
|
return rule.RuleType(""), fmt.Errorf("无效的规则类型: %s\n可用: %v", ruleTypeArg, slice.Join(rule.Values(), ", "))
|
||||||
}()
|
}()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Reply(update, ext.ReplyTextString(err.Error()), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgRuleErrorInvalidRuleType, map[string]any{
|
||||||
|
"Type": ruleTypeArg,
|
||||||
|
"Available": slice.Join(rule.Values(), ", "),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -72,28 +81,28 @@ func handleRuleCmd(ctx *ext.Context, update *ext.Update) error {
|
|||||||
}
|
}
|
||||||
if err := database.CreateRule(ctx, rd); err != nil {
|
if err := database.CreateRule(ctx, rd); err != nil {
|
||||||
logger.Errorf("创建规则失败: %s", err)
|
logger.Errorf("创建规则失败: %s", err)
|
||||||
ctx.Reply(update, ext.ReplyTextString("创建规则失败"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgRuleErrorCreateRuleFailed, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
ctx.Reply(update, ext.ReplyTextString("创建规则成功"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgRuleInfoCreateRuleSuccess, nil)), nil)
|
||||||
case "del":
|
case "del":
|
||||||
// /rule del <id>
|
// /rule del <id>
|
||||||
if len(args) < 3 {
|
if len(args) < 3 {
|
||||||
ctx.Reply(update, ext.ReplyTextString("请提供规则ID"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgRulePromptProvideRuleId, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
ruleID := args[2]
|
ruleID := args[2]
|
||||||
id, err := strconv.Atoi(ruleID)
|
id, err := strconv.Atoi(ruleID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Reply(update, ext.ReplyTextString("无效的规则ID"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgRuleErrorInvalidRuleId, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
if err := database.DeleteRule(ctx, uint(id)); err != nil {
|
if err := database.DeleteRule(ctx, uint(id)); err != nil {
|
||||||
logger.Errorf("删除规则失败: %s", err)
|
logger.Errorf("删除规则失败: %s", err)
|
||||||
ctx.Reply(update, ext.ReplyTextString("删除规则失败"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgRuleErrorDeleteRuleFailed, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
ctx.Reply(update, ext.ReplyTextString("删除规则成功"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgRuleInfoDeleteRuleSuccess, nil)), nil)
|
||||||
default:
|
default:
|
||||||
ctx.Reply(update, ext.ReplyTextStyledTextArray(msgelem.BuildRuleHelpStyling(user.ApplyRule, user.Rules)), nil)
|
ctx.Reply(update, ext.ReplyTextStyledTextArray(msgelem.BuildRuleHelpStyling(user.ApplyRule, user.Rules)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package handlers
|
package handlers
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/celestix/gotgproto/dispatcher"
|
"github.com/celestix/gotgproto/dispatcher"
|
||||||
@@ -9,6 +8,8 @@ import (
|
|||||||
"github.com/gotd/td/tg"
|
"github.com/gotd/td/tg"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
||||||
"github.com/krau/SaveAny-Bot/common/cache"
|
"github.com/krau/SaveAny-Bot/common/cache"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/database"
|
"github.com/krau/SaveAny-Bot/database"
|
||||||
"github.com/krau/SaveAny-Bot/pkg/tcbdata"
|
"github.com/krau/SaveAny-Bot/pkg/tcbdata"
|
||||||
"github.com/krau/SaveAny-Bot/storage"
|
"github.com/krau/SaveAny-Bot/storage"
|
||||||
@@ -17,20 +18,27 @@ import (
|
|||||||
func handleSilentCmd(ctx *ext.Context, update *ext.Update) error {
|
func handleSilentCmd(ctx *ext.Context, update *ext.Update) error {
|
||||||
user, err := database.GetUserByChatID(ctx, update.GetUserChat().GetID())
|
user, err := database.GetUserByChatID(ctx, update.GetUserChat().GetID())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Reply(update, ext.ReplyTextString("获取用户信息失败: "+err.Error()), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgCommonErrorGetUserInfoFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
if !user.Silent && user.DefaultStorage == "" {
|
if !user.Silent && user.DefaultStorage == "" {
|
||||||
ctx.Reply(update, ext.ReplyTextString("请先使用 /storage 设置默认存储位置"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgCommonErrorDefaultStorageNotSet, nil)), nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
user.Silent = !user.Silent
|
user.Silent = !user.Silent
|
||||||
if err := database.UpdateUser(ctx, user); err != nil {
|
if err := database.UpdateUser(ctx, user); err != nil {
|
||||||
ctx.Reply(update, ext.ReplyTextString("更新用户信息失败: "+err.Error()), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgCommonErrorUpdateUserInfoFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
responseText := "已" + map[bool]string{true: "开启", false: "关闭"}[user.Silent] + "静默模式"
|
if user.Silent {
|
||||||
ctx.Reply(update, ext.ReplyTextString(responseText), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgCommonInfoSilentModeOn, nil)), nil)
|
||||||
|
} else {
|
||||||
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgCommonInfoSilentModeOff, nil)), nil)
|
||||||
|
}
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,18 +57,22 @@ func handleSetDefaultCallback(ctx *ext.Context, update *ext.Update) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !ok {
|
if !ok {
|
||||||
return failedAnswer("数据已过期")
|
return failedAnswer(i18n.T(i18nk.BotMsgCommonErrorDataExpired, nil))
|
||||||
}
|
}
|
||||||
userID := update.CallbackQuery.GetUserID()
|
userID := update.CallbackQuery.GetUserID()
|
||||||
|
|
||||||
storageName := data.StorageName
|
storageName := data.StorageName
|
||||||
selectedStorage, err := storage.GetStorageByUserIDAndName(ctx, userID, storageName)
|
selectedStorage, err := storage.GetStorageByUserIDAndName(ctx, userID, storageName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return failedAnswer("存储获取失败: " + err.Error())
|
return failedAnswer(i18n.T(i18nk.BotMsgCommonErrorGetStorageFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
user, err := database.GetUserByChatID(ctx, userID)
|
user, err := database.GetUserByChatID(ctx, userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return failedAnswer("获取用户信息失败: " + err.Error())
|
return failedAnswer(i18n.T(i18nk.BotMsgCommonErrorGetUserInfoFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
var dir *database.Dir
|
var dir *database.Dir
|
||||||
if data.DirID != 0 {
|
if data.DirID != 0 {
|
||||||
@@ -68,24 +80,28 @@ func handleSetDefaultCallback(ctx *ext.Context, update *ext.Update) error {
|
|||||||
var err error
|
var err error
|
||||||
dir, err = database.GetDirByID(ctx, data.DirID)
|
dir, err = database.GetDirByID(ctx, data.DirID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return failedAnswer("获取文件夹信息失败: " + err.Error())
|
return failedAnswer(i18n.T(i18nk.BotMsgDirErrorGetUserDirsFailed, nil))
|
||||||
}
|
}
|
||||||
user.DefaultDir = dir.ID
|
user.DefaultDir = dir.ID
|
||||||
} else {
|
} else {
|
||||||
// 检查是否有可用的文件夹
|
// 检查是否有可用的文件夹
|
||||||
dirs, err := database.GetDirsByUserIDAndStorageName(ctx, user.ID, storageName)
|
dirs, err := database.GetDirsByUserIDAndStorageName(ctx, user.ID, storageName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return failedAnswer("获取目录失败: " + err.Error())
|
return failedAnswer(i18n.T(i18nk.BotMsgCommonErrorGetDirFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
if len(dirs) > 0 {
|
if len(dirs) > 0 {
|
||||||
// 要求选择文件夹
|
// 要求选择文件夹
|
||||||
markup, err := msgelem.BuildSetDefaultDirMarkup(ctx, storageName, dirs)
|
markup, err := msgelem.BuildSetDefaultDirMarkup(ctx, storageName, dirs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return failedAnswer("构建目录选择失败: " + err.Error())
|
return failedAnswer(i18n.T(i18nk.BotMsgCommonErrorBuildDirSelectKeyboardFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{
|
ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{
|
||||||
ID: update.CallbackQuery.GetMsgID(),
|
ID: update.CallbackQuery.GetMsgID(),
|
||||||
Message: "请选择要保存到的默认文件夹",
|
Message: i18n.T(i18nk.BotMsgCommonPromptSelectDefaultDir, nil),
|
||||||
ReplyMarkup: markup,
|
ReplyMarkup: markup,
|
||||||
})
|
})
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
@@ -93,11 +109,18 @@ func handleSetDefaultCallback(ctx *ext.Context, update *ext.Update) error {
|
|||||||
}
|
}
|
||||||
user.DefaultStorage = selectedStorage.Name()
|
user.DefaultStorage = selectedStorage.Name()
|
||||||
if err := database.UpdateUser(ctx, user); err != nil {
|
if err := database.UpdateUser(ctx, user); err != nil {
|
||||||
return failedAnswer("更新用户信息失败: " + err.Error())
|
return failedAnswer(i18n.T(i18nk.BotMsgCommonErrorUpdateUserInfoFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
}))
|
||||||
}
|
}
|
||||||
msg := fmt.Sprintf("已将默认存储位置设为: %s", selectedStorage.Name())
|
msg := i18n.T(i18nk.BotMsgCommonInfoDefaultStorageSet, map[string]any{
|
||||||
|
"Name": selectedStorage.Name(),
|
||||||
|
})
|
||||||
if dir != nil {
|
if dir != nil {
|
||||||
msg += fmt.Sprintf(":/%s", strings.TrimPrefix(dir.Path, "/"))
|
msg = i18n.T(i18nk.BotMsgCommonInfoDefaultStorageWithDirSet, map[string]any{
|
||||||
|
"Name": selectedStorage.Name(),
|
||||||
|
"Dir": strings.TrimPrefix(dir.Path, "/"),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{
|
ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{
|
||||||
ID: update.CallbackQuery.GetMsgID(),
|
ID: update.CallbackQuery.GetMsgID(),
|
||||||
@@ -110,15 +133,17 @@ func handleStorageCmd(ctx *ext.Context, update *ext.Update) error {
|
|||||||
userID := update.GetUserChat().GetID()
|
userID := update.GetUserChat().GetID()
|
||||||
storages := storage.GetUserStorages(ctx, userID)
|
storages := storage.GetUserStorages(ctx, userID)
|
||||||
if len(storages) == 0 {
|
if len(storages) == 0 {
|
||||||
ctx.Reply(update, ext.ReplyTextString("无可用的存储"), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgCommonErrorNoAvailableStorage, nil)), nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
markup, err := msgelem.BuildSetDefaultStorageMarkup(ctx, storages)
|
markup, err := msgelem.BuildSetDefaultStorageMarkup(ctx, storages)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Reply(update, ext.ReplyTextString("获取存储失败: "+err.Error()), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgCommonErrorGetStorageFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
ctx.Reply(update, ext.ReplyTextString("请选择要设为默认的存储位置"), &ext.ReplyOpts{
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgCommonPromptSelectDefaultStorage, nil)), &ext.ReplyOpts{
|
||||||
Markup: markup,
|
Markup: markup,
|
||||||
})
|
})
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ import (
|
|||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/dirutil"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/dirutil"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/msgelem"
|
||||||
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/shortcut"
|
"github.com/krau/SaveAny-Bot/client/bot/handlers/utils/shortcut"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/pkg/enums/tasktype"
|
"github.com/krau/SaveAny-Bot/pkg/enums/tasktype"
|
||||||
"github.com/krau/SaveAny-Bot/pkg/tcbdata"
|
"github.com/krau/SaveAny-Bot/pkg/tcbdata"
|
||||||
"github.com/krau/SaveAny-Bot/storage"
|
"github.com/krau/SaveAny-Bot/storage"
|
||||||
@@ -35,17 +37,19 @@ func handleTelegraphUrlMessage(ctx *ext.Context, update *ext.Update) error {
|
|||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Failed to build storage selection keyboard: %s", err)
|
logger.Errorf("Failed to build storage selection keyboard: %s", err)
|
||||||
ctx.Reply(update, ext.ReplyTextString("构建存储选择键盘失败: "+err.Error()), nil)
|
ctx.Reply(update, ext.ReplyTextString(i18n.T(i18nk.BotMsgTelegraphErrorBuildStorageSelectKeyboardFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
|
|
||||||
eb := entity.Builder{}
|
eb := entity.Builder{}
|
||||||
if err := styling.Perform(&eb,
|
if err := styling.Perform(&eb,
|
||||||
styling.Plain("标题: "),
|
styling.Plain(i18n.T(i18nk.BotMsgTelegraphInfoTitlePrefix, nil)),
|
||||||
styling.Code(result.Page.Title),
|
styling.Code(result.Page.Title),
|
||||||
styling.Plain("\n图片数量: "),
|
styling.Plain(i18n.T(i18nk.BotMsgTelegraphInfoPicCountPrefix, nil)),
|
||||||
styling.Code(fmt.Sprintf("%d", len(result.Pics))),
|
styling.Code(fmt.Sprintf("%d", len(result.Pics))),
|
||||||
styling.Plain("\n请选择存储位置"),
|
styling.Plain(i18n.T(i18nk.BotMsgTelegraphInfoPromptSelectStorage, nil)),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
log.FromContext(ctx).Errorf("Failed to build entity: %s", err)
|
log.FromContext(ctx).Errorf("Failed to build entity: %s", err)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ package handlers
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
@@ -11,6 +10,8 @@ import (
|
|||||||
"github.com/celestix/gotgproto/ext"
|
"github.com/celestix/gotgproto/ext"
|
||||||
"github.com/gotd/td/telegram/message/html"
|
"github.com/gotd/td/telegram/message/html"
|
||||||
"github.com/gotd/td/tg"
|
"github.com/gotd/td/tg"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/config"
|
"github.com/krau/SaveAny-Bot/config"
|
||||||
"github.com/unvgo/ghselfupdate"
|
"github.com/unvgo/ghselfupdate"
|
||||||
)
|
)
|
||||||
@@ -18,24 +19,33 @@ import (
|
|||||||
func handleUpdateCmd(ctx *ext.Context, u *ext.Update) error {
|
func handleUpdateCmd(ctx *ext.Context, u *ext.Update) error {
|
||||||
currentV, err := semver.Parse(config.Version)
|
currentV, err := semver.Parse(config.Version)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Reply(u, ext.ReplyTextString(fmt.Sprintf("You are in dev or the version var failed to inject: %v", err)), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgUpdateErrorVersionVarInvalid, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
latest, ok, err := ghselfupdate.DetectLatest(config.GitRepo)
|
latest, ok, err := ghselfupdate.DetectLatest(config.GitRepo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.Reply(u, ext.ReplyTextString(fmt.Sprintf("检测最新版本失败: %v", err)), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgUpdateErrorCheckLatestFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
if !ok {
|
if !ok {
|
||||||
ctx.Reply(u, ext.ReplyTextString("没有找到版本信息"), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgUpdateErrorNoReleaseFound, nil)), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
if latest.Version.Major != currentV.Major {
|
if latest.Version.Major != currentV.Major {
|
||||||
ctx.Reply(u, ext.ReplyTextString(fmt.Sprintf("检测到大版本更新: %s -> %s , 请前往 GitHub 手动下载最新版本并查看迁移指南", currentV, latest.Version)), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgUpdateInfoMajorUpgradeRequired, map[string]any{
|
||||||
|
"Current": currentV.String(),
|
||||||
|
"Latest": latest.Version.String(),
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
if latest.Version.LT(currentV) || latest.Version.Equals(currentV) {
|
if latest.Version.LT(currentV) || latest.Version.Equals(currentV) {
|
||||||
ctx.Reply(u, ext.ReplyTextString(fmt.Sprintf("当前已经是最新版本: %s", config.Version)), nil)
|
ctx.Reply(u, ext.ReplyTextString(i18n.T(i18nk.BotMsgUpdateInfoAlreadyLatest, map[string]any{
|
||||||
|
"Version": config.Version,
|
||||||
|
})), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
indocker := config.Docker == "true"
|
indocker := config.Docker == "true"
|
||||||
@@ -55,32 +65,28 @@ func handleUpdateCmd(ctx *ext.Context, u *ext.Update) error {
|
|||||||
return `<blockquote expandable>` + md + `</blockquote>`
|
return `<blockquote expandable>` + md + `</blockquote>`
|
||||||
}()))
|
}()))
|
||||||
if indocker {
|
if indocker {
|
||||||
text := fmt.Sprintf("发现新版本: %s\n当前版本: %s\n发布时间: %s\n由于您正在使用 Docker 部署, 请自行在部署平台上执行更新命令",
|
text := i18n.T(i18nk.BotMsgUpdateInfoNewVersionInDocker, map[string]any{
|
||||||
latest.Version,
|
"Latest": latest.Version.String(),
|
||||||
config.Version,
|
"Current": config.Version,
|
||||||
latest.PublishedAt.Format("2006-01-02 15:04:05"),
|
"PublishedAt": latest.PublishedAt.Format("2006-01-02 15:04:05"),
|
||||||
)
|
})
|
||||||
ctx.Reply(u, ext.ReplyTextString(text), nil)
|
ctx.Reply(u, ext.ReplyTextString(text), nil)
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
text := fmt.Sprintf(`发现新版本: %s
|
text := i18n.T(i18nk.BotMsgUpdateInfoNewVersionPromptUpgrade, map[string]any{
|
||||||
当前版本: %s
|
"Latest": latest.Version.String(),
|
||||||
|
"Current": config.Version,
|
||||||
文件大小: %.2f MB
|
"SizeMB": float64(latest.AssetByteSize) / (1024 * 1024),
|
||||||
下载链接: %s
|
"URL": latest.AssetURL,
|
||||||
发布时间: %s
|
"PublishedAt": latest.PublishedAt.Format("2006-01-02 15:04:05"),
|
||||||
|
})
|
||||||
升级将重启 Bot , 是否升级?`, latest.Version, config.Version,
|
|
||||||
float64(latest.AssetByteSize)/(1024*1024), latest.AssetURL,
|
|
||||||
latest.PublishedAt.Format("2006-01-02 15:04:05"),
|
|
||||||
)
|
|
||||||
ctx.Reply(u, ext.ReplyTextString(text), &ext.ReplyOpts{
|
ctx.Reply(u, ext.ReplyTextString(text), &ext.ReplyOpts{
|
||||||
Markup: &tg.ReplyInlineMarkup{
|
Markup: &tg.ReplyInlineMarkup{
|
||||||
Rows: []tg.KeyboardButtonRow{
|
Rows: []tg.KeyboardButtonRow{
|
||||||
{
|
{
|
||||||
Buttons: []tg.KeyboardButtonClass{
|
Buttons: []tg.KeyboardButtonClass{
|
||||||
&tg.KeyboardButtonCallback{
|
&tg.KeyboardButtonCallback{
|
||||||
Text: "升级",
|
Text: i18n.T(i18nk.BotMsgUpdateButtonUpgrade, nil),
|
||||||
Data: []byte("update"),
|
Data: []byte("update"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -98,19 +104,25 @@ func handleUpdateCallback(ctx *ext.Context, u *ext.Update) error {
|
|||||||
}
|
}
|
||||||
ctx.EditMessage(u.GetUserChat().GetID(), &tg.MessagesEditMessageRequest{
|
ctx.EditMessage(u.GetUserChat().GetID(), &tg.MessagesEditMessageRequest{
|
||||||
ID: u.CallbackQuery.GetMsgID(),
|
ID: u.CallbackQuery.GetMsgID(),
|
||||||
Message: fmt.Sprintf("正在升级中, 当前版本: %s", config.Version),
|
Message: i18n.T(i18nk.BotMsgUpdateInfoUpgradingWithVersion, map[string]any{
|
||||||
|
"Current": config.Version,
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
latest, err := ghselfupdate.UpdateSelf(currentV, config.GitRepo)
|
latest, err := ghselfupdate.UpdateSelf(currentV, config.GitRepo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ctx.EditMessage(u.GetUserChat().GetID(), &tg.MessagesEditMessageRequest{
|
ctx.EditMessage(u.GetUserChat().GetID(), &tg.MessagesEditMessageRequest{
|
||||||
ID: u.CallbackQuery.GetMsgID(),
|
ID: u.CallbackQuery.GetMsgID(),
|
||||||
Message: fmt.Sprintf("升级失败: %v", err),
|
Message: i18n.T(i18nk.BotMsgUpdateErrorUpgradeFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
ctx.EditMessage(u.GetUserChat().GetID(), &tg.MessagesEditMessageRequest{
|
ctx.EditMessage(u.GetUserChat().GetID(), &tg.MessagesEditMessageRequest{
|
||||||
ID: u.CallbackQuery.GetMsgID(),
|
ID: u.CallbackQuery.GetMsgID(),
|
||||||
Message: fmt.Sprintf("已升级至版本 %s\n若 Bot 未自动重启请手动启动", latest.Version),
|
Message: i18n.T(i18nk.BotMsgUpdateInfoUpgradeSuccess, map[string]any{
|
||||||
|
"Version": latest.Version.String(),
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
return errors.New("SAVEANTBOT-RESTART")
|
return errors.New("SAVEANTBOT-RESTART")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,22 +5,24 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gotd/td/telegram/message/styling"
|
"github.com/gotd/td/telegram/message/styling"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/database"
|
"github.com/krau/SaveAny-Bot/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BuildDirHelpStyling(dirs []database.Dir) []styling.StyledTextOption {
|
func BuildDirHelpStyling(dirs []database.Dir) []styling.StyledTextOption {
|
||||||
return []styling.StyledTextOption{
|
return []styling.StyledTextOption{
|
||||||
styling.Bold("使用方法: /dir <操作> <参数...>"),
|
styling.Bold(i18n.T(i18nk.BotMsgDirHelpUsage, nil)),
|
||||||
styling.Plain("\n\n可用操作:\n"),
|
styling.Plain(i18n.T(i18nk.BotMsgDirHelpAvailableOps, nil)),
|
||||||
styling.Code("add"),
|
styling.Code("add"),
|
||||||
styling.Plain(" <存储名> <路径> - 添加路径\n"),
|
styling.Plain(i18n.T(i18nk.BotMsgDirHelpAddSuffix, nil)),
|
||||||
styling.Code("del"),
|
styling.Code("del"),
|
||||||
styling.Plain(" <路径ID> - 删除路径\n"),
|
styling.Plain(i18n.T(i18nk.BotMsgDirHelpDelSuffix, nil)),
|
||||||
styling.Plain("\n添加路径示例:\n"),
|
styling.Plain(i18n.T(i18nk.BotMsgDirHelpAddExamplePrefix, nil)),
|
||||||
styling.Code("/dir add local1 path/to/dir"),
|
styling.Code(i18n.T(i18nk.BotMsgDirHelpAddExampleCmd, nil)),
|
||||||
styling.Plain("\n\n删除路径示例:\n"),
|
styling.Plain(i18n.T(i18nk.BotMsgDirHelpDelExamplePrefix, nil)),
|
||||||
styling.Code("/dir del 3"),
|
styling.Code(i18n.T(i18nk.BotMsgDirHelpDelExampleCmd, nil)),
|
||||||
styling.Plain("\n\n当前已添加的路径:\n"),
|
styling.Plain(i18n.T(i18nk.BotMsgDirHelpExistingDirsPrefix, nil)),
|
||||||
styling.Blockquote(func() string {
|
styling.Blockquote(func() string {
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
for _, dir := range dirs {
|
for _, dir := range dirs {
|
||||||
|
|||||||
@@ -7,6 +7,8 @@ import (
|
|||||||
"github.com/gotd/td/telegram/message/entity"
|
"github.com/gotd/td/telegram/message/entity"
|
||||||
"github.com/gotd/td/telegram/message/styling"
|
"github.com/gotd/td/telegram/message/styling"
|
||||||
"github.com/gotd/td/tg"
|
"github.com/gotd/td/tg"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/pkg/parser"
|
"github.com/krau/SaveAny-Bot/pkg/parser"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -14,15 +16,15 @@ func BuildParsedTextEntity(item parser.Item) (string, []tg.MessageEntityClass, e
|
|||||||
eb := entity.Builder{}
|
eb := entity.Builder{}
|
||||||
if err := styling.Perform(&eb,
|
if err := styling.Perform(&eb,
|
||||||
styling.Bold(fmt.Sprintf("[%s]%s", item.Site, item.Title)),
|
styling.Bold(fmt.Sprintf("[%s]%s", item.Site, item.Title)),
|
||||||
styling.Plain("\n链接: "),
|
styling.Plain(i18n.T(i18nk.BotMsgParseInfoLinkPrefix, nil)),
|
||||||
styling.Code(item.URL),
|
styling.Code(item.URL),
|
||||||
styling.Plain("\n作者: "),
|
styling.Plain(i18n.T(i18nk.BotMsgParseInfoAuthorPrefix, nil)),
|
||||||
styling.Code(item.Author),
|
styling.Code(item.Author),
|
||||||
styling.Plain("\n描述: "),
|
styling.Plain(i18n.T(i18nk.BotMsgParseInfoDescriptionPrefix, nil)),
|
||||||
styling.Code(strutil.Ellipsis(item.Description, 233)),
|
styling.Code(strutil.Ellipsis(item.Description, 233)),
|
||||||
styling.Plain("\n文件数量: "),
|
styling.Plain(i18n.T(i18nk.BotMsgParseInfoFileCountPrefix, nil)),
|
||||||
styling.Code(fmt.Sprintf("%d", len(item.Resources))),
|
styling.Code(fmt.Sprintf("%d", len(item.Resources))),
|
||||||
styling.Plain("\n预计总大小: "),
|
styling.Plain(i18n.T(i18nk.BotMsgParseInfoTotalSizePrefix, nil)),
|
||||||
styling.Code(fmt.Sprintf("%.2f MB", func() float64 {
|
styling.Code(fmt.Sprintf("%.2f MB", func() float64 {
|
||||||
var totalSize int64
|
var totalSize int64
|
||||||
for _, res := range item.Resources {
|
for _, res := range item.Resources {
|
||||||
@@ -30,9 +32,9 @@ func BuildParsedTextEntity(item parser.Item) (string, []tg.MessageEntityClass, e
|
|||||||
}
|
}
|
||||||
return float64(totalSize) / 1024 / 1024
|
return float64(totalSize) / 1024 / 1024
|
||||||
}())),
|
}())),
|
||||||
styling.Plain("\n请选择存储位置"),
|
styling.Plain(i18n.T(i18nk.BotMsgParseInfoPromptSelectStorage, nil)),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return "", nil, fmt.Errorf("构建消息失败: %w", err)
|
return "", nil, fmt.Errorf("failed to build parsed text entity: %w", err)
|
||||||
}
|
}
|
||||||
text, entities := eb.Complete()
|
text, entities := eb.Complete()
|
||||||
return text, entities, nil
|
return text, entities, nil
|
||||||
|
|||||||
@@ -5,21 +5,28 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/gotd/td/telegram/message/styling"
|
"github.com/gotd/td/telegram/message/styling"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/database"
|
"github.com/krau/SaveAny-Bot/database"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BuildRuleHelpStyling(enabled bool, rules []database.Rule) []styling.StyledTextOption {
|
func BuildRuleHelpStyling(enabled bool, rules []database.Rule) []styling.StyledTextOption {
|
||||||
return []styling.StyledTextOption{
|
return []styling.StyledTextOption{
|
||||||
styling.Bold("使用方法: /rule <操作> <参数...>"),
|
styling.Bold(i18n.T(i18nk.BotMsgRuleHelpUsage, nil)),
|
||||||
styling.Bold(fmt.Sprintf("\n当前已%s规则模式", map[bool]string{true: "启用", false: "禁用"}[enabled])),
|
styling.Bold(func() string {
|
||||||
styling.Plain("\n\n可用操作:\n"),
|
if enabled {
|
||||||
|
return i18n.T(i18nk.BotMsgRuleHelpCurrentModeEnabled, nil)
|
||||||
|
}
|
||||||
|
return i18n.T(i18nk.BotMsgRuleHelpCurrentModeDisabled, nil)
|
||||||
|
}()),
|
||||||
|
styling.Plain(i18n.T(i18nk.BotMsgRuleHelpAvailableOps, nil)),
|
||||||
styling.Code("switch"),
|
styling.Code("switch"),
|
||||||
styling.Plain(" - 开关规则模式\n"),
|
styling.Plain(i18n.T(i18nk.BotMsgRuleHelpSwitchSuffix, nil)),
|
||||||
styling.Code("add"),
|
styling.Code("add"),
|
||||||
styling.Plain(" <类型> <数据> <存储名> <路径> - 添加规则\n"),
|
styling.Plain(i18n.T(i18nk.BotMsgRuleHelpAddSuffix, nil)),
|
||||||
styling.Code("del"),
|
styling.Code("del"),
|
||||||
styling.Plain(" <规则ID> - 删除规则\n"),
|
styling.Plain(i18n.T(i18nk.BotMsgRuleHelpDelSuffix, nil)),
|
||||||
styling.Plain("\n当前已添加的规则:\n"),
|
styling.Plain(i18n.T(i18nk.BotMsgRuleHelpExistingRulesPrefix, nil)),
|
||||||
styling.Blockquote(func() string {
|
styling.Blockquote(func() string {
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
for _, rule := range rules {
|
for _, rule := range rules {
|
||||||
|
|||||||
@@ -9,6 +9,8 @@ import (
|
|||||||
"github.com/gotd/td/telegram/message/styling"
|
"github.com/gotd/td/telegram/message/styling"
|
||||||
"github.com/gotd/td/tg"
|
"github.com/gotd/td/tg"
|
||||||
"github.com/krau/SaveAny-Bot/common/cache"
|
"github.com/krau/SaveAny-Bot/common/cache"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/database"
|
"github.com/krau/SaveAny-Bot/database"
|
||||||
"github.com/krau/SaveAny-Bot/pkg/enums/tasktype"
|
"github.com/krau/SaveAny-Bot/pkg/enums/tasktype"
|
||||||
"github.com/krau/SaveAny-Bot/pkg/tcbdata"
|
"github.com/krau/SaveAny-Bot/pkg/tcbdata"
|
||||||
@@ -70,11 +72,14 @@ func BuildAddSelectStorageKeyboard(stors []storage.Storage, adddata tcbdata.Add)
|
|||||||
func BuildAddOneSelectStorageMessage(ctx context.Context, stors []storage.Storage, file tfile.TGFileMessage, msgId int) (*tg.MessagesEditMessageRequest, error) {
|
func BuildAddOneSelectStorageMessage(ctx context.Context, stors []storage.Storage, file tfile.TGFileMessage, msgId int) (*tg.MessagesEditMessageRequest, error) {
|
||||||
eb := entity.Builder{}
|
eb := entity.Builder{}
|
||||||
var entities []tg.MessageEntityClass
|
var entities []tg.MessageEntityClass
|
||||||
text := fmt.Sprintf("文件名: %s\n请选择存储位置", file.Name())
|
text := i18n.T(i18nk.BotMsgTasksInfoAddedToQueueFull, map[string]any{
|
||||||
|
"Filename": file.Name(),
|
||||||
|
"QueueLength": 0,
|
||||||
|
})
|
||||||
if err := styling.Perform(&eb,
|
if err := styling.Perform(&eb,
|
||||||
styling.Plain("文件名: "),
|
styling.Plain(i18n.T(i18nk.BotMsgStorageInfoFilenamePrefix, nil)),
|
||||||
styling.Code(file.Name()),
|
styling.Code(file.Name()),
|
||||||
styling.Plain("\n请选择存储位置"),
|
styling.Plain(i18n.T(i18nk.BotMsgStorageInfoPromptSelectStorage, nil)),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
log.FromContext(ctx).Errorf("Failed to build entity: %s", err)
|
log.FromContext(ctx).Errorf("Failed to build entity: %s", err)
|
||||||
} else {
|
} else {
|
||||||
@@ -185,7 +190,7 @@ func BuildSetDirMarkupForAdd(dirs []database.Dir, dataid string) (*tg.ReplyInlin
|
|||||||
return nil, fmt.Errorf("failed to set default directory data in cache: %w", err)
|
return nil, fmt.Errorf("failed to set default directory data in cache: %w", err)
|
||||||
}
|
}
|
||||||
buttons = append(buttons, &tg.KeyboardButtonCallback{
|
buttons = append(buttons, &tg.KeyboardButtonCallback{
|
||||||
Text: "默认",
|
Text: i18n.T(i18nk.BotMsgDirButtonDefault, nil),
|
||||||
Data: fmt.Appendf(nil, "%s %s", tcbdata.TypeAdd, dirDefaultDataId),
|
Data: fmt.Appendf(nil, "%s %s", tcbdata.TypeAdd, dirDefaultDataId),
|
||||||
})
|
})
|
||||||
markup := &tg.ReplyInlineMarkup{}
|
markup := &tg.ReplyInlineMarkup{}
|
||||||
|
|||||||
@@ -2,13 +2,14 @@ package msgelem
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"github.com/charmbracelet/log"
|
"github.com/charmbracelet/log"
|
||||||
"github.com/gotd/td/telegram/message/entity"
|
"github.com/gotd/td/telegram/message/entity"
|
||||||
"github.com/gotd/td/telegram/message/styling"
|
"github.com/gotd/td/telegram/message/styling"
|
||||||
"github.com/gotd/td/tg"
|
"github.com/gotd/td/tg"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
)
|
)
|
||||||
|
|
||||||
func BuildTaskAddedEntities(
|
func BuildTaskAddedEntities(
|
||||||
@@ -18,11 +19,15 @@ func BuildTaskAddedEntities(
|
|||||||
) (string, []tg.MessageEntityClass) {
|
) (string, []tg.MessageEntityClass) {
|
||||||
entityBuilder := entity.Builder{}
|
entityBuilder := entity.Builder{}
|
||||||
var entities []tg.MessageEntityClass
|
var entities []tg.MessageEntityClass
|
||||||
text := fmt.Sprintf("已添加到任务队列\n文件名: %s\n当前排队任务数: %d", filename, queueLength)
|
text := i18n.T(i18nk.BotMsgTasksInfoAddedToQueueFull, map[string]any{
|
||||||
|
"Filename": filename,
|
||||||
|
"QueueLength": queueLength,
|
||||||
|
})
|
||||||
if err := styling.Perform(&entityBuilder,
|
if err := styling.Perform(&entityBuilder,
|
||||||
styling.Plain("已添加到任务队列\n文件名: "),
|
styling.Plain(i18n.T(i18nk.BotMsgTasksInfoAddedToQueuePrefix, nil)),
|
||||||
|
styling.Plain(i18n.T(i18nk.BotMsgTasksInfoFilenamePrefix, nil)),
|
||||||
styling.Code(filename),
|
styling.Code(filename),
|
||||||
styling.Plain("\n当前排队任务数: "),
|
styling.Plain(i18n.T(i18nk.BotMsgTasksInfoQueueLengthPrefix, nil)),
|
||||||
styling.Bold(strconv.Itoa(queueLength)),
|
styling.Bold(strconv.Itoa(queueLength)),
|
||||||
); err != nil {
|
); err != nil {
|
||||||
log.FromContext(ctx).Errorf("Failed to build entity: %s", err)
|
log.FromContext(ctx).Errorf("Failed to build entity: %s", err)
|
||||||
|
|||||||
@@ -5,6 +5,8 @@ import (
|
|||||||
"github.com/celestix/gotgproto/ext"
|
"github.com/celestix/gotgproto/ext"
|
||||||
"github.com/charmbracelet/log"
|
"github.com/charmbracelet/log"
|
||||||
"github.com/gotd/td/tg"
|
"github.com/gotd/td/tg"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n"
|
||||||
|
"github.com/krau/SaveAny-Bot/common/i18n/i18nk"
|
||||||
"github.com/krau/SaveAny-Bot/common/utils/tgutil"
|
"github.com/krau/SaveAny-Bot/common/utils/tgutil"
|
||||||
"github.com/krau/SaveAny-Bot/core"
|
"github.com/krau/SaveAny-Bot/core"
|
||||||
"github.com/krau/SaveAny-Bot/core/tasks/directlinks"
|
"github.com/krau/SaveAny-Bot/core/tasks/directlinks"
|
||||||
@@ -18,13 +20,15 @@ func CreateAndAddDirectTaskWithEdit(ctx *ext.Context, stor storage.Storage, dirP
|
|||||||
if err := core.AddTask(injectCtx, task); err != nil {
|
if err := core.AddTask(injectCtx, task); err != nil {
|
||||||
log.FromContext(ctx).Errorf("Failed to add task: %s", err)
|
log.FromContext(ctx).Errorf("Failed to add task: %s", err)
|
||||||
ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{
|
ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{
|
||||||
ID: msgID,
|
ID: msgID,
|
||||||
Message: "任务添加失败: " + err.Error(),
|
Message: i18n.T(i18nk.BotMsgCommonErrorTaskAddFailed, map[string]any{
|
||||||
|
"Error": err.Error(),
|
||||||
|
}),
|
||||||
})
|
})
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{
|
ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{
|
||||||
Message: "任务已添加",
|
Message: i18n.T(i18nk.BotMsgCommonInfoTaskAdded, nil),
|
||||||
})
|
})
|
||||||
return dispatcher.EndGroups
|
return dispatcher.EndGroups
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ const (
|
|||||||
BotMsgCancelInfoCancelRequested Key = "bot.msg.cancel.info_cancel_requested"
|
BotMsgCancelInfoCancelRequested Key = "bot.msg.cancel.info_cancel_requested"
|
||||||
BotMsgCancelInfoCancellingTask Key = "bot.msg.cancel.info_cancelling_task"
|
BotMsgCancelInfoCancellingTask Key = "bot.msg.cancel.info_cancelling_task"
|
||||||
BotMsgCancelUsage Key = "bot.msg.cancel.usage"
|
BotMsgCancelUsage Key = "bot.msg.cancel.usage"
|
||||||
|
BotMsgCommonErrorBuildDirSelectKeyboardFailed Key = "bot.msg.common.error_build_dir_select_keyboard_failed"
|
||||||
BotMsgCommonErrorBuildStorageSelectKeyboardFailed Key = "bot.msg.common.error_build_storage_select_keyboard_failed"
|
BotMsgCommonErrorBuildStorageSelectKeyboardFailed Key = "bot.msg.common.error_build_storage_select_keyboard_failed"
|
||||||
BotMsgCommonErrorBuildStorageSelectMessageFailed Key = "bot.msg.common.error_build_storage_select_message_failed"
|
BotMsgCommonErrorBuildStorageSelectMessageFailed Key = "bot.msg.common.error_build_storage_select_message_failed"
|
||||||
BotMsgCommonErrorDataExpired Key = "bot.msg.common.error_data_expired"
|
BotMsgCommonErrorDataExpired Key = "bot.msg.common.error_data_expired"
|
||||||
@@ -26,6 +27,7 @@ const (
|
|||||||
BotMsgCommonErrorNoAvailableStorage Key = "bot.msg.common.error_no_available_storage"
|
BotMsgCommonErrorNoAvailableStorage Key = "bot.msg.common.error_no_available_storage"
|
||||||
BotMsgCommonErrorNoImagesInTelegraphPage Key = "bot.msg.common.error_no_images_in_telegraph_page"
|
BotMsgCommonErrorNoImagesInTelegraphPage Key = "bot.msg.common.error_no_images_in_telegraph_page"
|
||||||
BotMsgCommonErrorNoMessagesInRange Key = "bot.msg.common.error_no_messages_in_range"
|
BotMsgCommonErrorNoMessagesInRange Key = "bot.msg.common.error_no_messages_in_range"
|
||||||
|
BotMsgCommonErrorNoPermission Key = "bot.msg.common.error_no_permission"
|
||||||
BotMsgCommonErrorNoSavableFilesFound Key = "bot.msg.common.error_no_savable_files_found"
|
BotMsgCommonErrorNoSavableFilesFound Key = "bot.msg.common.error_no_savable_files_found"
|
||||||
BotMsgCommonErrorNoSavableMessagesInRange Key = "bot.msg.common.error_no_savable_messages_in_range"
|
BotMsgCommonErrorNoSavableMessagesInRange Key = "bot.msg.common.error_no_savable_messages_in_range"
|
||||||
BotMsgCommonErrorParseTelegraphPathFailed Key = "bot.msg.common.error_parse_telegraph_path_failed"
|
BotMsgCommonErrorParseTelegraphPathFailed Key = "bot.msg.common.error_parse_telegraph_path_failed"
|
||||||
@@ -49,18 +51,32 @@ const (
|
|||||||
BotMsgConfigErrorInvalidCallbackData Key = "bot.msg.config.error_invalid_callback_data"
|
BotMsgConfigErrorInvalidCallbackData Key = "bot.msg.config.error_invalid_callback_data"
|
||||||
BotMsgConfigErrorInvalidTemplate Key = "bot.msg.config.error_invalid_template"
|
BotMsgConfigErrorInvalidTemplate Key = "bot.msg.config.error_invalid_template"
|
||||||
BotMsgConfigFnametmplHelp Key = "bot.msg.config.fnametmpl_help"
|
BotMsgConfigFnametmplHelp Key = "bot.msg.config.fnametmpl_help"
|
||||||
|
BotMsgConfigInfoCurrentTemplatePrefix Key = "bot.msg.config.info_current_template_prefix"
|
||||||
BotMsgConfigInfoFilenameStrategySet Key = "bot.msg.config.info_filename_strategy_set"
|
BotMsgConfigInfoFilenameStrategySet Key = "bot.msg.config.info_filename_strategy_set"
|
||||||
BotMsgConfigInfoTemplateUpdated Key = "bot.msg.config.info_template_updated"
|
BotMsgConfigInfoTemplateUpdated Key = "bot.msg.config.info_template_updated"
|
||||||
BotMsgConfigPromptSelectFilenameStrategy Key = "bot.msg.config.prompt_select_filename_strategy"
|
BotMsgConfigPromptSelectFilenameStrategy Key = "bot.msg.config.prompt_select_filename_strategy"
|
||||||
BotMsgConfigPromptSelectOption Key = "bot.msg.config.prompt_select_option"
|
BotMsgConfigPromptSelectOption Key = "bot.msg.config.prompt_select_option"
|
||||||
|
BotMsgDirButtonDefault Key = "bot.msg.dir.button_default"
|
||||||
BotMsgDirErrorCreateDirFailed Key = "bot.msg.dir.error_create_dir_failed"
|
BotMsgDirErrorCreateDirFailed Key = "bot.msg.dir.error_create_dir_failed"
|
||||||
BotMsgDirErrorDeleteDirFailed Key = "bot.msg.dir.error_delete_dir_failed"
|
BotMsgDirErrorDeleteDirFailed Key = "bot.msg.dir.error_delete_dir_failed"
|
||||||
BotMsgDirErrorGetUserDirsFailed Key = "bot.msg.dir.error_get_user_dirs_failed"
|
BotMsgDirErrorGetUserDirsFailed Key = "bot.msg.dir.error_get_user_dirs_failed"
|
||||||
BotMsgDirErrorGetUserFailed Key = "bot.msg.dir.error_get_user_failed"
|
BotMsgDirErrorGetUserFailed Key = "bot.msg.dir.error_get_user_failed"
|
||||||
BotMsgDirErrorInvalidDirId Key = "bot.msg.dir.error_invalid_dir_id"
|
BotMsgDirErrorInvalidDirId Key = "bot.msg.dir.error_invalid_dir_id"
|
||||||
BotMsgDirErrorUnknownOperation Key = "bot.msg.dir.error_unknown_operation"
|
BotMsgDirErrorUnknownOperation Key = "bot.msg.dir.error_unknown_operation"
|
||||||
|
BotMsgDirHelpAddExampleCmd Key = "bot.msg.dir.help_add_example_cmd"
|
||||||
|
BotMsgDirHelpAddExamplePrefix Key = "bot.msg.dir.help_add_example_prefix"
|
||||||
|
BotMsgDirHelpAddSuffix Key = "bot.msg.dir.help_add_suffix"
|
||||||
|
BotMsgDirHelpAvailableOps Key = "bot.msg.dir.help_available_ops"
|
||||||
|
BotMsgDirHelpDelExampleCmd Key = "bot.msg.dir.help_del_example_cmd"
|
||||||
|
BotMsgDirHelpDelExamplePrefix Key = "bot.msg.dir.help_del_example_prefix"
|
||||||
|
BotMsgDirHelpDelSuffix Key = "bot.msg.dir.help_del_suffix"
|
||||||
|
BotMsgDirHelpExistingDirsPrefix Key = "bot.msg.dir.help_existing_dirs_prefix"
|
||||||
|
BotMsgDirHelpUsage Key = "bot.msg.dir.help_usage"
|
||||||
BotMsgDirInfoCreateDirSuccess Key = "bot.msg.dir.info_create_dir_success"
|
BotMsgDirInfoCreateDirSuccess Key = "bot.msg.dir.info_create_dir_success"
|
||||||
BotMsgDirInfoDeleteDirSuccess Key = "bot.msg.dir.info_delete_dir_success"
|
BotMsgDirInfoDeleteDirSuccess Key = "bot.msg.dir.info_delete_dir_success"
|
||||||
|
BotMsgDlErrorNoValidLinks Key = "bot.msg.dl.error_no_valid_links"
|
||||||
|
BotMsgDlInfoFilesSelectStorage Key = "bot.msg.dl.info_files_select_storage"
|
||||||
|
BotMsgDlUsage Key = "bot.msg.dl.usage"
|
||||||
BotMsgHelpTextFmt Key = "bot.msg.help_text_fmt"
|
BotMsgHelpTextFmt Key = "bot.msg.help_text_fmt"
|
||||||
BotMsgMediaGroupErrorBuildStorageSelectKeyboardFailed Key = "bot.msg.media_group.error_build_storage_select_keyboard_failed"
|
BotMsgMediaGroupErrorBuildStorageSelectKeyboardFailed Key = "bot.msg.media_group.error_build_storage_select_keyboard_failed"
|
||||||
BotMsgMediaGroupInfoGroupFoundFilesSelectStorage Key = "bot.msg.media_group.info_group_found_files_select_storage"
|
BotMsgMediaGroupInfoGroupFoundFilesSelectStorage Key = "bot.msg.media_group.info_group_found_files_select_storage"
|
||||||
@@ -68,7 +84,13 @@ const (
|
|||||||
BotMsgParseErrorBuildParsedTextEntityFailed Key = "bot.msg.parse.error_build_parsed_text_entity_failed"
|
BotMsgParseErrorBuildParsedTextEntityFailed Key = "bot.msg.parse.error_build_parsed_text_entity_failed"
|
||||||
BotMsgParseErrorBuildStorageSelectKeyboardFailed Key = "bot.msg.parse.error_build_storage_select_keyboard_failed"
|
BotMsgParseErrorBuildStorageSelectKeyboardFailed Key = "bot.msg.parse.error_build_storage_select_keyboard_failed"
|
||||||
BotMsgParseErrorParseTextFailed Key = "bot.msg.parse.error_parse_text_failed"
|
BotMsgParseErrorParseTextFailed Key = "bot.msg.parse.error_parse_text_failed"
|
||||||
|
BotMsgParseInfoAuthorPrefix Key = "bot.msg.parse.info_author_prefix"
|
||||||
|
BotMsgParseInfoDescriptionPrefix Key = "bot.msg.parse.info_description_prefix"
|
||||||
|
BotMsgParseInfoFileCountPrefix Key = "bot.msg.parse.info_file_count_prefix"
|
||||||
|
BotMsgParseInfoLinkPrefix Key = "bot.msg.parse.info_link_prefix"
|
||||||
BotMsgParseInfoParsing Key = "bot.msg.parse.info_parsing"
|
BotMsgParseInfoParsing Key = "bot.msg.parse.info_parsing"
|
||||||
|
BotMsgParseInfoPromptSelectStorage Key = "bot.msg.parse.info_prompt_select_storage"
|
||||||
|
BotMsgParseInfoTotalSizePrefix Key = "bot.msg.parse.info_total_size_prefix"
|
||||||
BotMsgParserErrorDownloadFileFailed Key = "bot.msg.parser.error_download_file_failed"
|
BotMsgParserErrorDownloadFileFailed Key = "bot.msg.parser.error_download_file_failed"
|
||||||
BotMsgParserErrorFileTooLarge Key = "bot.msg.parser.error_file_too_large"
|
BotMsgParserErrorFileTooLarge Key = "bot.msg.parser.error_file_too_large"
|
||||||
BotMsgParserErrorGetFilenameFailed Key = "bot.msg.parser.error_get_filename_failed"
|
BotMsgParserErrorGetFilenameFailed Key = "bot.msg.parser.error_get_filename_failed"
|
||||||
@@ -86,6 +108,14 @@ const (
|
|||||||
BotMsgRuleErrorInvalidRuleId Key = "bot.msg.rule.error_invalid_rule_id"
|
BotMsgRuleErrorInvalidRuleId Key = "bot.msg.rule.error_invalid_rule_id"
|
||||||
BotMsgRuleErrorInvalidRuleType Key = "bot.msg.rule.error_invalid_rule_type"
|
BotMsgRuleErrorInvalidRuleType Key = "bot.msg.rule.error_invalid_rule_type"
|
||||||
BotMsgRuleErrorUpdateUserFailed Key = "bot.msg.rule.error_update_user_failed"
|
BotMsgRuleErrorUpdateUserFailed Key = "bot.msg.rule.error_update_user_failed"
|
||||||
|
BotMsgRuleHelpAddSuffix Key = "bot.msg.rule.help_add_suffix"
|
||||||
|
BotMsgRuleHelpAvailableOps Key = "bot.msg.rule.help_available_ops"
|
||||||
|
BotMsgRuleHelpCurrentModeDisabled Key = "bot.msg.rule.help_current_mode_disabled"
|
||||||
|
BotMsgRuleHelpCurrentModeEnabled Key = "bot.msg.rule.help_current_mode_enabled"
|
||||||
|
BotMsgRuleHelpDelSuffix Key = "bot.msg.rule.help_del_suffix"
|
||||||
|
BotMsgRuleHelpExistingRulesPrefix Key = "bot.msg.rule.help_existing_rules_prefix"
|
||||||
|
BotMsgRuleHelpSwitchSuffix Key = "bot.msg.rule.help_switch_suffix"
|
||||||
|
BotMsgRuleHelpUsage Key = "bot.msg.rule.help_usage"
|
||||||
BotMsgRuleInfoCreateRuleSuccess Key = "bot.msg.rule.info_create_rule_success"
|
BotMsgRuleInfoCreateRuleSuccess Key = "bot.msg.rule.info_create_rule_success"
|
||||||
BotMsgRuleInfoDeleteRuleSuccess Key = "bot.msg.rule.info_delete_rule_success"
|
BotMsgRuleInfoDeleteRuleSuccess Key = "bot.msg.rule.info_delete_rule_success"
|
||||||
BotMsgRuleInfoRuleModeDisabled Key = "bot.msg.rule.info_rule_mode_disabled"
|
BotMsgRuleInfoRuleModeDisabled Key = "bot.msg.rule.info_rule_mode_disabled"
|
||||||
@@ -93,12 +123,18 @@ const (
|
|||||||
BotMsgRulePromptProvideRuleId Key = "bot.msg.rule.prompt_provide_rule_id"
|
BotMsgRulePromptProvideRuleId Key = "bot.msg.rule.prompt_provide_rule_id"
|
||||||
BotMsgSaveErrorInvalidIdOrUsername Key = "bot.msg.save.error_invalid_id_or_username"
|
BotMsgSaveErrorInvalidIdOrUsername Key = "bot.msg.save.error_invalid_id_or_username"
|
||||||
BotMsgSaveHelpText Key = "bot.msg.save_help_text"
|
BotMsgSaveHelpText Key = "bot.msg.save_help_text"
|
||||||
|
BotMsgStorageInfoFilenamePrefix Key = "bot.msg.storage.info_filename_prefix"
|
||||||
|
BotMsgStorageInfoPromptSelectStorage Key = "bot.msg.storage.info_prompt_select_storage"
|
||||||
BotMsgTasksCancelFailed Key = "bot.msg.tasks.cancel_failed"
|
BotMsgTasksCancelFailed Key = "bot.msg.tasks.cancel_failed"
|
||||||
BotMsgTasksCancelRequestedPrefix Key = "bot.msg.tasks.cancel_requested_prefix"
|
BotMsgTasksCancelRequestedPrefix Key = "bot.msg.tasks.cancel_requested_prefix"
|
||||||
BotMsgTasksFieldCreated Key = "bot.msg.tasks.field_created"
|
BotMsgTasksFieldCreated Key = "bot.msg.tasks.field_created"
|
||||||
BotMsgTasksFieldId Key = "bot.msg.tasks.field_id"
|
BotMsgTasksFieldId Key = "bot.msg.tasks.field_id"
|
||||||
BotMsgTasksFieldStatus Key = "bot.msg.tasks.field_status"
|
BotMsgTasksFieldStatus Key = "bot.msg.tasks.field_status"
|
||||||
BotMsgTasksFieldTitle Key = "bot.msg.tasks.field_title"
|
BotMsgTasksFieldTitle Key = "bot.msg.tasks.field_title"
|
||||||
|
BotMsgTasksInfoAddedToQueueFull Key = "bot.msg.tasks.info_added_to_queue_full"
|
||||||
|
BotMsgTasksInfoAddedToQueuePrefix Key = "bot.msg.tasks.info_added_to_queue_prefix"
|
||||||
|
BotMsgTasksInfoFilenamePrefix Key = "bot.msg.tasks.info_filename_prefix"
|
||||||
|
BotMsgTasksInfoQueueLengthPrefix Key = "bot.msg.tasks.info_queue_length_prefix"
|
||||||
BotMsgTasksQueuedEmpty Key = "bot.msg.tasks.queued_empty"
|
BotMsgTasksQueuedEmpty Key = "bot.msg.tasks.queued_empty"
|
||||||
BotMsgTasksQueuedTitle Key = "bot.msg.tasks.queued_title"
|
BotMsgTasksQueuedTitle Key = "bot.msg.tasks.queued_title"
|
||||||
BotMsgTasksRunningEmpty Key = "bot.msg.tasks.running_empty"
|
BotMsgTasksRunningEmpty Key = "bot.msg.tasks.running_empty"
|
||||||
|
|||||||
@@ -103,6 +103,10 @@ bot:
|
|||||||
info_fetching_telegraph_page: "正在获取 telegraph 页面..."
|
info_fetching_telegraph_page: "正在获取 telegraph 页面..."
|
||||||
error_get_telegraph_page_failed: "获取 telegraph 页面失败: {{.Error}}"
|
error_get_telegraph_page_failed: "获取 telegraph 页面失败: {{.Error}}"
|
||||||
error_no_images_in_telegraph_page: "在 telegraph 页面中未找到图片"
|
error_no_images_in_telegraph_page: "在 telegraph 页面中未找到图片"
|
||||||
|
error_build_dir_select_keyboard_failed: "构建目录选择键盘失败: {{.Error}}"
|
||||||
|
error_no_permission: |
|
||||||
|
您不在白名单中, 无法使用此 Bot.
|
||||||
|
您可以部署自己的实例: https://github.com/krau/SaveAny-Bot
|
||||||
save:
|
save:
|
||||||
error_invalid_id_or_username: "无效的ID或用户名: {{.Error}}"
|
error_invalid_id_or_username: "无效的ID或用户名: {{.Error}}"
|
||||||
watch:
|
watch:
|
||||||
@@ -135,6 +139,10 @@ bot:
|
|||||||
queued_empty: "当前没有排队中的任务"
|
queued_empty: "当前没有排队中的任务"
|
||||||
queued_title: "当前排队中的任务:"
|
queued_title: "当前排队中的任务:"
|
||||||
truncated_note: "...\n只显示前 10 个任务, 共 {{.Count}} 个任务"
|
truncated_note: "...\n只显示前 10 个任务, 共 {{.Count}} 个任务"
|
||||||
|
info_added_to_queue_full: "已添加到任务队列\n文件名: {{.Filename}}\n当前排队任务数: {{.QueueLength}}"
|
||||||
|
info_added_to_queue_prefix: "已添加到任务队列\n"
|
||||||
|
info_filename_prefix: "文件名: "
|
||||||
|
info_queue_length_prefix: "\n当前排队任务数: "
|
||||||
rule:
|
rule:
|
||||||
error_get_user_rules_failed: "获取用户规则失败"
|
error_get_user_rules_failed: "获取用户规则失败"
|
||||||
error_update_user_failed: "更新用户失败"
|
error_update_user_failed: "更新用户失败"
|
||||||
@@ -147,6 +155,14 @@ bot:
|
|||||||
error_invalid_rule_id: "无效的规则ID"
|
error_invalid_rule_id: "无效的规则ID"
|
||||||
error_delete_rule_failed: "删除规则失败"
|
error_delete_rule_failed: "删除规则失败"
|
||||||
info_delete_rule_success: "删除规则成功"
|
info_delete_rule_success: "删除规则成功"
|
||||||
|
help_usage: "使用方法: /rule <操作> <参数...>"
|
||||||
|
help_current_mode_enabled: "\n当前已启用规则模式"
|
||||||
|
help_current_mode_disabled: "\n当前已禁用规则模式"
|
||||||
|
help_available_ops: "\n\n可用操作:\n"
|
||||||
|
help_switch_suffix: " - 开关规则模式\n"
|
||||||
|
help_add_suffix: " <类型> <数据> <存储名> <路径> - 添加规则\n"
|
||||||
|
help_del_suffix: " <规则ID> - 删除规则\n"
|
||||||
|
help_existing_rules_prefix: "\n当前已添加的规则:\n"
|
||||||
dir:
|
dir:
|
||||||
error_get_user_dirs_failed: "获取用户文件夹失败"
|
error_get_user_dirs_failed: "获取用户文件夹失败"
|
||||||
error_get_user_failed: "获取用户失败"
|
error_get_user_failed: "获取用户失败"
|
||||||
@@ -156,6 +172,16 @@ bot:
|
|||||||
error_delete_dir_failed: "删除文件夹失败"
|
error_delete_dir_failed: "删除文件夹失败"
|
||||||
info_delete_dir_success: "文件夹删除成功"
|
info_delete_dir_success: "文件夹删除成功"
|
||||||
error_unknown_operation: "未知操作"
|
error_unknown_operation: "未知操作"
|
||||||
|
help_usage: "使用方法: /dir <操作> <参数...>"
|
||||||
|
help_available_ops: "\n\n可用操作:\n"
|
||||||
|
help_add_suffix: " <存储名> <路径> - 添加路径\n"
|
||||||
|
help_del_suffix: " <路径ID> - 删除路径\n"
|
||||||
|
help_add_example_prefix: "\n添加路径示例:\n"
|
||||||
|
help_add_example_cmd: "/dir add local1 path/to/dir"
|
||||||
|
help_del_example_prefix: "\n\n删除路径示例:\n"
|
||||||
|
help_del_example_cmd: "/dir del 3"
|
||||||
|
help_existing_dirs_prefix: "\n\n当前已添加的路径:\n"
|
||||||
|
button_default: "默认"
|
||||||
parser:
|
parser:
|
||||||
help_text: |
|
help_text: |
|
||||||
用法:
|
用法:
|
||||||
@@ -176,6 +202,12 @@ bot:
|
|||||||
error_parse_text_failed: "Failed to parse text: {{.Error}}"
|
error_parse_text_failed: "Failed to parse text: {{.Error}}"
|
||||||
error_build_storage_select_keyboard_failed: "Failed to build storage selection keyboard: {{.Error}}"
|
error_build_storage_select_keyboard_failed: "Failed to build storage selection keyboard: {{.Error}}"
|
||||||
error_build_parsed_text_entity_failed: "Failed to build parsed text entity: {{.Error}}"
|
error_build_parsed_text_entity_failed: "Failed to build parsed text entity: {{.Error}}"
|
||||||
|
info_link_prefix: "\n链接: "
|
||||||
|
info_author_prefix: "\n作者: "
|
||||||
|
info_description_prefix: "\n描述: "
|
||||||
|
info_file_count_prefix: "\n文件数量: "
|
||||||
|
info_total_size_prefix: "\n预计总大小: "
|
||||||
|
info_prompt_select_storage: "\n请选择存储位置"
|
||||||
telegraph:
|
telegraph:
|
||||||
error_build_storage_select_keyboard_failed: "构建存储选择键盘失败: {{.Error}}"
|
error_build_storage_select_keyboard_failed: "构建存储选择键盘失败: {{.Error}}"
|
||||||
info_title_prefix: "标题: "
|
info_title_prefix: "标题: "
|
||||||
@@ -199,7 +231,7 @@ bot:
|
|||||||
文件大小: {{.SizeMB}} MB
|
文件大小: {{.SizeMB}} MB
|
||||||
下载链接: {{.URL}}
|
下载链接: {{.URL}}
|
||||||
发布时间: {{.PublishedAt}}
|
发布时间: {{.PublishedAt}}
|
||||||
|
|
||||||
升级将重启 Bot , 是否升级?
|
升级将重启 Bot , 是否升级?
|
||||||
info_upgrading_with_version: "正在升级中, 当前版本: {{.Current}}"
|
info_upgrading_with_version: "正在升级中, 当前版本: {{.Current}}"
|
||||||
error_upgrade_failed: "升级失败: {{.Error}}"
|
error_upgrade_failed: "升级失败: {{.Error}}"
|
||||||
@@ -226,6 +258,11 @@ bot:
|
|||||||
模板仅在文件名策略设置为 '自定义模板' 时生效, 且模板解析错误时会回退到默认文件名
|
模板仅在文件名策略设置为 '自定义模板' 时生效, 且模板解析错误时会回退到默认文件名
|
||||||
error_invalid_template: "无效的模板, 请检查语法\n{{.Error}}"
|
error_invalid_template: "无效的模板, 请检查语法\n{{.Error}}"
|
||||||
info_template_updated: "已更新文件名模板"
|
info_template_updated: "已更新文件名模板"
|
||||||
|
info_current_template_prefix: "当前模板: {{.Template}}"
|
||||||
|
dl:
|
||||||
|
usage: "用法: /dl <链接1> <链接2> ..."
|
||||||
|
error_no_valid_links: "没有有效的链接可供下载"
|
||||||
|
info_files_select_storage: "共 {{.Count}} 个文件, 请选择存储位置"
|
||||||
cancel:
|
cancel:
|
||||||
usage: "用法: /cancel <task_id>"
|
usage: "用法: /cancel <task_id>"
|
||||||
error_cancel_failed: "取消任务失败: {{.Error}}"
|
error_cancel_failed: "取消任务失败: {{.Error}}"
|
||||||
@@ -235,3 +272,6 @@ bot:
|
|||||||
info_saving_files: "正在保存文件..."
|
info_saving_files: "正在保存文件..."
|
||||||
error_build_storage_select_keyboard_failed: "构建存储选择键盘失败: {{.Error}}"
|
error_build_storage_select_keyboard_failed: "构建存储选择键盘失败: {{.Error}}"
|
||||||
info_group_found_files_select_storage: "共 {{.Count}} 个文件, 请选择存储位置"
|
info_group_found_files_select_storage: "共 {{.Count}} 个文件, 请选择存储位置"
|
||||||
|
storage:
|
||||||
|
info_filename_prefix: "文件名: "
|
||||||
|
info_prompt_select_storage: "\n请选择存储位置"
|
||||||
|
|||||||
Reference in New Issue
Block a user