233 lines
7.3 KiB
Go
233 lines
7.3 KiB
Go
package bot
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
|
|
"github.com/celestix/gotgproto/dispatcher"
|
|
"github.com/celestix/gotgproto/ext"
|
|
"github.com/gotd/td/tg"
|
|
"github.com/krau/SaveAny-Bot/dao"
|
|
"github.com/krau/SaveAny-Bot/logger"
|
|
"github.com/krau/SaveAny-Bot/storage"
|
|
"github.com/krau/SaveAny-Bot/types"
|
|
)
|
|
|
|
func manageStorageEntry(ctx *ext.Context, update *ext.Update) error {
|
|
user, err := dao.GetUserByChatID(update.EffectiveUser().GetID())
|
|
if err != nil {
|
|
logger.L.Errorf("Failed to get user active storages: %s", err)
|
|
ctx.Reply(update, ext.ReplyTextString("获取用户存储失败"), nil)
|
|
return dispatcher.EndGroups
|
|
}
|
|
|
|
state, ok := userConversationState[user.ChatID]
|
|
if !ok {
|
|
state = &ConversationState{}
|
|
userConversationState[user.ChatID] = state
|
|
}
|
|
state.Reset()
|
|
state.InConversation = true
|
|
state.SetConversationType(ConversationTypeManageStorage)
|
|
state.SetData("status", "entry")
|
|
|
|
storagesMsg := "已添加的存储:"
|
|
if len(user.Storages) == 0 {
|
|
storagesMsg += " 无"
|
|
} else {
|
|
for i, storage := range user.Storages {
|
|
storagesMsg += fmt.Sprintf("\n%d. %s", i+1, storage.Name)
|
|
}
|
|
}
|
|
storagesMsg += "\n\n请选择操作:"
|
|
_, err = ctx.Reply(update, ext.ReplyTextString(storagesMsg), &ext.ReplyOpts{
|
|
Markup: &manageStorageKeyboardMarkup,
|
|
})
|
|
if err != nil {
|
|
logger.L.Errorf("Failed to send manage storage message: %s", err)
|
|
return dispatcher.EndGroups
|
|
}
|
|
|
|
return dispatcher.EndGroups
|
|
}
|
|
|
|
func handleManageStorageConversation(ctx *ext.Context, update *ext.Update, state *ConversationState) error {
|
|
status := state.GetData("status").(string)
|
|
switch status {
|
|
case "entry":
|
|
return manageStorageMenu(ctx, update, state)
|
|
case "add_select_type":
|
|
return manageStorageAddSelectType(ctx, update, state)
|
|
case "selected_add_type":
|
|
return manageStorageAddSelectedType(ctx, update, state)
|
|
default:
|
|
logger.L.Errorf("Unknown manage storage status: %s", status)
|
|
}
|
|
return dispatcher.EndGroups
|
|
}
|
|
|
|
func manageStorageMenu(ctx *ext.Context, update *ext.Update, state *ConversationState) error {
|
|
text := update.EffectiveMessage.Text
|
|
switch text {
|
|
case manageStorageButtonAdd:
|
|
return manageStorageAdd(ctx, update, state)
|
|
case manageStorageButtonDelete:
|
|
return manageStorageDelete(ctx, update)
|
|
case manageStorageButtonEdit:
|
|
return manageStorageEdit(ctx, update)
|
|
case manageStorageButtonSetDefault:
|
|
return manageStorageSetDefault(ctx, update)
|
|
default:
|
|
logger.L.Errorf("Unknown manage storage button: %s", text)
|
|
ctx.Reply(update, ext.ReplyTextString("未知操作"), nil)
|
|
return dispatcher.EndGroups
|
|
}
|
|
}
|
|
|
|
func manageStorageAdd(ctx *ext.Context, update *ext.Update, state *ConversationState) error {
|
|
rows := make([]tg.KeyboardButtonRow, 0)
|
|
buttons := make([]tg.KeyboardButtonClass, 0)
|
|
for i, storageType := range types.StorageTypes {
|
|
buttons = append(buttons, &tg.KeyboardButton{
|
|
Text: types.StorageTypeDisplay[storageType],
|
|
})
|
|
if (i+1)%3 == 0 || i == len(types.StorageTypes)-1 {
|
|
rows = append(rows, tg.KeyboardButtonRow{
|
|
Buttons: buttons,
|
|
})
|
|
buttons = make([]tg.KeyboardButtonClass, 0)
|
|
}
|
|
}
|
|
manageStorageAddKeyboardMarkup := tg.ReplyKeyboardMarkup{
|
|
Selective: true,
|
|
Resize: true,
|
|
Rows: rows,
|
|
}
|
|
|
|
state.SetData("status", "add_select_type")
|
|
|
|
ctx.Reply(update, ext.ReplyTextString("请选择要添加的存储类型"), &ext.ReplyOpts{
|
|
Markup: &manageStorageAddKeyboardMarkup,
|
|
})
|
|
return dispatcher.ContinueGroups
|
|
}
|
|
|
|
func manageStorageAddSelectType(ctx *ext.Context, update *ext.Update, state *ConversationState) error {
|
|
text := update.EffectiveMessage.Text
|
|
var storageType types.StorageType
|
|
for t, display := range types.StorageTypeDisplay {
|
|
if display == text {
|
|
storageType = t
|
|
break
|
|
}
|
|
}
|
|
if storageType == "" {
|
|
ctx.Reply(update, ext.ReplyTextString("未知的存储类型"), nil)
|
|
return dispatcher.EndGroups
|
|
}
|
|
state.SetData("status", "selected_add_type")
|
|
state.SetData("storage_type", storageType)
|
|
return manageStorageAddSelectedType(ctx, update, state)
|
|
}
|
|
|
|
func manageStorageAddSelectedType(ctx *ext.Context, update *ext.Update, state *ConversationState) error {
|
|
selectedType := state.GetData("storage_type").(types.StorageType)
|
|
configItems := storage.GetStorageConfigurableItems(selectedType)
|
|
configIndexData := state.GetData("configindex")
|
|
configIndex := 0
|
|
if configIndexData == nil {
|
|
state.SetData("configindex", configIndex)
|
|
} else {
|
|
configIndex = configIndexData.(int)
|
|
if update.EffectiveMessage.Text != "" {
|
|
logger.L.Debugf("config %s: %s", configItems[configIndex-1], update.EffectiveMessage.Text)
|
|
state.SetData(configItems[configIndex-1], update.EffectiveMessage.Text)
|
|
}
|
|
}
|
|
if configIndex >= len(configItems) {
|
|
// TODO: save storage
|
|
state.SetData("status", "add_complete")
|
|
logger.L.Infof("Save storage")
|
|
return manageStorageSave(ctx, update, state)
|
|
}
|
|
|
|
ctx.Reply(update, ext.ReplyTextString(fmt.Sprintf("正在配置 %s 存储...\n请提供 %s", types.StorageTypeDisplay[selectedType], configItems[configIndex])), &ext.ReplyOpts{
|
|
Markup: &tg.ReplyKeyboardForceReply{
|
|
Selective: true,
|
|
SingleUse: true,
|
|
},
|
|
})
|
|
state.SetData("configindex", configIndex+1)
|
|
return dispatcher.EndGroups
|
|
}
|
|
|
|
func manageStorageSave(ctx *ext.Context, update *ext.Update, state *ConversationState) error {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
logger.L.Errorf("Failed to save storage: %s", r)
|
|
ctx.Reply(update, ext.ReplyTextString("存储配置失败"), nil)
|
|
}
|
|
state.Reset()
|
|
}()
|
|
storageType := state.GetData("storage_type").(types.StorageType)
|
|
config := make(map[string]string)
|
|
configItems := storage.GetStorageConfigurableItems(storageType)
|
|
for _, item := range configItems {
|
|
config[item] = state.GetData(item).(string)
|
|
}
|
|
configJSON, err := json.Marshal(config)
|
|
if err != nil {
|
|
logger.L.Errorf("Failed to marshal storage config: %s", err)
|
|
ctx.Reply(update, ext.ReplyTextString("存储配置失败"), nil)
|
|
return dispatcher.EndGroups
|
|
}
|
|
user, err := dao.GetUserByChatID(update.EffectiveUser().GetID())
|
|
if err != nil {
|
|
logger.L.Errorf("Failed to get user: %s", err)
|
|
ctx.Reply(update, ext.ReplyTextString("获取用户失败"), nil)
|
|
return dispatcher.EndGroups
|
|
}
|
|
storageModel := types.StorageModel{
|
|
Type: string(storageType),
|
|
Active: true,
|
|
Config: configJSON,
|
|
}
|
|
hash := storageModel.GenHash()
|
|
storageModel.Hash = hash
|
|
if storagedb, err := dao.GetStorageByHash(hash); err == nil {
|
|
logger.L.Debugf("Storage already exists")
|
|
user.Storages = append(user.Storages, storagedb)
|
|
} else {
|
|
if id, err := dao.CreateStorage(&storageModel); err != nil {
|
|
logger.L.Errorf("Failed to create storage: %s", err)
|
|
ctx.Reply(update, ext.ReplyTextString("存储创建失败"), nil)
|
|
return dispatcher.EndGroups
|
|
} else {
|
|
storagedb := &types.StorageModel{}
|
|
storagedb.ID = id
|
|
user.Storages = append(user.Storages, storagedb)
|
|
}
|
|
}
|
|
if err := dao.UpdateUser(user); err != nil {
|
|
logger.L.Errorf("Failed to update user with storages: %s", err)
|
|
ctx.Reply(update, ext.ReplyTextString("用户更新失败"), nil)
|
|
return dispatcher.EndGroups
|
|
}
|
|
ctx.Reply(update, ext.ReplyTextString("存储已添加"), &ext.ReplyOpts{
|
|
Markup: &tg.ReplyKeyboardHide{},
|
|
})
|
|
return dispatcher.EndGroups
|
|
}
|
|
|
|
func manageStorageDelete(ctx *ext.Context, update *ext.Update) error {
|
|
return dispatcher.ContinueGroups
|
|
}
|
|
|
|
func manageStorageEdit(ctx *ext.Context, update *ext.Update) error {
|
|
return dispatcher.ContinueGroups
|
|
}
|
|
|
|
func manageStorageSetDefault(ctx *ext.Context, update *ext.Update) error {
|
|
return dispatcher.ContinueGroups
|
|
}
|