fix: add smart download classification

This commit is contained in:
ShukeBta
2026-06-07 21:34:21 +08:00
parent 681fc33dd5
commit 8c8d472524
23 changed files with 388 additions and 40 deletions
+39 -5
View File
@@ -74,6 +74,9 @@ type DownloadTaskMeta struct {
PosterURL string
BackdropURL string
Overview string
MediaType string
MediaCategory string
SourceCategory string
AllowExistingLibrary bool
}
@@ -205,14 +208,18 @@ func (d *DownloadService) AddDownloadWithMeta(ctx context.Context, userID, urlSt
if urlStr == "" {
return nil, errors.New("empty url")
}
if savePath == "" {
savePath, _ = d.repo.Setting.Get(ctx, "qbittorrent.savepath")
}
title := strings.TrimSpace(meta.Title)
if title == "" {
title = publicDownloadTitle(urlStr)
meta.Title = title
}
autoClassify := downloadSmartClassifyEnabled(ctx, d.repo, d.organizer)
savePath, resolvedCategory := d.resolveDownloadSavePath(ctx, savePath, meta, autoClassify)
if !autoClassify {
meta.MediaCategory = ""
} else if strings.TrimSpace(meta.MediaCategory) == "" {
meta.MediaCategory = resolvedCategory
}
if !meta.AllowExistingLibrary && d.localMediaAlreadyExists(ctx, title) {
return nil, ErrMediaAlreadyInLibrary
}
@@ -231,9 +238,10 @@ func (d *DownloadService) AddDownloadWithMeta(ctx context.Context, userID, urlSt
return task, ErrDownloadAlreadyExists
}
var siteFetchErr error
qbitCategory := strings.TrimSpace(meta.MediaCategory)
if d.site != nil {
if data, name, err := d.site.FetchTorrentFile(ctx, urlStr); err == nil {
if err := d.qb.AddTorrentFile(ctx, data, name, savePath); err != nil {
if err := d.qb.AddTorrentFileWithCategory(ctx, data, name, savePath, qbitCategory); err != nil {
return nil, err
}
if strings.TrimSpace(meta.Title) == "" {
@@ -244,7 +252,7 @@ func (d *DownloadService) AddDownloadWithMeta(ctx context.Context, userID, urlSt
siteFetchErr = err
}
}
if err := d.qb.AddTorrent(ctx, urlStr, savePath); err != nil {
if err := d.qb.AddTorrentWithCategory(ctx, urlStr, savePath, qbitCategory); err != nil {
if siteFetchErr != nil && !strings.Contains(siteFetchErr.Error(), "no matching PT site") {
return nil, errors.Join(err, siteFetchErr)
}
@@ -253,6 +261,32 @@ func (d *DownloadService) AddDownloadWithMeta(ctx context.Context, userID, urlSt
return d.createTask(ctx, userID, urlStr, savePath, meta)
}
func (d *DownloadService) resolveDownloadSavePath(ctx context.Context, explicitSavePath string, meta DownloadTaskMeta, autoClassify bool) (string, string) {
if strings.TrimSpace(explicitSavePath) != "" {
if !autoClassify {
return explicitSavePath, ""
}
return explicitSavePath, strings.TrimSpace(meta.MediaCategory)
}
base := downloadDefaultSaveRoot(ctx, d.repo)
if strings.TrimSpace(base) == "" {
return "", strings.TrimSpace(meta.MediaCategory)
}
mediaType := normalizeMediaType(meta.MediaType, meta.Title, meta.SourceCategory)
category := strings.TrimSpace(meta.MediaCategory)
if category == "" {
category = classifyMediaCategory(mediaClassifyInput{
MediaType: mediaType,
Title: meta.Title,
Category: meta.SourceCategory,
}, downloadCategoryMap(d.organizer))
}
if !autoClassify || category == "" {
return base, ""
}
return categoryRoot(base, sanitizeFilename(category)), category
}
func (d *DownloadService) localMediaAlreadyExists(ctx context.Context, title string) bool {
if d == nil || d.repo == nil || d.repo.DB == nil {
return false