package naming import ( "regexp" "strings" ) // parenURL — markdown-хвост " (https://…)" в строках контекста. var parenURL = regexp.MustCompile(`\s*\(https?://[^)]+\)`) // parenSpecs — открывающая скобка тех. характеристик «(2024, …»: круглая // скобка, за которой (через необяз. пробелы) идёт цифра. var parenSpecs = regexp.MustCompile(`\(\s*\d`) // fallbackName выводит имя без сети: берёт первую содержательную строку // контекста, отсекает технические характеристики и обрезает по длине. Если // контекст пуст/бесполезен — пробует hint (dn из magnet). Возвращает "", // если ничего пригодного нет. func fallbackName(contextText, hint string) string { if line := firstMeaningfulLine(contextText); line != "" { return truncate(stripTechSpecs(line), maxNameLen) } if h := sanitize(hint); h != "" { return truncate(stripTechSpecs(h), maxNameLen) } return "" } // firstMeaningfulLine возвращает первую строку контекста, не являющуюся // ссылкой, командой бота или UI-мусором. Контекст из tgbot уже вычищен, но // для HTTP/CLI вход может быть сырым — отсюда лёгкая фильтрация. func firstMeaningfulLine(text string) string { for line := range strings.SplitSeq(text, "\n") { line = strings.TrimSpace(parenURL.ReplaceAllString(line, "")) line = sanitize(line) if line == "" || isNoiseLine(line) { continue } return line } return "" } // isNoiseLine отсекает строки-ссылки и команды бота (см. tgbot для исходной // эвристики; здесь — минимум, нужный фолбеку для сырого ввода). Проверяем // префиксы, а не вхождения: голый URL внутри осмысленной строки не должен // выкидывать всю строку с названием. func isNoiseLine(line string) bool { switch { case strings.HasPrefix(line, "/"): return true // команда бота case strings.HasPrefix(line, "magnet:"), strings.HasPrefix(line, "http://"), strings.HasPrefix(line, "https://"): return true // строка-ссылка case strings.Contains(line, ": /"): return true // строка рейтинга/команд бота «👍: /g_… или 👎: /r_…» default: return false } } // stripTechSpecs отсекает хвост технических характеристик в скобках — // квадратных ("… [2024, WEB-DL 2160p …]") или круглых с годом // ("… (2024, WEB-DL …)") — и подчищает разделители на конце. Скобка с // текстом (например режиссёр «(Дени Вильнёв)») не режется. func stripTechSpecs(s string) string { cut := len(s) if i := strings.IndexByte(s, '['); i >= 0 && i < cut { cut = i } if loc := parenSpecs.FindStringIndex(s); loc != nil && loc[0] < cut { cut = loc[0] } s = strings.TrimRight(s[:cut], " -–—/.,") return strings.TrimSpace(s) }