mirror of
https://github.com/truewhile/MeBox.git
synced 2026-09-28 03:06:38 +08:00
146 lines
3.2 KiB
Go
146 lines
3.2 KiB
Go
package service
|
|
|
|
import (
|
|
"fmt"
|
|
"net/url"
|
|
"path"
|
|
"regexp"
|
|
"strings"
|
|
"unicode"
|
|
)
|
|
|
|
var torrentEpisodeToken = regexp.MustCompile(`(?i)e\d{1,3}`)
|
|
|
|
func localAvailabilityTitleCandidates(title string) []string {
|
|
seen := map[string]struct{}{}
|
|
out := make([]string, 0, 6)
|
|
add := func(value string) {
|
|
value = strings.TrimSpace(value)
|
|
if value == "" {
|
|
return
|
|
}
|
|
if _, ok := seen[value]; ok {
|
|
return
|
|
}
|
|
seen[value] = struct{}{}
|
|
out = append(out, value)
|
|
}
|
|
add(availabilityQuery(title, ""))
|
|
if cleaned, _ := CleanQuery(title); cleaned != "" {
|
|
for _, candidate := range titleCandidates(cleaned) {
|
|
add(candidate)
|
|
fields := strings.Fields(candidate)
|
|
for i := len(fields) - 1; i >= 1; i-- {
|
|
prefix := strings.Join(fields[:i], " ")
|
|
if containsCJK(prefix) {
|
|
add(prefix)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
func downloadTaskBlocksDuplicate(status string) bool {
|
|
switch strings.ToLower(strings.TrimSpace(status)) {
|
|
case "failed", "error", "removed", "cancelled", "canceled":
|
|
return false
|
|
default:
|
|
return true
|
|
}
|
|
}
|
|
|
|
func downloadTaskBlocksReadd(status string) bool {
|
|
switch strings.ToLower(strings.TrimSpace(status)) {
|
|
case "failed", "error", "deleted", "removed", "cancelled", "canceled":
|
|
return false
|
|
default:
|
|
return true
|
|
}
|
|
}
|
|
|
|
func downloadTaskIdentityKey(name string) string {
|
|
if key := downloadMediaIdentityKey(name); key != "" {
|
|
return key
|
|
}
|
|
return normalizedDownloadTitleKey(name)
|
|
}
|
|
|
|
func downloadMediaIdentityKey(name string) string {
|
|
name = strings.ToLower(strings.TrimSpace(name))
|
|
if name == "" {
|
|
return ""
|
|
}
|
|
title, year := CleanQuery(name)
|
|
titleKey := normalizeAvailabilityComparable(title)
|
|
if titleKey == "" {
|
|
titleKey = normalizeAvailabilityComparable(availabilityQuery(name, ""))
|
|
}
|
|
if titleKey == "" {
|
|
return ""
|
|
}
|
|
season, episode := ParseEpisode(name)
|
|
parts := []string{titleKey}
|
|
if year > 0 {
|
|
parts = append(parts, fmt.Sprintf("y%d", year))
|
|
}
|
|
if episode > 0 {
|
|
if season <= 0 {
|
|
season = 1
|
|
}
|
|
parts = append(parts, fmt.Sprintf("s%02de%03d", season, episode))
|
|
}
|
|
return strings.Join(parts, "|")
|
|
}
|
|
|
|
func normalizedDownloadTitleKey(name string) string {
|
|
name = strings.ToLower(strings.TrimSpace(name))
|
|
var b strings.Builder
|
|
for _, r := range name {
|
|
if unicode.IsLetter(r) || unicode.IsDigit(r) {
|
|
b.WriteRune(r)
|
|
}
|
|
}
|
|
return b.String()
|
|
}
|
|
|
|
func publicDownloadTitle(raw string) string {
|
|
raw = strings.TrimSpace(raw)
|
|
if raw == "" {
|
|
return "下载任务"
|
|
}
|
|
if u, err := url.Parse(raw); err == nil {
|
|
if dn := strings.TrimSpace(u.Query().Get("dn")); dn != "" {
|
|
if decoded, err := url.QueryUnescape(dn); err == nil && strings.TrimSpace(decoded) != "" {
|
|
return strings.TrimSpace(decoded)
|
|
}
|
|
return dn
|
|
}
|
|
if u.Host != "" {
|
|
base := path.Base(u.Path)
|
|
if base != "." && base != "/" && base != "" {
|
|
base = strings.TrimSuffix(base, path.Ext(base))
|
|
if base != "" {
|
|
return base
|
|
}
|
|
}
|
|
return u.Host
|
|
}
|
|
}
|
|
if strings.HasPrefix(strings.ToLower(raw), "magnet:") {
|
|
return "磁力下载"
|
|
}
|
|
return "下载任务"
|
|
}
|
|
|
|
func normalizeTorrentName(name string) string {
|
|
name = torrentEpisodeToken.ReplaceAllString(strings.ToLower(name), "")
|
|
var b strings.Builder
|
|
for _, r := range name {
|
|
if unicode.IsLetter(r) || unicode.IsDigit(r) {
|
|
b.WriteRune(r)
|
|
}
|
|
}
|
|
return b.String()
|
|
}
|