diff --git a/anilist.go b/anilist.go index b5ff665..06a0645 100644 --- a/anilist.go +++ b/anilist.go @@ -12,7 +12,7 @@ type Pair[A, B any] struct { Second B } -func GetAnimesToDownloadByAnimeID() (map[anilist.MediaID]*anilist.MediaList, error) { +func GetAnimeListByAnimeID() (map[anilist.MediaID]*anilist.MediaList, error) { watchingAnimesChannel, err := GetCurrentlyWatchingAnimes() if err != nil { return nil, err diff --git a/download_torrent_file.go b/download_torrent_file.go index df869ae..d0396f5 100644 --- a/download_torrent_file.go +++ b/download_torrent_file.go @@ -12,7 +12,7 @@ import ( ) func DownloadTorrent(animeEp model.AnimeEpisode, torrent *model.ParsedTorrent) error { - if err := SetAnimeEpDownloading(animeEp); err != nil { + if err := SetCurrentlyDownloading(animeEp); err != nil { return ErrLockFileCreationFailed.Wrap(err, animeEp.Anime.Title.Romaji, animeEp.Episode) } diff --git a/local_file_check.go b/local_file_check.go index 7fa0f15..9ed5f55 100644 --- a/local_file_check.go +++ b/local_file_check.go @@ -41,11 +41,11 @@ func AnimeEpExistsLocally(animeEp model.AnimeEpisode) bool { return len(files) > 0 } -func GetLocalAnimeEpProperties(animeEp model.AnimeEpisode) (*FilePriority, bool, error) { +func GetAnimeEpProps(animeEp model.AnimeEpisode) (*FilePriority, bool) { animeEpPath := GetAnimeEpFilepath(animeEp, "*") files, err := filepath.Glob(animeEpPath) if err != nil { - return nil, false, ErrInvalidGlobSyntax.Wrap(err, animeEpPath) + panic(ErrInvalidGlobSyntax.Wrap(err, animeEpPath)) } var mostPrio *FilePriority @@ -67,16 +67,16 @@ func GetLocalAnimeEpProperties(animeEp model.AnimeEpisode) (*FilePriority, bool, } } - return mostPrio, mostPrio != nil, nil + return mostPrio, mostPrio != nil } -func IsAnimeEpDownloading(animeEp model.AnimeEpisode) bool { +func IsCurrentlyDownloading(animeEp model.AnimeEpisode) bool { animeEpPath := GetAnimeEpFilepath(animeEp, "lock") _, err := os.Stat(animeEpPath) return !errors.Is(err, os.ErrNotExist) } -func SetAnimeEpDownloading(animeEp model.AnimeEpisode) error { +func SetCurrentlyDownloading(animeEp model.AnimeEpisode) error { animeEpPath := GetAnimeEpFilepath(animeEp, "lock") file, err := os.Create(animeEpPath) if err != nil { diff --git a/main.go b/main.go index 323bbfe..e4ee225 100644 --- a/main.go +++ b/main.go @@ -97,70 +97,44 @@ func checkTorrents() { fmt.Println("checking torrents") start := time.Now() - torrents, err := GetLatestNyaaContent() + torrents, err := GetTorrents() if err != nil { fmt.Println(adverr.Wrap("retrieving torrents failed", err)) return } - animes, err := GetAnimesToDownloadByAnimeID() + animeList, err := GetAnimeListByAnimeID() if err != nil { fmt.Println(adverr.Wrap("retrieving anime list failed", err)) return } - parsedTorrents := ParseTorrentsByAnimeEpSortedByProperties(torrents) + // parse torrents + parsedTorrentsByAnimeEp := ParseTorrentsByAnimeEp(torrents) - for animeEp, torrentPriorities := range parsedTorrents { - _, animeOnList := animes[animeEp.Anime.ID] - props, found, err := GetLocalAnimeEpProperties(animeEp) - episodeInCollection := err == nil && found + // filter not on anime list + animeListTorrents := FilterTorrentsByAnimeList(parsedTorrentsByAnimeEp, animeList) - fmt.Print(FormatFilePriority(animeEp, props, animeOnList, episodeInCollection, len(torrentPriorities))) + // filter essential properties + essentialTorrents := FilterEssentialTorrents(animeListTorrents) - if !animeOnList { + // filter preferred properties + preferredTorrents := GetTorrentsWithMaxPrioByAnimeEp(essentialTorrents) + + for animeEp, torrentPrio := range preferredTorrents { + if IsCurrentlyDownloading(animeEp) { continue } - for _, torrentPriority := range torrentPriorities { - torrent := torrentPriority.ParsedTorrent + if props, inCollection := GetAnimeEpProps(animeEp); inCollection && props.Priority > torrentPrio.Priority { + continue + } - if IsAnimeEpDownloading(animeEp) { - fmt.Printf("%s | CURRENTLY DOWNLOADING\n", FormatTorrentPriority(torrentPriority)) - continue - } - - if episodeInCollection { - if props.Priority > torrentPriority.Priority { - fmt.Printf("%s | LOWER PRIORITY\n", FormatTorrentPriority(torrentPriority)) - } else { - fmt.Printf("%s | HIGHER PRIORITY | STARTING DOWNLOAD\n", FormatTorrentPriority(torrentPriority)) - if err := DownloadTorrent(animeEp, torrent); err != nil { - panic(err) - } - } - } else { - fmt.Printf("%s | NOT IN COLLECTION | STARTING DOWNLOAD\n", FormatTorrentPriority(torrentPriority)) - if err := DownloadTorrent(animeEp, torrent); err != nil { - panic(err) - } - } + if err := DownloadTorrent(animeEp, torrentPrio.ParsedTorrent); err != nil { + panic(err) // TODO error handling } } duration := time.Since(start) fmt.Printf("\ncheck took %s. sleeping for %s\n", duration.Truncate(time.Millisecond), (PollRate - duration).Truncate(time.Millisecond)) } - -func ParseTorrentsByAnimeEpSortedByProperties(torrents []model.Torrent) map[model.AnimeEpisode][]*TorrentPriority { - // parse torrents - parsedTorrentsByAnimeEp := ParseTorrentsByAnimeEp(torrents) - - // filter out torrents without essential properties - filteredTorrentsByAnimeEp := FilterEssentialTorrents(parsedTorrentsByAnimeEp) - - // sort torrents by preferred properties - sortedTorrentsByAnimeEp := SortTorrentsByPreferredProperties(filteredTorrentsByAnimeEp) - - return sortedTorrentsByAnimeEp -} diff --git a/nyaa.go b/nyaa.go index 8ffdd18..53652d9 100644 --- a/nyaa.go +++ b/nyaa.go @@ -14,7 +14,7 @@ import ( var torrentLinkRegex = regexp.MustCompile(`https:\/\/nyaa\.si\/download\/(\d+?)\.torrent`) -func GetLatestNyaaContent() ([]model.Torrent, error) { +func GetTorrents() ([]model.Torrent, error) { resp, err := http.Get("https://nyaa.si/?page=rss&f=0&c=0_0&q=Erai-Raws+ayumu") // TODO https://nyaa.si/?page=rss if err != nil { return nil, ErrTorrentNotObtainable.Wrap(err, "torrent data acqusition failed") diff --git a/torrent_filter.go b/torrent_filter.go index b366542..93933e5 100644 --- a/torrent_filter.go +++ b/torrent_filter.go @@ -1,20 +1,31 @@ package main import ( + "git.milar.in/milarin/anilist" "git.milar.in/milarin/slices" "git.milar.in/nyaanime/model" ) -func FilterEssentialTorrents(parsedTorrentsByAnimeEp map[model.AnimeEpisode][]*model.ParsedTorrent) map[model.AnimeEpisode][]*model.ParsedTorrent { - filteredMap := map[model.AnimeEpisode][]*model.ParsedTorrent{} - for animeEpisode, parsedTorrents := range parsedTorrentsByAnimeEp { +func FilterTorrentsByAnimeList(allTorrents map[model.AnimeEpisode][]*model.ParsedTorrent, animeList map[anilist.MediaID]*anilist.MediaList) map[model.AnimeEpisode][]*model.ParsedTorrent { + filtered := map[model.AnimeEpisode][]*model.ParsedTorrent{} + for animeEp, torrents := range allTorrents { + if _, ok := animeList[animeEp.Anime.ID]; ok { + filtered[animeEp] = torrents + } + } + return filtered +} + +func FilterEssentialTorrents(allTorrents map[model.AnimeEpisode][]*model.ParsedTorrent) map[model.AnimeEpisode][]*model.ParsedTorrent { + filtered := map[model.AnimeEpisode][]*model.ParsedTorrent{} + for animeEpisode, parsedTorrents := range allTorrents { for _, parsedTorrent := range parsedTorrents { if HasEssentialProperties(parsedTorrent) { - filteredMap[animeEpisode] = append(filteredMap[animeEpisode], parsedTorrent) + filtered[animeEpisode] = append(filtered[animeEpisode], parsedTorrent) } } } - return filteredMap + return filtered } func HasEssentialProperties(torrent *model.ParsedTorrent) bool { diff --git a/torrent_sort.go b/torrent_sort.go index bdf6ac5..51e7218 100644 --- a/torrent_sort.go +++ b/torrent_sort.go @@ -1,19 +1,27 @@ package main import ( - "sort" - "git.milar.in/milarin/slices" "git.milar.in/nyaanime/model" ) -func SortTorrentsByPreferredProperties(torrents map[model.AnimeEpisode][]*model.ParsedTorrent) map[model.AnimeEpisode][]*TorrentPriority { - torrentsWithPrio := map[model.AnimeEpisode][]*TorrentPriority{} +func GetTorrentsWithMaxPrioByAnimeEp(torrents map[model.AnimeEpisode][]*model.ParsedTorrent) map[model.AnimeEpisode]*TorrentPriority { + torrentsWithPrio := map[model.AnimeEpisode]*TorrentPriority{} for animeEp, torrentList := range torrents { torrentPrioList := slices.Map(torrentList, NewTorrentPriority) - sort.Slice(torrentPrioList, func(i, j int) bool { return torrentPrioList[i].Priority > torrentPrioList[j].Priority }) - torrentsWithPrio[animeEp] = torrentPrioList + + var maxPrio *TorrentPriority + + for _, torrentPrio := range torrentPrioList { + if maxPrio == nil || torrentPrio.Priority > maxPrio.Priority { + maxPrio = torrentPrio + } + } + + if maxPrio != nil { + torrentsWithPrio[animeEp] = maxPrio + } } return torrentsWithPrio