torrent download implemented
This commit is contained in:
parent
95f77cf189
commit
17ee4822a9
41
download_torrent_file.go
Normal file
41
download_torrent_file.go
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"git.milar.in/nyaanime/model"
|
||||||
|
)
|
||||||
|
|
||||||
|
func DownloadTorrent(animeEp model.AnimeEpisode, torrent *model.ParsedTorrent) error {
|
||||||
|
if err := SetAnimeEpDownloading(animeEp); err != nil {
|
||||||
|
return ErrLockFileCreationFailed.Wrap(err, animeEp.Anime.Title.Romaji, animeEp.Episode)
|
||||||
|
}
|
||||||
|
|
||||||
|
torrentFilePath := filepath.Join(TorrentPath, path.Base(torrent.Torrent.Link))
|
||||||
|
|
||||||
|
fmt.Printf("download: %s -> %s\n", torrent.Torrent.Link, torrentFilePath)
|
||||||
|
|
||||||
|
resp, err := http.Get(torrent.Torrent.Link)
|
||||||
|
if err != nil {
|
||||||
|
return ErrDownloadTorrentFileFailed.Wrap(err, torrent.Torrent.Link)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
file, err := os.Create(torrentFilePath)
|
||||||
|
if err != nil {
|
||||||
|
return ErrSaveTorrentFileFailed.Wrap(err, torrent.Torrent.Link)
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
|
||||||
|
_, err = io.Copy(file, resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return ErrSaveTorrentFileFailed.Wrap(err, torrent.Torrent.Link)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
@ -14,4 +14,8 @@ var (
|
|||||||
ErrInvalidAnimeStatus = adverr.NewErrTmpl("ErrInvalidAnimeStatus", "invalid status '%s' in ANIME_STATUS (allowed: %s)")
|
ErrInvalidAnimeStatus = adverr.NewErrTmpl("ErrInvalidAnimeStatus", "invalid status '%s' in ANIME_STATUS (allowed: %s)")
|
||||||
ErrInvalidGlobSyntax = adverr.NewErrTmpl("ErrInvalidGlobSyntax", "invalid filepath.Glob syntax: '%s'")
|
ErrInvalidGlobSyntax = adverr.NewErrTmpl("ErrInvalidGlobSyntax", "invalid filepath.Glob syntax: '%s'")
|
||||||
ErrNoSuitableFileFound = adverr.NewErrTmpl("ErrNoSuitableFileFound", "no file found with essential properties for anime '%s' and episode %d")
|
ErrNoSuitableFileFound = adverr.NewErrTmpl("ErrNoSuitableFileFound", "no file found with essential properties for anime '%s' and episode %d")
|
||||||
|
|
||||||
|
ErrDownloadTorrentFileFailed = adverr.NewErrTmpl("ErrDownloadTorrentFileFailed", "torrent file download failed: %s")
|
||||||
|
ErrLockFileCreationFailed = adverr.NewErrTmpl("ErrLockFileCreationFailed", "creation of lock file for anime '%s' and episode %d failed")
|
||||||
|
ErrSaveTorrentFileFailed = adverr.NewErrTmpl("ErrSaveTorrentFileFailed", "torrent file could not be saved: %s")
|
||||||
)
|
)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"errors"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
@ -27,11 +27,11 @@ func GetAnimeEpFilepath(animeEp model.AnimeEpisode, ext string) string {
|
|||||||
if err := AnimeEpFilepathPattern.Execute(b, tmplData); err != nil {
|
if err := AnimeEpFilepathPattern.Execute(b, tmplData); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
return b.String()
|
return filepath.Join(AnimePath, b.String())
|
||||||
}
|
}
|
||||||
|
|
||||||
func AnimeEpExistsLocally(animeEp model.AnimeEpisode) bool {
|
func AnimeEpExistsLocally(animeEp model.AnimeEpisode) bool {
|
||||||
animeEpPath := filepath.Join(AnimePath, GetAnimeEpFilepath(animeEp, "*"))
|
animeEpPath := GetAnimeEpFilepath(animeEp, "*")
|
||||||
|
|
||||||
files, err := filepath.Glob(animeEpPath)
|
files, err := filepath.Glob(animeEpPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -42,7 +42,7 @@ func AnimeEpExistsLocally(animeEp model.AnimeEpisode) bool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetLocalAnimeEpProperties(animeEp model.AnimeEpisode) (*FilePriority, bool, error) {
|
func GetLocalAnimeEpProperties(animeEp model.AnimeEpisode) (*FilePriority, bool, error) {
|
||||||
animeEpPath := filepath.Join(AnimePath, GetAnimeEpFilepath(animeEp, "*"))
|
animeEpPath := GetAnimeEpFilepath(animeEp, "*")
|
||||||
files, err := filepath.Glob(animeEpPath)
|
files, err := filepath.Glob(animeEpPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, false, ErrInvalidGlobSyntax.Wrap(err, animeEpPath)
|
return nil, false, ErrInvalidGlobSyntax.Wrap(err, animeEpPath)
|
||||||
@ -70,18 +70,17 @@ func GetLocalAnimeEpProperties(animeEp model.AnimeEpisode) (*FilePriority, bool,
|
|||||||
return mostPrio, mostPrio != nil, nil
|
return mostPrio, mostPrio != nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO cache?
|
func IsAnimeEpDownloading(animeEp model.AnimeEpisode) bool {
|
||||||
func TorrentFileDownloading(torrent *model.ParsedTorrent) bool {
|
animeEpPath := GetAnimeEpFilepath(animeEp, "lock")
|
||||||
torrentFile := filepath.Join(TorrentPath, fmt.Sprintf("%s.torrent", torrent.Torrent.ID))
|
_, err := os.Stat(animeEpPath)
|
||||||
|
return !errors.Is(err, os.ErrNotExist)
|
||||||
if _, err := os.Stat(torrentFile); err == nil {
|
}
|
||||||
return true
|
|
||||||
}
|
func SetAnimeEpDownloading(animeEp model.AnimeEpisode) error {
|
||||||
|
animeEpPath := GetAnimeEpFilepath(animeEp, "lock")
|
||||||
addedTorrentFile := filepath.Join(TorrentPath, fmt.Sprintf("%s.torrent.added", torrent.Torrent.ID))
|
file, err := os.Create(animeEpPath)
|
||||||
if _, err := os.Stat(addedTorrentFile); err == nil {
|
if err != nil {
|
||||||
return true
|
defer file.Close()
|
||||||
}
|
}
|
||||||
|
return err
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
17
main.go
17
main.go
@ -71,6 +71,7 @@ func main() {
|
|||||||
fmt.Println("subtitle priorites:", Map2Str(PreferredSubtitles))
|
fmt.Println("subtitle priorites:", Map2Str(PreferredSubtitles))
|
||||||
fmt.Println("resolution priorites:", Map2Str(PreferredResolutions))
|
fmt.Println("resolution priorites:", Map2Str(PreferredResolutions))
|
||||||
|
|
||||||
|
// TODO ugly code (see issue nyaanime/downloader#1)
|
||||||
if len(AnimeStatus) == 0 {
|
if len(AnimeStatus) == 0 {
|
||||||
AnimeStatus = []anilist.MediaListStatus{
|
AnimeStatus = []anilist.MediaListStatus{
|
||||||
anilist.MediaListStatusCurrent,
|
anilist.MediaListStatusCurrent,
|
||||||
@ -122,7 +123,9 @@ func checkTorrents() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for _, torrentPriority := range torrentPriorities {
|
for _, torrentPriority := range torrentPriorities {
|
||||||
if TorrentFileDownloading(torrentPriority.ParsedTorrent) {
|
torrent := torrentPriority.ParsedTorrent
|
||||||
|
|
||||||
|
if IsAnimeEpDownloading(animeEp) {
|
||||||
fmt.Printf("%s | CURRENTLY DOWNLOADING\n", FormatTorrentPriority(torrentPriority))
|
fmt.Printf("%s | CURRENTLY DOWNLOADING\n", FormatTorrentPriority(torrentPriority))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
@ -132,19 +135,19 @@ func checkTorrents() {
|
|||||||
fmt.Printf("%s | LOWER PRIORITY\n", FormatTorrentPriority(torrentPriority))
|
fmt.Printf("%s | LOWER PRIORITY\n", FormatTorrentPriority(torrentPriority))
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("%s | HIGHER PRIORITY | STARTING DOWNLOAD\n", FormatTorrentPriority(torrentPriority))
|
fmt.Printf("%s | HIGHER PRIORITY | STARTING DOWNLOAD\n", FormatTorrentPriority(torrentPriority))
|
||||||
// TODO start download
|
if err := DownloadTorrent(animeEp, torrent); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("%s | NOT IN COLLECTION | STARTING DOWNLOAD\n", FormatTorrentPriority(torrentPriority))
|
fmt.Printf("%s | NOT IN COLLECTION | STARTING DOWNLOAD\n", FormatTorrentPriority(torrentPriority))
|
||||||
// TODO start download
|
if err := DownloadTorrent(animeEp, torrent); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO download anime episode with highest priority (first one in slice)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO store preferred properties of downloaded torrents in db
|
|
||||||
|
|
||||||
duration := time.Since(start)
|
duration := time.Since(start)
|
||||||
fmt.Printf("\ncheck took %s. sleeping for %s\n", duration.Truncate(time.Millisecond), (PollRate - duration).Truncate(time.Millisecond))
|
fmt.Printf("\ncheck took %s. sleeping for %s\n", duration.Truncate(time.Millisecond), (PollRate - duration).Truncate(time.Millisecond))
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user