164 lines
5.0 KiB
Go
164 lines
5.0 KiB
Go
package main
|
|
|
|
import (
|
|
"fmt"
|
|
"html/template"
|
|
"math"
|
|
"time"
|
|
|
|
"git.milar.in/milarin/adverr"
|
|
"git.milar.in/milarin/anilist"
|
|
"git.milar.in/milarin/envvars"
|
|
"git.milar.in/nyaanime/model"
|
|
)
|
|
|
|
var (
|
|
PollRate = envvars.Object("POLL_RATE", 30*time.Minute, time.ParseDuration)
|
|
|
|
AnilistUsername = envvars.String("ANILIST_USERNAME", "username")
|
|
AnilistAccessToken = envvars.String("ANILIST_TOKEN", "")
|
|
|
|
StoragePath = envvars.String("STORAGE_PATH", "")
|
|
StorageUser = envvars.String("STORAGE_USER", "")
|
|
StoragePass = envvars.String("STORAGE_PASS", "")
|
|
|
|
TorrentPath = envvars.String("TORRENT_PATH", "")
|
|
AnimePath = envvars.String("ANIME_PATH", "")
|
|
|
|
AnimeEpFilepathPattern = envvars.Object(
|
|
"EPISODE_FILEPATH_PATTERN",
|
|
template.Must(template.New("anime-episode-filepath-pattern").Parse(`{{.Title.UserPreferred}}/{{.Title.UserPreferred}} Episode {{.Episode}}.{{.Ext}}`)),
|
|
template.New("anime-episode-filepath-pattern").Parse,
|
|
)
|
|
|
|
AnimeStatus = envvars.ObjectSlice("ANIME_STATUS", ",", ParseMediaListStatus)
|
|
|
|
// essential torrent properties
|
|
|
|
MaxResolution = envvars.Object("MAX_RESOLUTION", model.Resolution4K, model.ParseResolution)
|
|
MinResolution = envvars.Object("MIN_RESOLUTION", model.ResolutionHD, model.ParseResolution)
|
|
|
|
EssentialLanguages = envvars.StringSlice("ESSENTIAL_LANGUAGES", "|")
|
|
EssentialSubtitles = envvars.StringSlice("ESSENTIAL_SUBTITLES", "|")
|
|
|
|
MaxSeeders = envvars.Int("MAX_SEEDERS", math.MaxInt)
|
|
MinSeeders = envvars.Int("MIN_SEEDERS", 0)
|
|
|
|
MaxLeechers = envvars.Int("MAX_LEECHERS", math.MaxInt)
|
|
MinLeechers = envvars.Int("MIN_LEECHERS", 0)
|
|
|
|
MaxDownloads = envvars.Int("MAX_DOWNLOADS", math.MaxInt)
|
|
MinDownloads = envvars.Int("MIN_DOWNLOADS", 0)
|
|
|
|
TrustedOnly = envvars.Bool("TRUSTED_ONLY", false)
|
|
|
|
// preferred torrent properties
|
|
|
|
PreferredLanguages = ParsePreferredStringProps(envvars.StringSlice("PREFERRED_LANGUAGES", "|"))
|
|
PreferredSubtitles = ParsePreferredStringProps(envvars.StringSlice("PREFERRED_SUBTITLES", "|"))
|
|
PreferredResolutions = ParsePreferredProps(envvars.StringSlice("PREFERRED_RESOLUTIONS", "|"), model.ParseResolution)
|
|
|
|
/*
|
|
TODO
|
|
|
|
PreferMoreLanguages = envvars.Bool("PREFERER_MORE_LANGUAGES", false)
|
|
PreferMoreSubtitles = envvars.Bool("PREFERER_MORE_SUBTITLES", false)
|
|
*/
|
|
)
|
|
|
|
func main() {
|
|
fmt.Println("language priorites:", Map2Str(PreferredLanguages))
|
|
fmt.Println("subtitle priorites:", Map2Str(PreferredSubtitles))
|
|
fmt.Println("resolution priorites:", Map2Str(PreferredResolutions))
|
|
|
|
if len(AnimeStatus) == 0 {
|
|
AnimeStatus = []anilist.MediaListStatus{
|
|
anilist.MediaListStatusCurrent,
|
|
anilist.MediaListStatusPlanning,
|
|
}
|
|
}
|
|
|
|
// get access token once at startup to be sure that an access token is obtainable at all
|
|
if _, err := GetAnilistAccessToken(); err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
ticker := time.NewTicker(PollRate)
|
|
defer ticker.Stop()
|
|
|
|
checkTorrents()
|
|
for range ticker.C {
|
|
checkTorrents()
|
|
}
|
|
}
|
|
|
|
func checkTorrents() {
|
|
fmt.Println("checking torrents")
|
|
start := time.Now()
|
|
|
|
torrents, err := GetLatestNyaaContent()
|
|
if err != nil {
|
|
fmt.Println(adverr.Wrap("retrieving torrents failed", err))
|
|
return
|
|
}
|
|
|
|
animes, err := GetAnimesToDownloadByAnimeID()
|
|
if err != nil {
|
|
fmt.Println(adverr.Wrap("retrieving anime list failed", err))
|
|
return
|
|
}
|
|
|
|
parsedTorrents := ParseTorrentsByAnimeEpSortedByProperties(torrents)
|
|
|
|
for animeEp, torrentPriorities := range parsedTorrents {
|
|
_, animeOnList := animes[animeEp.Anime.ID]
|
|
props, found, err := GetLocalAnimeEpProperties(animeEp)
|
|
episodeInCollection := err == nil && found
|
|
|
|
fmt.Print(FormatFilePriority(animeEp, props, animeOnList, episodeInCollection, len(torrentPriorities)))
|
|
|
|
if !animeOnList {
|
|
continue
|
|
}
|
|
|
|
for _, torrentPriority := range torrentPriorities {
|
|
if TorrentFileDownloading(torrentPriority.ParsedTorrent) {
|
|
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))
|
|
// TODO start download
|
|
}
|
|
} else {
|
|
fmt.Printf("%s | NOT IN COLLECTION | STARTING DOWNLOAD\n", FormatTorrentPriority(torrentPriority))
|
|
// TODO start download
|
|
}
|
|
|
|
// TODO download anime episode with highest priority (first one in slice)
|
|
}
|
|
}
|
|
|
|
// TODO store preferred properties of downloaded torrents in db
|
|
|
|
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
|
|
}
|