mirror of
https://github.com/krau/SaveAny-Bot.git
synced 2026-07-12 16:02:05 +08:00
Fix album (NEW-FOR-ALBUM) rule handling and proper filename logic
Co-authored-by: krau <71133316+krau@users.noreply.github.com>
This commit is contained in:
167
api/handlers.go
167
api/handlers.go
@@ -10,6 +10,7 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"path"
|
"path"
|
||||||
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
"time"
|
"time"
|
||||||
@@ -225,7 +226,7 @@ func handleCreateTask(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create tasks for all files
|
// Create tasks for all files with proper album handling
|
||||||
taskIDs := make([]string, 0, len(files))
|
taskIDs := make([]string, 0, len(files))
|
||||||
baseDirPath := req.DirPath
|
baseDirPath := req.DirPath
|
||||||
if baseDirPath == "" {
|
if baseDirPath == "" {
|
||||||
@@ -238,18 +239,17 @@ func handleCreateTask(w http.ResponseWriter, r *http.Request) {
|
|||||||
// Apply storage rules if enabled for the user
|
// Apply storage rules if enabled for the user
|
||||||
useRule := userDB.ApplyRule && userDB.Rules != nil
|
useRule := userDB.ApplyRule && userDB.Rules != nil
|
||||||
|
|
||||||
for _, tgFile := range files {
|
// Helper to apply rules to a file
|
||||||
// Determine storage and directory path for this specific file
|
applyRule := func(file tfile.TGFileMessage) (storage.Storage, ruleutil.MatchedDirPath) {
|
||||||
fileStor := stor
|
fileStor := stor
|
||||||
dirPath := baseDirPath
|
dirPath := ruleutil.MatchedDirPath(baseDirPath)
|
||||||
|
|
||||||
// Apply rules if enabled
|
|
||||||
if useRule {
|
if useRule {
|
||||||
matched, matchedStorName, matchedDirPath := ruleutil.ApplyRule(injectCtx, userDB.Rules, ruleutil.NewInput(tgFile))
|
matched, matchedStorName, matchedDirPath := ruleutil.ApplyRule(injectCtx, userDB.Rules, ruleutil.NewInput(file))
|
||||||
if matched {
|
if matched {
|
||||||
// Rule matched, apply overrides
|
// Rule matched, apply overrides
|
||||||
if matchedDirPath != "" && matchedDirPath != "{{album}}" {
|
if matchedDirPath != "" {
|
||||||
dirPath = matchedDirPath.String()
|
dirPath = matchedDirPath
|
||||||
}
|
}
|
||||||
if matchedStorName.Usable() {
|
if matchedStorName.Usable() {
|
||||||
var err error
|
var err error
|
||||||
@@ -262,31 +262,144 @@ func handleCreateTask(w http.ResponseWriter, r *http.Request) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return fileStor, dirPath
|
||||||
|
}
|
||||||
|
|
||||||
storagePath := fileStor.JoinStoragePath(path.Join(dirPath, tgFile.Name()))
|
// Separate files into regular and album files
|
||||||
taskID := xid.New().String()
|
type albumFile struct {
|
||||||
|
file tfile.TGFileMessage
|
||||||
|
storage storage.Storage
|
||||||
|
dirPath ruleutil.MatchedDirPath
|
||||||
|
}
|
||||||
|
albumFiles := make(map[int64][]albumFile)
|
||||||
|
|
||||||
|
for _, tgFile := range files {
|
||||||
|
fileStor, dirPath := applyRule(tgFile)
|
||||||
|
|
||||||
|
// Check if this needs album handling (NEW-FOR-ALBUM rule)
|
||||||
|
if dirPath.NeedNewForAlbum() {
|
||||||
|
groupId, isGroup := tgFile.Message().GetGroupedID()
|
||||||
|
if !isGroup || groupId == 0 {
|
||||||
|
logger.Warnf("File %s has NEW-FOR-ALBUM rule but is not in a group, treating as regular file", tgFile.Name())
|
||||||
|
// Treat as regular file with base dir path
|
||||||
|
storagePath := fileStor.JoinStoragePath(path.Join(baseDirPath, tgFile.Name()))
|
||||||
|
taskID := xid.New().String()
|
||||||
|
|
||||||
task, err := tftask.NewTGFileTask(taskID, injectCtx, tgFile, fileStor, storagePath, &apiProgressTracker{
|
task, err := tftask.NewTGFileTask(taskID, injectCtx, tgFile, fileStor, storagePath, &apiProgressTracker{
|
||||||
taskID: taskID,
|
taskID: taskID,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger.Errorf("Failed to create task: %v", err)
|
logger.Errorf("Failed to create task: %v", err)
|
||||||
respondError(w, "failed to create task", http.StatusInternalServerError)
|
respondError(w, "failed to create task", http.StatusInternalServerError)
|
||||||
return
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
trackTask(taskID, task.Title(), "queued")
|
||||||
|
if err := core.AddTask(injectCtx, task); err != nil {
|
||||||
|
logger.Errorf("Failed to add task: %v", err)
|
||||||
|
updateTaskStatus(taskID, "failed", err.Error())
|
||||||
|
respondError(w, "failed to add task to queue", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
taskIDs = append(taskIDs, taskID)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
// Group by album ID
|
||||||
|
if _, ok := albumFiles[groupId]; !ok {
|
||||||
|
albumFiles[groupId] = make([]albumFile, 0)
|
||||||
|
}
|
||||||
|
albumFiles[groupId] = append(albumFiles[groupId], albumFile{
|
||||||
|
file: tgFile,
|
||||||
|
storage: fileStor,
|
||||||
|
dirPath: dirPath,
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
// Regular file - create task immediately
|
||||||
|
storagePath := fileStor.JoinStoragePath(path.Join(dirPath.String(), tgFile.Name()))
|
||||||
|
taskID := xid.New().String()
|
||||||
|
|
||||||
|
task, err := tftask.NewTGFileTask(taskID, injectCtx, tgFile, fileStor, storagePath, &apiProgressTracker{
|
||||||
|
taskID: taskID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Failed to create task: %v", err)
|
||||||
|
respondError(w, "failed to create task", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
trackTask(taskID, task.Title(), "queued")
|
||||||
|
if err := core.AddTask(injectCtx, task); err != nil {
|
||||||
|
logger.Errorf("Failed to add task: %v", err)
|
||||||
|
updateTaskStatus(taskID, "failed", err.Error())
|
||||||
|
respondError(w, "failed to add task to queue", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
taskIDs = append(taskIDs, taskID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle album files - group them into subdirectories
|
||||||
|
for _, afiles := range albumFiles {
|
||||||
|
if len(afiles) <= 1 {
|
||||||
|
// Single file in album, treat as regular
|
||||||
|
for _, af := range afiles {
|
||||||
|
storagePath := af.storage.JoinStoragePath(path.Join(baseDirPath, af.file.Name()))
|
||||||
|
taskID := xid.New().String()
|
||||||
|
|
||||||
|
task, err := tftask.NewTGFileTask(taskID, injectCtx, af.file, af.storage, storagePath, &apiProgressTracker{
|
||||||
|
taskID: taskID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Failed to create task: %v", err)
|
||||||
|
respondError(w, "failed to create task", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
trackTask(taskID, task.Title(), "queued")
|
||||||
|
if err := core.AddTask(injectCtx, task); err != nil {
|
||||||
|
logger.Errorf("Failed to add task: %v", err)
|
||||||
|
updateTaskStatus(taskID, "failed", err.Error())
|
||||||
|
respondError(w, "failed to add task to queue", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
taskIDs = append(taskIDs, taskID)
|
||||||
|
}
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
// Track task status
|
// Multiple files in album - create subdirectory named after first file
|
||||||
trackTask(taskID, task.Title(), "queued")
|
// Remove extension from first file's name to use as directory name
|
||||||
|
albumDir := strings.TrimSuffix(path.Base(afiles[0].file.Name()), path.Ext(afiles[0].file.Name()))
|
||||||
|
albumStor := afiles[0].storage
|
||||||
|
|
||||||
// Add task to queue
|
for _, af := range afiles {
|
||||||
if err := core.AddTask(injectCtx, task); err != nil {
|
// All files go into the album subdirectory
|
||||||
logger.Errorf("Failed to add task: %v", err)
|
storagePath := albumStor.JoinStoragePath(path.Join(baseDirPath, albumDir, af.file.Name()))
|
||||||
updateTaskStatus(taskID, "failed", err.Error())
|
taskID := xid.New().String()
|
||||||
respondError(w, "failed to add task to queue", http.StatusInternalServerError)
|
|
||||||
return
|
task, err := tftask.NewTGFileTask(taskID, injectCtx, af.file, albumStor, storagePath, &apiProgressTracker{
|
||||||
|
taskID: taskID,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
logger.Errorf("Failed to create task for album file: %v", err)
|
||||||
|
respondError(w, "failed to create task", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
trackTask(taskID, task.Title(), "queued")
|
||||||
|
if err := core.AddTask(injectCtx, task); err != nil {
|
||||||
|
logger.Errorf("Failed to add task: %v", err)
|
||||||
|
updateTaskStatus(taskID, "failed", err.Error())
|
||||||
|
respondError(w, "failed to add task to queue", http.StatusInternalServerError)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
taskIDs = append(taskIDs, taskID)
|
||||||
}
|
}
|
||||||
|
|
||||||
taskIDs = append(taskIDs, taskID)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send success response
|
// Send success response
|
||||||
|
|||||||
Reference in New Issue
Block a user