177 lines
3.0 KiB
Go
177 lines
3.0 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"flag"
|
|
"git.lumen.sh/shyim/realdebrid-torrent/realdebrid"
|
|
"github.com/fsnotify/fsnotify"
|
|
"log"
|
|
"os"
|
|
"path/filepath"
|
|
"time"
|
|
)
|
|
|
|
var client realdebrid.Client
|
|
|
|
func main() {
|
|
flag.Parse()
|
|
|
|
client = realdebrid.Client{
|
|
Token: os.Getenv("R_TOKEN"),
|
|
}
|
|
|
|
watcher, err := fsnotify.NewWatcher()
|
|
if err != nil {
|
|
panic(watcher)
|
|
}
|
|
|
|
defer watcher.Close()
|
|
|
|
go watchFiles(watcher)
|
|
|
|
if len(flag.Args()) == 0 {
|
|
log.Fatal("no files specified")
|
|
}
|
|
|
|
for _, file := range flag.Args() {
|
|
err = watcher.Add(file)
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
|
|
log.Println("watching", file)
|
|
}
|
|
|
|
<-make(chan struct{})
|
|
}
|
|
|
|
func watchFiles(watcher *fsnotify.Watcher) {
|
|
for {
|
|
select {
|
|
case event, ok := <-watcher.Events:
|
|
if !ok {
|
|
return
|
|
}
|
|
|
|
if event.Has(fsnotify.Create) {
|
|
if filepath.Ext(event.Name) == ".torrent" {
|
|
go handleTorrent(event.Name)
|
|
} else if filepath.Ext(event.Name) == ".magnet" {
|
|
go handleMagnet(event.Name)
|
|
}
|
|
}
|
|
case err, ok := <-watcher.Errors:
|
|
if !ok {
|
|
return
|
|
}
|
|
log.Println("error:", err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func handleTorrent(name string) {
|
|
ctx := context.Background()
|
|
|
|
file, err := os.ReadFile(name)
|
|
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
|
|
id, err := client.AddTorrent(ctx, file)
|
|
|
|
if err != nil {
|
|
log.Printf("error adding torrent: %s", err)
|
|
return
|
|
}
|
|
|
|
log.Printf("added torrent %s", id)
|
|
|
|
handleTorrentDownload(ctx, id)
|
|
}
|
|
|
|
func handleMagnet(name string) {
|
|
ctx := context.Background()
|
|
|
|
file, err := os.ReadFile(name)
|
|
|
|
if err != nil {
|
|
log.Println(err)
|
|
return
|
|
}
|
|
|
|
id, err := client.AddMagnet(ctx, string(file))
|
|
|
|
if err != nil {
|
|
log.Printf("error adding magnet: %s", err)
|
|
return
|
|
}
|
|
|
|
log.Printf("added magnet %s", id)
|
|
|
|
handleTorrentDownload(ctx, id)
|
|
}
|
|
|
|
func handleTorrentDownload(ctx context.Context, id string) {
|
|
var err error
|
|
|
|
if err := client.SelectFiles(ctx, id); err != nil {
|
|
log.Printf("error selecting files: %s", err)
|
|
return
|
|
}
|
|
|
|
log.Printf("selected files for torrent %s", id)
|
|
|
|
var status *realdebrid.TorrentStatus
|
|
|
|
for {
|
|
status, err = client.StatusTorrent(ctx, id)
|
|
|
|
if err != nil {
|
|
log.Printf("error getting status: %s", err)
|
|
return
|
|
}
|
|
|
|
if status.IsDone() {
|
|
break
|
|
}
|
|
|
|
if status.IsError() {
|
|
log.Printf("error downloading torrent %s: %s", id, status.Status)
|
|
|
|
if err := client.DeleteTorrent(ctx, id); err != nil {
|
|
log.Printf("error deleting torrent: %s", err)
|
|
}
|
|
return
|
|
}
|
|
|
|
log.Printf("still downloading torrent %s, progress %d", status.FileName, status.Progress)
|
|
|
|
time.Sleep(30 * time.Second)
|
|
}
|
|
|
|
log.Printf("finished downloading torrent %s", id)
|
|
|
|
downloadLink, err := client.UnrestrictLink(ctx, status.Links[0])
|
|
|
|
if err != nil {
|
|
log.Printf("error getting download link: %s", err)
|
|
return
|
|
}
|
|
|
|
log.Printf("got download link %s", downloadLink)
|
|
|
|
if err := downloadFile(downloadLink, status.FileName); err != nil {
|
|
log.Printf("error downloading file: %s", err)
|
|
return
|
|
}
|
|
|
|
log.Printf("downloaded file %s", status.FileName)
|
|
|
|
if err := client.DeleteTorrent(ctx, id); err != nil {
|
|
log.Printf("error deleting torrent: %s", err)
|
|
return
|
|
}
|
|
}
|