mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-28 11:16:37 +08:00
168 lines
4.6 KiB
Go
168 lines
4.6 KiB
Go
package service
|
||
|
||
import (
|
||
"regexp"
|
||
"strings"
|
||
|
||
"github.com/ShukeBta/MediaStationGo/internal/model"
|
||
)
|
||
|
||
var (
|
||
dolbyVisionTokenRE = regexp.MustCompile(`\bdv\b`)
|
||
webDLTokenRE = regexp.MustCompile(`\bweb[\s._-]?dl\b`)
|
||
webRipTokenRE = regexp.MustCompile(`\bweb[\s._-]?rip\b`)
|
||
bluRayTokenRE = regexp.MustCompile(`\b(?:blu[\s._-]?ray|bdrip|bdremux|uhd[\s._-]?blu[\s._-]?ray)\b`)
|
||
)
|
||
|
||
const (
|
||
defaultSubscriptionFreePromotionScore = 50_000
|
||
washSubscriptionFreePromotionScore = 25
|
||
)
|
||
|
||
func subscriptionCandidateScore(sub *model.Subscription, item SearchResult) int {
|
||
title := strings.ToLower(subscriptionSearchResultText(item))
|
||
score := item.Seeders
|
||
if !subscriptionAllowsWash(sub) {
|
||
score += detectDefaultSubscriptionQualityScore(title)*1_000_000 + detectResolutionScore(title)*100_000
|
||
if item.Free {
|
||
score += defaultSubscriptionFreePromotionScore
|
||
}
|
||
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 += washSubscriptionFreePromotionScore
|
||
}
|
||
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") || dolbyVisionTokenRE.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 webDLTokenRE.MatchString(titleFold)
|
||
case "webrip", "web-rip":
|
||
return webRipTokenRE.MatchString(titleFold)
|
||
case "bluray", "blu-ray":
|
||
return bluRayTokenRE.MatchString(titleFold)
|
||
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 detectDefaultSubscriptionQualityScore(titleFold string) int {
|
||
switch {
|
||
case titleMatchesQuality(titleFold, "web-dl"):
|
||
return 5
|
||
case titleMatchesQuality(titleFold, "web-rip"):
|
||
return 4
|
||
case titleMatchesQuality(titleFold, "bluray"), titleMatchesQuality(titleFold, "remux"):
|
||
return 3
|
||
case titleMatchesQuality(titleFold, "hdtv"):
|
||
return 2
|
||
default:
|
||
return 1
|
||
}
|
||
}
|
||
|
||
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
|
||
}
|