realdebrid-torrent/main.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
}
}