104 lines
2.9 KiB
Go
104 lines
2.9 KiB
Go
package core
|
|
|
|
import (
|
|
"fmt"
|
|
"path"
|
|
"regexp"
|
|
|
|
"github.com/celestix/gotgproto/ext"
|
|
"github.com/krau/SaveAny-Bot/bot"
|
|
"github.com/krau/SaveAny-Bot/common"
|
|
"github.com/krau/SaveAny-Bot/dao"
|
|
"github.com/krau/SaveAny-Bot/storage"
|
|
"github.com/krau/SaveAny-Bot/types"
|
|
)
|
|
|
|
func getStorageAndPathForTask(task *types.Task) (storage.Storage, string, error) {
|
|
user, err := dao.GetUserByChatID(task.UserID)
|
|
if err != nil {
|
|
return nil, "", fmt.Errorf("failed to get user by chat ID: %w", err)
|
|
}
|
|
if task.StoragePath == "" {
|
|
task.StoragePath = task.FileName()
|
|
}
|
|
taskStorage, err := storage.GetStorageByUserIDAndName(task.UserID, task.StorageName)
|
|
if err != nil {
|
|
return nil, "", err
|
|
}
|
|
storagePath := taskStorage.JoinStoragePath(*task)
|
|
if !user.ApplyRule || user.Rules == nil {
|
|
return taskStorage, storagePath, nil
|
|
}
|
|
var ruleTaskStorage storage.Storage
|
|
var ruleStoragePath string
|
|
for _, rule := range user.Rules {
|
|
matchStorage, matchStoragePath := applyRule(&rule, *task)
|
|
if matchStorage != nil && matchStoragePath != "" {
|
|
ruleTaskStorage = matchStorage
|
|
ruleStoragePath = matchStoragePath
|
|
}
|
|
}
|
|
if ruleStoragePath == "" || ruleTaskStorage == nil {
|
|
return taskStorage, storagePath, nil
|
|
}
|
|
common.Log.Debugf("Rule matched: %s, %s", ruleTaskStorage.Name(), ruleStoragePath)
|
|
return ruleTaskStorage, ruleStoragePath, nil
|
|
}
|
|
|
|
func applyRule(rule *dao.Rule, task types.Task) (storage.Storage, string) {
|
|
var DirPath, StorageName string
|
|
switch rule.Type {
|
|
case string(types.RuleTypeFileNameRegex):
|
|
ruleRegex, err := regexp.Compile(rule.Data)
|
|
if err != nil {
|
|
common.Log.Errorf("failed to compile regex: %s", err)
|
|
return nil, ""
|
|
}
|
|
if !ruleRegex.MatchString(task.FileName()) {
|
|
return nil, ""
|
|
}
|
|
DirPath = rule.DirPath
|
|
StorageName = rule.StorageName
|
|
case string(types.RuleTypeMessageRegex):
|
|
ruleRegex, err := regexp.Compile(rule.Data)
|
|
if err != nil {
|
|
common.Log.Errorf("failed to compile regex: %s", err)
|
|
return nil, ""
|
|
}
|
|
ctx, ok := task.Ctx.(*ext.Context)
|
|
if !ok {
|
|
common.Log.Fatalf("context is not *ext.Context: %T", task.Ctx)
|
|
return nil, ""
|
|
}
|
|
msg, err := bot.GetTGMessage(ctx, task.FileChatID, task.FileMessageID)
|
|
if err != nil {
|
|
common.Log.Errorf("failed to get message: %s", err)
|
|
return nil, ""
|
|
}
|
|
if msg == nil {
|
|
return nil, ""
|
|
}
|
|
if !ruleRegex.MatchString(msg.GetMessage()) {
|
|
return nil, ""
|
|
}
|
|
DirPath = rule.DirPath
|
|
StorageName = rule.StorageName
|
|
default:
|
|
common.Log.Errorf("unknown rule type: %s", rule.Type)
|
|
return nil, ""
|
|
}
|
|
taskStorageName := func() string {
|
|
if StorageName == "" || StorageName == "CHOSEN" {
|
|
return task.StorageName
|
|
}
|
|
return StorageName
|
|
}()
|
|
taskStorage, err := storage.GetStorageByUserIDAndName(task.UserID, taskStorageName)
|
|
if err != nil {
|
|
common.Log.Errorf("failed to get storage: %s", err)
|
|
return nil, ""
|
|
}
|
|
task.StoragePath = path.Join(DirPath, task.StoragePath)
|
|
return taskStorage, taskStorage.JoinStoragePath(task)
|
|
}
|