mirror of
https://github.com/krau/SaveAny-Bot.git
synced 2026-06-30 03:31:24 +08:00
feat: automatic file organization based on rules, close #28
This commit is contained in:
@@ -31,15 +31,14 @@ func processPendingTask(task *types.Task) error {
|
||||
task.File.FileName = fmt.Sprintf("%d_%d_%s", task.FileChatID, task.FileMessageID, task.File.Hash())
|
||||
}
|
||||
|
||||
if task.StoragePath == "" {
|
||||
task.StoragePath = task.FileName()
|
||||
}
|
||||
|
||||
taskStorage, err := storage.GetStorageByUserIDAndName(task.UserID, task.StorageName)
|
||||
taskStorage, storagePath, err := getStorageAndPathForTask(task)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
task.StoragePath = taskStorage.JoinStoragePath(*task)
|
||||
if taskStorage == nil {
|
||||
return fmt.Errorf("not found storage: %s", task.StorageName)
|
||||
}
|
||||
task.StoragePath = storagePath
|
||||
|
||||
ctx, ok := task.Ctx.(*ext.Context)
|
||||
if !ok {
|
||||
|
||||
103
core/rule.go
Normal file
103
core/rule.go
Normal file
@@ -0,0 +1,103 @@
|
||||
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)
|
||||
}
|
||||
Reference in New Issue
Block a user