package service import ( "regexp" "strings" "github.com/ShukeBta/MediaStationGo/internal/model" ) func subscriptionCandidateScore(sub *model.Subscription, item SearchResult) int { title := strings.ToLower(subscriptionSearchResultText(item)) score := item.Seeders if sub == nil || !sub.WashEnabled { if item.Free { score += 25 } return score } resolutionScore := detectResolutionScore(title) qualityScore := detectQualityScore(title) effectScore := detectEffectScore(title) priority := "balanced" if sub != nil && strings.TrimSpace(sub.WashPriority) != "" { priority = strings.ToLower(strings.TrimSpace(sub.WashPriority)) } switch priority { case "resolution": score += resolutionScore*1000 + qualityScore*100 + effectScore*50 case "quality": score += qualityScore*1000 + resolutionScore*200 + effectScore*50 case "effects": score += effectScore*1000 + resolutionScore*200 + qualityScore*100 case "seeders": score += qualityScore*3 + resolutionScore*2 + effectScore default: score += resolutionScore*500 + qualityScore*300 + effectScore*150 } if item.Free { score += 25 } return score } func containsAnyEffect(titleFold, csv string) bool { for _, token := range strings.FieldsFunc(strings.ToLower(csv), func(r rune) bool { return r == ',' || r == '/' || r == '|' || r == ';' || r == ',' }) { token = strings.TrimSpace(token) if token == "" { continue } switch token { case "dolby-vision", "dolby vision", "dv": if strings.Contains(titleFold, "dolby vision") || strings.Contains(titleFold, "dovi") || regexp.MustCompile(`\bdv\b`).MatchString(titleFold) { return true } default: if strings.Contains(titleFold, token) { return true } } } return false } func titleMatchesResolution(titleFold, resolution string) bool { switch strings.ToLower(strings.TrimSpace(resolution)) { case "2160p", "4k", "uhd": return strings.Contains(titleFold, "2160p") || strings.Contains(titleFold, "4k") || strings.Contains(titleFold, "uhd") case "1080p": return strings.Contains(titleFold, "1080p") || strings.Contains(titleFold, "fhd") case "720p": return strings.Contains(titleFold, "720p") default: return strings.Contains(titleFold, strings.ToLower(strings.TrimSpace(resolution))) } } func titleMatchesQuality(titleFold, quality string) bool { switch strings.ToLower(strings.TrimSpace(quality)) { case "webdl", "web-dl": return strings.Contains(titleFold, "web-dl") || strings.Contains(titleFold, "webdl") case "bluray", "blu-ray": return strings.Contains(titleFold, "bluray") || strings.Contains(titleFold, "blu-ray") || strings.Contains(titleFold, "bdrip") case "remux": return strings.Contains(titleFold, "remux") case "hdtv": return strings.Contains(titleFold, "hdtv") default: return strings.Contains(titleFold, strings.ToLower(strings.TrimSpace(quality))) } } func detectResolutionScore(titleFold string) int { switch { case titleMatchesResolution(titleFold, "2160p"): return 4 case titleMatchesResolution(titleFold, "1080p"): return 3 case titleMatchesResolution(titleFold, "720p"): return 2 default: return 1 } } func detectQualityScore(titleFold string) int { switch { case titleMatchesQuality(titleFold, "remux"): return 5 case titleMatchesQuality(titleFold, "bluray"): return 4 case titleMatchesQuality(titleFold, "web-dl"): return 3 case titleMatchesQuality(titleFold, "hdtv"): return 2 default: return 1 } } func detectEffectScore(titleFold string) int { score := 0 if containsAnyEffect(titleFold, "dolby-vision") { score += 4 } if strings.Contains(titleFold, "hdr10+") { score += 3 } else if strings.Contains(titleFold, "hdr") { score += 2 } if strings.Contains(titleFold, "atmos") { score += 2 } return score }