mirror of
https://gitlab.com/foxixus/neomovies-api.git
synced 2025-10-28 09:58:50 +05:00
Bug fix
This commit is contained in:
@@ -32,7 +32,7 @@ func NewTorrentService() *TorrentService {
|
||||
// SearchTorrents - основной метод поиска торрентов через RedAPI
|
||||
func (s *TorrentService) SearchTorrents(params map[string]string) (*models.TorrentSearchResponse, error) {
|
||||
searchParams := url.Values{}
|
||||
|
||||
|
||||
// Добавляем все параметры поиска
|
||||
for key, value := range params {
|
||||
if value != "" {
|
||||
@@ -43,13 +43,13 @@ func (s *TorrentService) SearchTorrents(params map[string]string) (*models.Torre
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if s.apiKey != "" {
|
||||
searchParams.Add("apikey", s.apiKey)
|
||||
}
|
||||
|
||||
searchURL := fmt.Sprintf("%s/api/v2.0/indexers/all/results?%s", s.baseURL, searchParams.Encode())
|
||||
|
||||
|
||||
resp, err := s.client.Get(searchURL)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to search torrents: %w", err)
|
||||
@@ -67,7 +67,7 @@ func (s *TorrentService) SearchTorrents(params map[string]string) (*models.Torre
|
||||
}
|
||||
|
||||
results := s.parseRedAPIResults(redAPIResponse)
|
||||
|
||||
|
||||
return &models.TorrentSearchResponse{
|
||||
Query: params["query"],
|
||||
Results: results,
|
||||
@@ -78,7 +78,7 @@ func (s *TorrentService) SearchTorrents(params map[string]string) (*models.Torre
|
||||
// parseRedAPIResults преобразует результаты RedAPI в наш формат
|
||||
func (s *TorrentService) parseRedAPIResults(data models.RedAPIResponse) []models.TorrentResult {
|
||||
var results []models.TorrentResult
|
||||
|
||||
|
||||
for _, torrent := range data.Results {
|
||||
// Обрабатываем размер - может быть строкой или числом
|
||||
var sizeStr string
|
||||
@@ -92,7 +92,7 @@ func (s *TorrentService) parseRedAPIResults(data models.RedAPIResponse) []models
|
||||
default:
|
||||
sizeStr = ""
|
||||
}
|
||||
|
||||
|
||||
result := models.TorrentResult{
|
||||
Title: torrent.Title,
|
||||
Tracker: torrent.Tracker,
|
||||
@@ -105,7 +105,7 @@ func (s *TorrentService) parseRedAPIResults(data models.RedAPIResponse) []models
|
||||
Details: torrent.Details,
|
||||
Source: "RedAPI",
|
||||
}
|
||||
|
||||
|
||||
// Добавляем информацию из Info если она есть
|
||||
if torrent.Info != nil {
|
||||
// Обрабатываем качество - может быть строкой или числом
|
||||
@@ -117,56 +117,55 @@ func (s *TorrentService) parseRedAPIResults(data models.RedAPIResponse) []models
|
||||
case int:
|
||||
result.Quality = fmt.Sprintf("%dp", v)
|
||||
}
|
||||
|
||||
|
||||
result.Voice = torrent.Info.Voices
|
||||
result.Types = torrent.Info.Types
|
||||
result.Seasons = torrent.Info.Seasons
|
||||
}
|
||||
|
||||
|
||||
// Если качество не определено через Info, пытаемся извлечь из названия
|
||||
if result.Quality == "" {
|
||||
result.Quality = s.ExtractQuality(result.Title)
|
||||
}
|
||||
|
||||
|
||||
results = append(results, result)
|
||||
}
|
||||
|
||||
|
||||
return results
|
||||
}
|
||||
|
||||
// SearchTorrentsByIMDbID - поиск по IMDB ID с поддержкой всех функций
|
||||
func (s *TorrentService) SearchTorrentsByIMDbID(tmdbService *TMDBService, imdbID, mediaType string, options *models.TorrentSearchOptions) (*models.TorrentSearchResponse, error) {
|
||||
// Получаем информацию о фильме/сериале из TMDB
|
||||
// ИСПРАВЛЕНО: Теперь присваиваются все 4 возвращаемых значения
|
||||
title, originalTitle, year, err := s.getTitleFromTMDB(tmdbService, imdbID, mediaType)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to get title from TMDB: %w", err)
|
||||
}
|
||||
|
||||
// Формируем параметры поиска
|
||||
params := make(map[string]string)
|
||||
params["imdb"] = imdbID
|
||||
params["title"] = title
|
||||
params["title_original"] = originalTitle
|
||||
params["year"] = year
|
||||
|
||||
// Устанавливаем тип контента и категорию
|
||||
// Создаем параметры поиска для RedAPI
|
||||
params := map[string]string{
|
||||
"imdb": imdbID,
|
||||
"query": title,
|
||||
"title_original": originalTitle,
|
||||
"year": year,
|
||||
}
|
||||
|
||||
// Определяем тип контента для API
|
||||
switch mediaType {
|
||||
case "movie":
|
||||
params["is_serial"] = "1"
|
||||
params["category"] = "2000"
|
||||
case "tv", "series":
|
||||
case "serial", "series", "tv":
|
||||
params["is_serial"] = "2"
|
||||
params["category"] = "5000"
|
||||
case "anime":
|
||||
params["is_serial"] = "5"
|
||||
params["category"] = "5070"
|
||||
default:
|
||||
params["is_serial"] = "1"
|
||||
params["category"] = "2000"
|
||||
}
|
||||
|
||||
// Добавляем сезон если указан
|
||||
if options != nil && options.Season != nil {
|
||||
|
||||
// Добавляем сезон, если он указан
|
||||
if options != nil && options.Season != nil && *options.Season > 0 {
|
||||
params["season"] = strconv.Itoa(*options.Season)
|
||||
}
|
||||
|
||||
@@ -181,12 +180,40 @@ func (s *TorrentService) SearchTorrentsByIMDbID(tmdbService *TMDBService, imdbID
|
||||
response.Results = s.FilterByContentType(response.Results, options.ContentType)
|
||||
response.Results = s.FilterTorrents(response.Results, options)
|
||||
response.Results = s.sortTorrents(response.Results, options.SortBy, options.SortOrder)
|
||||
response.Total = len(response.Results)
|
||||
}
|
||||
response.Total = len(response.Results)
|
||||
|
||||
// Fallback для сериалов, если результатов мало
|
||||
if len(response.Results) < 5 && (mediaType == "serial" || mediaType == "series" || mediaType == "tv") && options != nil && options.Season != nil {
|
||||
paramsNoSeason := map[string]string{
|
||||
"imdb": imdbID,
|
||||
"query": title,
|
||||
"title_original": originalTitle,
|
||||
"year": year,
|
||||
"is_serial": "2",
|
||||
"category": "5000",
|
||||
}
|
||||
fallbackResp, err := s.SearchTorrents(paramsNoSeason)
|
||||
if err == nil {
|
||||
filtered := s.filterBySeason(fallbackResp.Results, *options.Season)
|
||||
all := append(response.Results, filtered...)
|
||||
unique := make([]models.TorrentResult, 0, len(all))
|
||||
seen := make(map[string]bool)
|
||||
for _, t := range all {
|
||||
if !seen[t.MagnetLink] {
|
||||
unique = append(unique, t)
|
||||
seen[t.MagnetLink] = true
|
||||
}
|
||||
}
|
||||
response.Results = unique
|
||||
response.Total = len(response.Results)
|
||||
}
|
||||
}
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
|
||||
// SearchMovies - поиск фильмов с дополнительной фильтрацией
|
||||
func (s *TorrentService) SearchMovies(title, originalTitle, year string) (*models.TorrentSearchResponse, error) {
|
||||
params := map[string]string{
|
||||
@@ -196,15 +223,15 @@ func (s *TorrentService) SearchMovies(title, originalTitle, year string) (*model
|
||||
"is_serial": "1",
|
||||
"category": "2000",
|
||||
}
|
||||
|
||||
|
||||
response, err := s.SearchTorrents(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
response.Results = s.FilterByContentType(response.Results, "movie")
|
||||
response.Total = len(response.Results)
|
||||
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
@@ -304,15 +331,15 @@ func (s *TorrentService) SearchAnime(title, originalTitle, year string) (*models
|
||||
"is_serial": "5",
|
||||
"category": "5070",
|
||||
}
|
||||
|
||||
|
||||
response, err := s.SearchTorrents(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
response.Results = s.FilterByContentType(response.Results, "anime")
|
||||
response.Total = len(response.Results)
|
||||
|
||||
|
||||
return response, nil
|
||||
}
|
||||
|
||||
@@ -331,7 +358,7 @@ type AllohaResponse struct {
|
||||
func (s *TorrentService) getMovieInfoByIMDB(imdbID string) (string, string, string, error) {
|
||||
// Используем тот же токен что и в JavaScript версии
|
||||
endpoint := fmt.Sprintf("https://api.alloha.tv/?token=04941a9a3ca3ac16e2b4327347bbc1&imdb=%s", imdbID)
|
||||
|
||||
|
||||
req, err := http.NewRequest("GET", endpoint, nil)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
@@ -377,7 +404,7 @@ func (s *TorrentService) getTitleFromTMDB(tmdbService *TMDBService, imdbID, medi
|
||||
|
||||
// Если Alloha API не работает, пробуем TMDB API
|
||||
endpoint := fmt.Sprintf("https://api.themoviedb.org/3/find/%s", imdbID)
|
||||
|
||||
|
||||
req, err := http.NewRequest("GET", endpoint, nil)
|
||||
if err != nil {
|
||||
return "", "", "", err
|
||||
@@ -444,14 +471,12 @@ func (s *TorrentService) getTitleFromTMDB(tmdbService *TMDBService, imdbID, medi
|
||||
return "", "", "", fmt.Errorf("no results found for IMDB ID: %s", imdbID)
|
||||
}
|
||||
|
||||
// FilterByContentType - фильтрация по типу контента
|
||||
// FilterByContentType - фильтрация по типу контента (как в JS)
|
||||
func (s *TorrentService) FilterByContentType(results []models.TorrentResult, contentType string) []models.TorrentResult {
|
||||
if contentType == "" {
|
||||
return results
|
||||
}
|
||||
|
||||
var filtered []models.TorrentResult
|
||||
|
||||
for _, torrent := range results {
|
||||
// Фильтрация по полю types, если оно есть
|
||||
if len(torrent.Types) > 0 {
|
||||
@@ -460,7 +485,7 @@ func (s *TorrentService) FilterByContentType(results []models.TorrentResult, con
|
||||
if s.containsAny(torrent.Types, []string{"movie", "multfilm", "documovie"}) {
|
||||
filtered = append(filtered, torrent)
|
||||
}
|
||||
case "serial":
|
||||
case "serial", "series", "tv":
|
||||
if s.containsAny(torrent.Types, []string{"serial", "multserial", "docuserial", "tvshow"}) {
|
||||
filtered = append(filtered, torrent)
|
||||
}
|
||||
@@ -471,7 +496,6 @@ func (s *TorrentService) FilterByContentType(results []models.TorrentResult, con
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
// Фильтрация по названию, если types недоступно
|
||||
title := strings.ToLower(torrent.Title)
|
||||
switch contentType {
|
||||
@@ -479,7 +503,7 @@ func (s *TorrentService) FilterByContentType(results []models.TorrentResult, con
|
||||
if !regexp.MustCompile(`(?i)(сезон|серии|series|season|эпизод)`).MatchString(title) {
|
||||
filtered = append(filtered, torrent)
|
||||
}
|
||||
case "serial":
|
||||
case "serial", "series", "tv":
|
||||
if regexp.MustCompile(`(?i)(сезон|серии|series|season|эпизод)`).MatchString(title) {
|
||||
filtered = append(filtered, torrent)
|
||||
}
|
||||
@@ -491,7 +515,6 @@ func (s *TorrentService) FilterByContentType(results []models.TorrentResult, con
|
||||
filtered = append(filtered, torrent)
|
||||
}
|
||||
}
|
||||
|
||||
return filtered
|
||||
}
|
||||
|
||||
@@ -579,7 +602,7 @@ func (s *TorrentService) matchesSeason(torrent models.TorrentResult, season int)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Проверяем в названии
|
||||
seasonRegex := regexp.MustCompile(`(?i)(?:s|сезон)[\s:]*(\d+)|(\d+)\s*сезон`)
|
||||
matches := seasonRegex.FindAllStringSubmatch(torrent.Title, -1)
|
||||
@@ -594,14 +617,14 @@ func (s *TorrentService) matchesSeason(torrent models.TorrentResult, season int)
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// ExtractQuality - извлечение качества из названия
|
||||
func (s *TorrentService) ExtractQuality(title string) string {
|
||||
title = strings.ToUpper(title)
|
||||
|
||||
|
||||
qualityPatterns := []struct {
|
||||
pattern string
|
||||
quality string
|
||||
@@ -613,7 +636,7 @@ func (s *TorrentService) ExtractQuality(title string) string {
|
||||
{`480P`, "480p"},
|
||||
{`360P`, "360p"},
|
||||
}
|
||||
|
||||
|
||||
for _, qp := range qualityPatterns {
|
||||
if matched, _ := regexp.MatchString(qp.pattern, title); matched {
|
||||
if qp.quality == "2160p" {
|
||||
@@ -622,7 +645,7 @@ func (s *TorrentService) ExtractQuality(title string) string {
|
||||
return qp.quality
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return "Unknown"
|
||||
}
|
||||
|
||||
@@ -637,14 +660,16 @@ func (s *TorrentService) sortTorrents(torrents []models.TorrentResult, sortBy, s
|
||||
|
||||
sort.Slice(torrents, func(i, j int) bool {
|
||||
var less bool
|
||||
|
||||
|
||||
switch sortBy {
|
||||
case "seeders":
|
||||
less = torrents[i].Seeders < torrents[j].Seeders
|
||||
case "size":
|
||||
less = s.compareSizes(torrents[i].Size, torrents[j].Size)
|
||||
case "date":
|
||||
less = torrents[i].PublishDate < torrents[j].PublishDate
|
||||
t1, _ := time.Parse(time.RFC3339, torrents[i].PublishDate)
|
||||
t2, _ := time.Parse(time.RFC3339, torrents[j].PublishDate)
|
||||
less = t1.Before(t2)
|
||||
default:
|
||||
less = torrents[i].Seeders < torrents[j].Seeders
|
||||
}
|
||||
@@ -661,43 +686,43 @@ func (s *TorrentService) sortTorrents(torrents []models.TorrentResult, sortBy, s
|
||||
// GroupByQuality - группировка по качеству
|
||||
func (s *TorrentService) GroupByQuality(results []models.TorrentResult) map[string][]models.TorrentResult {
|
||||
groups := make(map[string][]models.TorrentResult)
|
||||
|
||||
|
||||
for _, torrent := range results {
|
||||
quality := torrent.Quality
|
||||
if quality == "" {
|
||||
quality = "unknown"
|
||||
}
|
||||
|
||||
|
||||
// Объединяем 4K и 2160p в одну группу
|
||||
if quality == "2160p" {
|
||||
quality = "4K"
|
||||
}
|
||||
|
||||
|
||||
groups[quality] = append(groups[quality], torrent)
|
||||
}
|
||||
|
||||
|
||||
// Сортируем торренты внутри каждой группы по сидам
|
||||
for quality := range groups {
|
||||
sort.Slice(groups[quality], func(i, j int) bool {
|
||||
return groups[quality][i].Seeders > groups[quality][j].Seeders
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
return groups
|
||||
}
|
||||
|
||||
// GroupBySeason - группировка по сезонам
|
||||
func (s *TorrentService) GroupBySeason(results []models.TorrentResult) map[string][]models.TorrentResult {
|
||||
groups := make(map[string][]models.TorrentResult)
|
||||
|
||||
|
||||
for _, torrent := range results {
|
||||
seasons := make(map[int]bool)
|
||||
|
||||
|
||||
// Извлекаем сезоны из поля seasons
|
||||
for _, season := range torrent.Seasons {
|
||||
seasons[season] = true
|
||||
}
|
||||
|
||||
|
||||
// Извлекаем сезоны из названия
|
||||
seasonRegex := regexp.MustCompile(`(?i)(?:s|сезон)[\s:]*(\d+)|(\d+)\s*сезон`)
|
||||
matches := seasonRegex.FindAllStringSubmatch(torrent.Title, -1)
|
||||
@@ -712,7 +737,7 @@ func (s *TorrentService) GroupBySeason(results []models.TorrentResult) map[strin
|
||||
seasons[seasonNumber] = true
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Если сезоны не найдены, добавляем в группу "unknown"
|
||||
if len(seasons) == 0 {
|
||||
groups["Неизвестно"] = append(groups["Неизвестно"], torrent)
|
||||
@@ -734,14 +759,14 @@ func (s *TorrentService) GroupBySeason(results []models.TorrentResult) map[strin
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Сортируем торренты внутри каждой группы по сидам
|
||||
for season := range groups {
|
||||
sort.Slice(groups[season], func(i, j int) bool {
|
||||
return groups[season][i].Seeders > groups[season][j].Seeders
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
return groups
|
||||
}
|
||||
|
||||
@@ -751,15 +776,15 @@ func (s *TorrentService) GetAvailableSeasons(title, originalTitle, year string)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
||||
seasonsSet := make(map[int]bool)
|
||||
|
||||
|
||||
for _, torrent := range response.Results {
|
||||
// Извлекаем из поля seasons
|
||||
for _, season := range torrent.Seasons {
|
||||
seasonsSet[season] = true
|
||||
}
|
||||
|
||||
|
||||
// Извлекаем из названия
|
||||
seasonRegex := regexp.MustCompile(`(?i)(?:s|сезон)[\s:]*(\d+)|(\d+)\s*сезон`)
|
||||
matches := seasonRegex.FindAllStringSubmatch(torrent.Title, -1)
|
||||
@@ -775,25 +800,99 @@ func (s *TorrentService) GetAvailableSeasons(title, originalTitle, year string)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
var seasons []int
|
||||
for season := range seasonsSet {
|
||||
seasons = append(seasons, season)
|
||||
}
|
||||
|
||||
|
||||
sort.Ints(seasons)
|
||||
return seasons, nil
|
||||
}
|
||||
|
||||
// Вспомогательные функции
|
||||
// SearchByImdb - поиск по IMDB ID (movie/serial/anime).
|
||||
func (s *TorrentService) SearchByImdb(imdbID, contentType string, season *int) ([]models.TorrentResult, error) {
|
||||
if imdbID == "" || !strings.HasPrefix(imdbID, "tt") {
|
||||
return nil, fmt.Errorf("Неверный формат IMDB ID. Должен быть в формате tt1234567")
|
||||
}
|
||||
|
||||
// НЕ добавляем title, originalTitle, year, чтобы запрос не был слишком строгим.
|
||||
params := map[string]string{
|
||||
"imdb": imdbID,
|
||||
}
|
||||
|
||||
// Определяем тип контента для API
|
||||
switch contentType {
|
||||
case "movie":
|
||||
params["is_serial"] = "1"
|
||||
params["category"] = "2000"
|
||||
case "serial", "series", "tv":
|
||||
params["is_serial"] = "2"
|
||||
params["category"] = "5000"
|
||||
case "anime":
|
||||
params["is_serial"] = "5"
|
||||
params["category"] = "5070"
|
||||
default:
|
||||
// Значение по умолчанию на случай неизвестного типа
|
||||
params["is_serial"] = "1"
|
||||
params["category"] = "2000"
|
||||
}
|
||||
|
||||
// Параметр season можно оставить, он полезен
|
||||
if season != nil && *season > 0 {
|
||||
params["season"] = strconv.Itoa(*season)
|
||||
}
|
||||
|
||||
resp, err := s.SearchTorrents(params)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
results := resp.Results
|
||||
|
||||
// Fallback для сериалов: если указан сезон и результатов мало, ищем без сезона и фильтруем на клиенте
|
||||
if s.contains([]string{"serial", "series", "tv"}, contentType) && season != nil && len(results) < 5 {
|
||||
paramsNoSeason := map[string]string{
|
||||
"imdb": imdbID,
|
||||
"is_serial": "2",
|
||||
"category": "5000",
|
||||
}
|
||||
|
||||
fallbackResp, err := s.SearchTorrents(paramsNoSeason)
|
||||
if err == nil {
|
||||
filtered := s.filterBySeason(fallbackResp.Results, *season)
|
||||
// Объединяем и убираем дубликаты по MagnetLink
|
||||
all := append(results, filtered...)
|
||||
unique := make([]models.TorrentResult, 0, len(all))
|
||||
seen := make(map[string]bool)
|
||||
for _, t := range all {
|
||||
if !seen[t.MagnetLink] {
|
||||
unique = append(unique, t)
|
||||
seen[t.MagnetLink] = true
|
||||
}
|
||||
}
|
||||
results = unique
|
||||
}
|
||||
}
|
||||
|
||||
// Финальная фильтрация по типу контента на стороне клиента для надежности
|
||||
results = s.FilterByContentType(results, contentType)
|
||||
return results, nil
|
||||
}
|
||||
|
||||
// ############# ВСПОМОГАТЕЛЬНЫЕ ФУНКЦИИ #############
|
||||
|
||||
func (s *TorrentService) qualityMeetsMinimum(quality, minQuality string) bool {
|
||||
qualityOrder := map[string]int{
|
||||
"360p": 1, "480p": 2, "720p": 3, "1080p": 4, "1440p": 5, "4K": 6, "2160p": 6,
|
||||
}
|
||||
|
||||
currentLevel := qualityOrder[strings.ToLower(quality)]
|
||||
minLevel := qualityOrder[strings.ToLower(minQuality)]
|
||||
|
||||
|
||||
currentLevel, ok1 := qualityOrder[strings.ToLower(quality)]
|
||||
minLevel, ok2 := qualityOrder[strings.ToLower(minQuality)]
|
||||
|
||||
if !ok1 || !ok2 {
|
||||
return true // Если качество не определено, не фильтруем
|
||||
}
|
||||
|
||||
return currentLevel >= minLevel
|
||||
}
|
||||
|
||||
@@ -801,21 +900,32 @@ func (s *TorrentService) qualityMeetsMaximum(quality, maxQuality string) bool {
|
||||
qualityOrder := map[string]int{
|
||||
"360p": 1, "480p": 2, "720p": 3, "1080p": 4, "1440p": 5, "4K": 6, "2160p": 6,
|
||||
}
|
||||
|
||||
currentLevel := qualityOrder[strings.ToLower(quality)]
|
||||
maxLevel := qualityOrder[strings.ToLower(maxQuality)]
|
||||
|
||||
|
||||
currentLevel, ok1 := qualityOrder[strings.ToLower(quality)]
|
||||
maxLevel, ok2 := qualityOrder[strings.ToLower(maxQuality)]
|
||||
|
||||
if !ok1 || !ok2 {
|
||||
return true // Если качество не определено, не фильтруем
|
||||
}
|
||||
|
||||
return currentLevel <= maxLevel
|
||||
}
|
||||
|
||||
func (s *TorrentService) parseSize(sizeStr string) int64 {
|
||||
val, err := strconv.ParseInt(sizeStr, 10, 64)
|
||||
if err != nil {
|
||||
return 0
|
||||
}
|
||||
return val
|
||||
}
|
||||
|
||||
func (s *TorrentService) compareSizes(size1, size2 string) bool {
|
||||
// Простое сравнение размеров (можно улучшить)
|
||||
return len(size1) < len(size2)
|
||||
return s.parseSize(size1) < s.parseSize(size2)
|
||||
}
|
||||
|
||||
func (s *TorrentService) contains(slice []string, item string) bool {
|
||||
for _, s := range slice {
|
||||
if s == item {
|
||||
if strings.EqualFold(s, item) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -829,4 +939,4 @@ func (s *TorrentService) containsAny(slice []string, items []string) bool {
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user