fix media workflows and download organization

This commit is contained in:
ShukeBta
2026-06-26 08:42:16 +08:00
parent 0da96f7e4e
commit 65adca04df
102 changed files with 4063 additions and 437 deletions
@@ -5,6 +5,7 @@ import (
"fmt"
"net/url"
"regexp"
"strconv"
"strings"
"go.uber.org/zap"
@@ -54,7 +55,7 @@ func inferSearchTotalEpisodes(results []SearchResult, sub *model.Subscription) i
maxEpisode := 0
for _, item := range results {
matchText := subscriptionSearchResultText(item)
if !subscriptionTitleMatchesQuery(sub, matchText) {
if !subscriptionSearchResultMatchesQuery(sub, item) {
continue
}
if !matchesSubscriptionRules(sub, matchText) {
@@ -210,6 +211,91 @@ func subscriptionTitleMatchesQuery(sub *model.Subscription, title string) bool {
return len(subscriptionTitleMatchQueries(sub)) == 0
}
func subscriptionSearchResultMatchesQuery(sub *model.Subscription, item SearchResult) bool {
matchText := subscriptionSearchResultText(item)
if subscriptionTitleMatchesQuery(sub, matchText) {
return true
}
if !subscriptionSearchResultYearCompatible(sub, matchText) {
return false
}
return subscriptionKeywordMatchesQuery(sub, item.SearchKeyword)
}
func subscriptionSearchResultYearCompatible(sub *model.Subscription, title string) bool {
expected := subscriptionExpectedYear(sub)
if expected <= 0 {
return true
}
years := titleYears(title)
if len(years) == 0 {
return true
}
for _, year := range years {
if year == expected {
return true
}
}
return false
}
func subscriptionExpectedYear(sub *model.Subscription) int {
if sub == nil {
return 0
}
if sub.Year > 0 {
return sub.Year
}
for _, value := range []string{sub.Filter, sub.Name, sub.FeedURL} {
for _, year := range titleYears(value) {
return year
}
}
return 0
}
func titleYears(value string) []int {
matches := regexp.MustCompile(`\b(19\d{2}|20\d{2})\b`).FindAllString(value, -1)
if len(matches) == 0 {
return nil
}
out := make([]int, 0, len(matches))
seen := map[int]struct{}{}
for _, match := range matches {
year, err := strconv.Atoi(match)
if err != nil {
continue
}
if _, ok := seen[year]; ok {
continue
}
seen[year] = struct{}{}
out = append(out, year)
}
return out
}
func subscriptionKeywordMatchesQuery(sub *model.Subscription, keyword string) bool {
keyword = strings.TrimSpace(keyword)
if keyword == "" {
return false
}
normalizedKeyword := normalizeAvailabilityComparable(keyword)
if normalizedKeyword == "" {
return false
}
for _, query := range subscriptionTitleMatchQueries(sub) {
normalizedQuery := normalizeAvailabilityComparable(query)
if normalizedQuery == "" {
continue
}
if strings.Contains(normalizedKeyword, normalizedQuery) || strings.Contains(normalizedQuery, normalizedKeyword) {
return true
}
}
return len(subscriptionTitleMatchQueries(sub)) == 0
}
func subscriptionTitleMatchQueries(sub *model.Subscription) []string {
if sub == nil {
return nil