2017-06-17 02:11:46 -07:00
package main
import (
2017-07-16 23:48:06 -07:00
"bufio"
2018-01-06 17:31:50 -08:00
"crypto/tls"
2017-06-17 02:11:46 -07:00
"fmt"
2018-01-06 17:31:50 -08:00
"net/http"
2017-06-20 12:25:19 -07:00
"os"
2017-07-16 23:48:06 -07:00
"os/exec"
2017-08-08 11:07:36 -07:00
"path/filepath"
2018-01-06 17:31:50 -08:00
"sort"
"strconv"
2017-08-08 11:07:36 -07:00
"strings"
2018-01-06 17:31:50 -08:00
"sync"
"time"
"timmy.narnian.us/git/timmy/scene"
2017-06-20 12:25:19 -07:00
"github.com/alexflint/go-arg"
2018-01-06 17:31:50 -08:00
"github.com/lordwelch/transmission"
2017-06-20 12:25:19 -07:00
)
var (
2018-01-06 17:31:50 -08:00
CurrentTorrents map [ string ] SeriesTorrent
unselectedDir string
Transmission * transmission . Client
mutex = new ( sync . Mutex )
args struct {
RES string ` arg:"help:Resolution preference [480/720/1080]" `
RELEASE [ ] string ` arg:"-r,help:Release group preference order." `
NRELEASE [ ] string ` arg:"-R,help:Release groups to use only as a lost resort." `
TAGS [ ] string ` arg:"-t,help:Tags to prefer -t internal would choose an internal over another. Whichever file with the most tags is chosen. Release Group takes priority" `
Series [ ] string ` arg:"required,positional,help:TV series to download torrent file for" `
NEW bool ` arg:"-n,help:Only modify new torrents" `
PATH string ` arg:"-P,required,help:Path to torrent files" `
}
2017-06-17 02:11:46 -07:00
)
func main ( ) {
2017-07-23 23:21:25 -07:00
var (
2018-01-06 17:31:50 -08:00
stdC = make ( chan * SceneVideoTorrent )
2017-07-23 23:21:25 -07:00
)
2018-01-06 17:31:50 -08:00
initialize ( )
go stdinLoop ( stdC )
2017-09-22 17:47:50 -07:00
2018-01-06 17:31:50 -08:00
for {
select {
case <- time . After ( time . Minute * 15 ) :
download ( )
case current := <- stdC :
mutex . Lock ( )
addtorrent ( CurrentTorrents [ current . Title ] , current )
mutex . Unlock ( )
}
2017-09-22 17:47:50 -07:00
}
2018-01-06 17:31:50 -08:00
}
2017-09-22 17:47:50 -07:00
2018-01-06 17:31:50 -08:00
func stdinLoop ( C chan * SceneVideoTorrent ) {
2017-07-22 22:53:12 -07:00
scanner := bufio . NewScanner ( os . Stdin )
2017-08-08 11:07:36 -07:00
for scanner . Scan ( ) {
url := strings . TrimSpace ( scanner . Text ( ) )
2018-01-06 17:31:50 -08:00
torrentName := filepath . Base ( url )
torrentPath := filepath . Join ( unselectedDir , torrentName )
_ , err := os . Stat ( torrentPath )
if ! os . IsNotExist ( err ) {
continue
}
2017-11-30 19:41:28 -08:00
cmd := exec . Command ( "wget" , url , "-q" , "-O" , torrentPath )
2017-11-30 18:38:02 -08:00
cmd . Stdout = os . Stdout
cmd . Stderr = os . Stderr
2018-01-06 17:31:50 -08:00
err = cmd . Run ( )
2017-11-30 18:29:28 -08:00
if err != nil {
2017-08-08 11:07:36 -07:00
fmt . Println ( "url failed: " , url )
2017-11-30 18:29:28 -08:00
fmt . Println ( err )
2017-08-08 11:07:36 -07:00
continue
2017-07-16 23:48:06 -07:00
}
2018-01-06 17:31:50 -08:00
current := process ( torrentPath )
for _ , title := range args . Series {
if current . Title == title {
C <- current
break
}
}
}
}
func download ( ) {
mutex . Lock ( )
defer mutex . Unlock ( )
hash := removeLinks ( )
removeDownloads ( hash )
for _ , s := range CurrentTorrents {
for _ , se := range s {
for _ , ep := range se {
fmt . Println ( "symlink" , ep . Ep [ 0 ] . Title , ep . Ep [ 0 ] . Season , ep . Ep [ 0 ] . Episode )
os . Symlink ( ep . Ep [ 0 ] . Meta . FilePath , filepath . Join ( filepath . Join ( ep . Ep [ 0 ] . Meta . FilePath , "../../" ) , filepath . Base ( ep . Ep [ 0 ] . Meta . FilePath ) ) )
}
}
}
}
func addtorrent ( St SeriesTorrent , torrent * SceneVideoTorrent ) {
_ , ok := St [ torrent . Season ]
if ! ok {
St [ torrent . Season ] = make ( SeasonTorrent , 20 )
}
Ep := St [ torrent . Season ] [ torrent . Episode ]
if Ep == nil {
RES , _ := strconv . Atoi ( args . RES )
St [ torrent . Season ] [ torrent . Episode ] = & EpisodeTorrent {
Tags : make ( map [ string ] int ) ,
Release : make ( map [ string ] int ) ,
Res : scene . Res ( RES ) ,
}
for i , v := range args . RELEASE {
if i + 1 == 0 {
panic ( "You do not exist in a world that I know of" )
}
St [ torrent . Season ] [ torrent . Episode ] . Release [ v ] = i + 1
}
for i , v := range args . NRELEASE {
if i + 1 == 0 {
panic ( "You do not exist in a world that I know of" )
}
St [ torrent . Season ] [ torrent . Episode ] . Release [ v ] = i + 1000000
}
for i , v := range args . TAGS {
if i + 1 == 0 {
panic ( "You do not exist in a world that I know of" )
}
St [ torrent . Season ] [ torrent . Episode ] . Tags [ v ] = i + 1
}
2017-07-16 23:48:06 -07:00
}
2018-01-06 17:31:50 -08:00
St [ torrent . Season ] [ torrent . Episode ] . Add ( torrent )
}
// Get hashes of torrents that were previously selected then remove the link to them
func removeLinks ( ) ( hash [ ] string ) {
selectedDir := filepath . Join ( unselectedDir , "../" )
selectedFolder , _ := os . Open ( selectedDir )
//fmt.Println("selected dir", selectedDir)
defer selectedFolder . Close ( )
selectedNames , _ := selectedFolder . Readdirnames ( 0 )
for _ , lnk := range selectedNames {
target , err := os . Readlink ( filepath . Join ( selectedDir , lnk ) )
//fmt.Println(target)
//fmt.Println(err)
if err == nil {
if filepath . Base ( filepath . Dir ( target ) ) == "unselected" {
hash = append ( hash , process ( target ) . Meta . Hash )
os . Remove ( filepath . Join ( selectedDir , lnk ) )
}
}
}
selectedNames , _ = selectedFolder . Readdirnames ( 0 )
fmt . Println ( selectedNames )
return
}
func removeDownloads ( hash [ ] string ) {
tmap , err := Transmission . GetTorrentMap ( )
if err != nil {
panic ( err )
}
2018-01-06 17:39:56 -08:00
thash := make ( [ ] * transmission . Torrent , len ( hash ) )
2018-01-06 17:31:50 -08:00
// Removes torrents from transmission that are not selected this time
for _ , CHash := range hash {
v , ok := tmap [ CHash ]
if ok {
current := scene . Parse ( v . Name )
if CurrentTorrents [ current . Title ] [ current . Season ] [ current . Episode ] . Ep [ 0 ] . Meta . Hash != CHash {
thash = append ( thash , v )
}
}
}
Transmission . RemoveTorrents ( false , thash ... )
}
func initialize ( ) {
var (
err error
)
args . PATH , _ = os . Getwd ( )
args . RES = "-1"
arg . MustParse ( & args )
CurrentTorrents = make ( map [ string ] SeriesTorrent , len ( args . Series ) )
for _ , title := range args . Series {
fmt . Println ( title )
CurrentTorrents [ title ] = make ( SeriesTorrent , 10 )
}
unselectedDir , _ = filepath . Abs ( filepath . Join ( args . PATH , "unselected/" ) )
//fmt.Println("unselected dir:", unselectedDir)
// Load all downloaded torrents
unselectedFolder , _ := os . Open ( unselectedDir )
defer unselectedFolder . Close ( )
unselectedNames , _ := unselectedFolder . Readdirnames ( 0 )
sort . Strings ( unselectedNames )
for _ , name := range unselectedNames {
current := process ( filepath . Join ( unselectedDir , name ) )
for _ , title := range args . Series {
if current . Title == title {
addtorrent ( CurrentTorrents [ title ] , current )
break
}
}
}
Transmission , err = transmission . New ( transmission . Config {
Address : "http://timmy:9091/transmission/rpc" ,
HTTPClient : & http . Client {
Transport : & http . Transport {
TLSClientConfig : & tls . Config {
InsecureSkipVerify : true ,
} ,
} ,
} ,
} )
if err != nil {
panic ( err )
}
download ( )
2017-06-20 12:25:19 -07:00
}
2017-09-27 13:17:58 -07:00
func process ( torrentFile string ) * SceneVideoTorrent {
2017-06-20 12:25:19 -07:00
var (
2018-01-06 17:31:50 -08:00
mt = new ( MetaTorrent )
vt = new ( SceneVideoTorrent )
2017-06-20 12:25:19 -07:00
)
2018-01-06 17:31:50 -08:00
2017-11-30 20:40:41 -08:00
f , _ := os . OpenFile ( torrentFile , os . O_RDONLY , 755 )
2018-01-06 17:31:50 -08:00
defer f . Close ( )
2017-11-30 20:40:41 -08:00
mt . ReadFile ( f )
2017-06-20 12:25:19 -07:00
vt . Torrent = NewTorrent ( * mt )
2018-01-06 17:31:50 -08:00
vt . Parse ( strings . TrimSuffix ( vt . Name , filepath . Ext ( vt . Name ) ) )
//fmt.Println(vt.Original)
fmt . Println ( vt . Title )
2017-06-20 12:25:19 -07:00
return vt
2017-06-17 02:11:46 -07:00
}