mirror of
https://github.com/truewhile/MeBox.git
synced 2026-10-10 15:26:38 +08:00
refactor: split subscription planner modules
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"regexp"
|
||||
"strings"
|
||||
|
||||
"github.com/ShukeBta/MediaStationGo/internal/model"
|
||||
)
|
||||
|
||||
func collectSiteSearchCandidates(results []SearchResult, sub *model.Subscription, seenSet map[string]struct{}, allowQueryMismatch bool, stats *siteSearchSelectionStats) []siteSearchCandidate {
|
||||
candidates := make([]siteSearchCandidate, 0, len(results))
|
||||
for _, item := range results {
|
||||
matchText := subscriptionSearchResultText(item)
|
||||
if !subscriptionTitleMatchesQuery(sub, matchText) {
|
||||
if allowQueryMismatch {
|
||||
stats.RelaxedQueryMatch++
|
||||
} else {
|
||||
stats.QueryMismatch++
|
||||
stats.QueryMismatchExamples = appendLimitedStrings(stats.QueryMismatchExamples, matchText, 5)
|
||||
continue
|
||||
}
|
||||
}
|
||||
if !matchesSubscriptionRules(sub, matchText) {
|
||||
stats.RuleMismatch++
|
||||
continue
|
||||
}
|
||||
download := strings.TrimSpace(item.DownloadURL)
|
||||
if download == "" {
|
||||
download = strings.TrimSpace(item.TorrentURL)
|
||||
}
|
||||
if download == "" {
|
||||
stats.MissingDownload++
|
||||
continue
|
||||
}
|
||||
guid := stableSiteSearchGUID(item, download)
|
||||
if _, ok := seenSet[guid]; ok {
|
||||
stats.Seen++
|
||||
continue
|
||||
}
|
||||
season, episode := ParseEpisode(matchText)
|
||||
score := subscriptionCandidateScore(sub, item)
|
||||
stats.Prepared++
|
||||
candidates = append(candidates, siteSearchCandidate{
|
||||
Item: item,
|
||||
Download: download,
|
||||
GUID: guid,
|
||||
Season: season,
|
||||
Episode: episode,
|
||||
Pack: isSeriesPackTitle(item.Title),
|
||||
Score: score,
|
||||
})
|
||||
}
|
||||
return candidates
|
||||
}
|
||||
|
||||
func appendLimitedStrings(values []string, value string, limit int) []string {
|
||||
value = strings.TrimSpace(value)
|
||||
if value == "" || limit <= 0 || len(values) >= limit {
|
||||
return values
|
||||
}
|
||||
return append(values, value)
|
||||
}
|
||||
|
||||
func shouldRelaxSiteSearchQueryMatch(sub *model.Subscription, local LocalAvailability) bool {
|
||||
if sub == nil {
|
||||
return false
|
||||
}
|
||||
mediaType := normalizeMediaType(sub.MediaType, sub.Name+" "+sub.Filter, "")
|
||||
if !isSubscriptionSeriesType(mediaType) {
|
||||
return false
|
||||
}
|
||||
if local.LocalMediaCount == 0 && len(local.ExistingEpisodeKeys) == 0 {
|
||||
return false
|
||||
}
|
||||
return local.TotalEpisodes > 0 || len(local.MissingEpisodes) > 0
|
||||
}
|
||||
|
||||
func subscriptionSearchResultText(item SearchResult) string {
|
||||
return strings.TrimSpace(strings.Join([]string{item.Title, item.Subtitle}, " "))
|
||||
}
|
||||
|
||||
func selectRSSSubscriptionCandidates(items []rssItem, sub *model.Subscription, filter *regexp.Regexp, seenSet map[string]struct{}, local LocalAvailability) []siteSearchCandidate {
|
||||
if seenSet == nil {
|
||||
seenSet = map[string]struct{}{}
|
||||
}
|
||||
candidates := make([]siteSearchCandidate, 0, len(items))
|
||||
for _, item := range items {
|
||||
title := strings.TrimSpace(item.Title)
|
||||
if title == "" {
|
||||
continue
|
||||
}
|
||||
if filter != nil && !filter.MatchString(title) {
|
||||
continue
|
||||
}
|
||||
if !matchesSubscriptionRules(sub, title) {
|
||||
continue
|
||||
}
|
||||
download := strings.TrimSpace(item.Enclosure.URL)
|
||||
if download == "" {
|
||||
download = strings.TrimSpace(item.Link)
|
||||
}
|
||||
if download == "" {
|
||||
continue
|
||||
}
|
||||
guid := stableRSSItemGUID(title, item.GUID, item.Link, item.Enclosure.URL)
|
||||
if _, ok := seenSet[guid]; ok {
|
||||
continue
|
||||
}
|
||||
searchItem := SearchResult{Title: title, DownloadURL: download}
|
||||
season, episode := ParseEpisode(title)
|
||||
candidates = append(candidates, siteSearchCandidate{
|
||||
Item: searchItem,
|
||||
Download: download,
|
||||
GUID: guid,
|
||||
Season: season,
|
||||
Episode: episode,
|
||||
Pack: isSeriesPackTitle(title),
|
||||
Score: subscriptionCandidateScore(sub, searchItem),
|
||||
})
|
||||
}
|
||||
return selectPreparedSubscriptionCandidates(candidates, sub, local)
|
||||
}
|
||||
Reference in New Issue
Block a user