diff --git a/.gitignore b/.gitignore index 529a74e..3ee331e 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,5 @@ -.direnv +.direnv/ +vids/ config.toml subs-opml.xml +subsyt diff --git a/internal/config/config.go b/internal/config/config.go new file mode 100644 index 0000000..7ba3972 --- /dev/null +++ b/internal/config/config.go @@ -0,0 +1,36 @@ +package config + +import ( + "os" + + toml "github.com/pelletier/go-toml/v2" +) + +type Provider struct { + Url string + Throttle int + Video_items int + After_date string +} + +type Config struct { + Out_dir string + Provider map[string]Provider + Dry_run bool +} + +func Load(filepath string) (Config, error) { + data, err := os.ReadFile(filepath) + if err != nil { + panic(err) + } + + cfg := Config{} + + err = toml.Unmarshal(data, &cfg) + if err != nil { + panic(err) + } + + return cfg, err +} diff --git a/internal/dl/dl.go b/internal/dl/dl.go index 09ef0e6..2adbe56 100644 --- a/internal/dl/dl.go +++ b/internal/dl/dl.go @@ -6,37 +6,60 @@ import ( "net/url" "os/exec" "path/filepath" + "strconv" + "strings" "sync" + + "git.meatbag.se/varl/subsyt/internal/config" ) type Download struct { - Url *url.URL - OutDir string - AfterDate string - Name string + Url string + OutDir string + Name string + DryRun bool } -func Get(d Download) { +func Get(d Download, p config.Provider) { output := filepath.Join("%(upload_date>%Y)s/%(upload_date)s-%(title)s-%(id)s.%(ext)s") archive := filepath.Join(d.OutDir, d.Name, "archive.txt") outdir := filepath.Join(d.OutDir, d.Name) + curl := strings.TrimPrefix(d.Url, "/feed/") + furl, err := url.JoinPath(p.Url, curl, "videos") + if err != nil { + panic(err) + } + + fullUrl, err := url.Parse(furl) + if err != nil { + panic(err) + } + + var simulate string + if d.DryRun == true { + simulate = "--simulate" + log.Printf("/!\\ DRY RUN ENABLED /!\\") + } else { + simulate = "--no-simulate" + } + cmd := exec.Command("yt-dlp", - d.Url.String(), - "--no-simulate", + fullUrl.String(), + simulate, "--no-progress", - "--sleep-interval", "1", - "--sleep-subtitles", "3", - "--sleep-requests", "1", + "--sleep-interval", strconv.Itoa(p.Throttle), + "--sleep-subtitles", strconv.Itoa(p.Throttle), + "--sleep-requests", strconv.Itoa(p.Throttle), "--prefer-free-formats", "--write-subs", "--no-write-automatic-subs", "--sub-langs", "en", - "--dateafter", d.AfterDate, "--paths", outdir, "--output", output, "--download-archive", archive, "--break-on-existing", + "--playlist-items", strconv.Itoa(p.Video_items), "--restrict-filenames", ) @@ -44,6 +67,7 @@ func Get(d Download) { if err != nil { log.Fatal(err) } + stderr, err := cmd.StderrPipe() if err != nil { log.Fatal(err) diff --git a/internal/opml/opml.go b/internal/opml/opml.go index 792431c..cb27ab3 100644 --- a/internal/opml/opml.go +++ b/internal/opml/opml.go @@ -22,7 +22,7 @@ type OPML struct { Body `xml:"opml>body"` } -func Unmarshal(path string) OPML { +func Load(path string) (OPML, error) { data, err := os.ReadFile(path) if err != nil { @@ -31,7 +31,10 @@ func Unmarshal(path string) OPML { opml := OPML{} - xml.Unmarshal(data, &opml) + err = xml.Unmarshal(data, &opml) + if err != nil { + panic(err) + } - return opml + return opml, err } diff --git a/main.go b/main.go index 7149d48..90d2304 100644 --- a/main.go +++ b/main.go @@ -1,68 +1,36 @@ package main import ( - "fmt" - "net/url" - "os" - "strings" + "log" + "git.meatbag.se/varl/subsyt/internal/config" "git.meatbag.se/varl/subsyt/internal/dl" "git.meatbag.se/varl/subsyt/internal/opml" - toml "github.com/pelletier/go-toml/v2" ) -type Provider struct { - Url string -} - -type Config struct { - Out_dir string - Provider map[string]Provider -} - func main() { - data, err := os.ReadFile("./config.toml") + cfg, err := config.Load("./config.toml") if err != nil { panic(err) } - cfg := Config{} - - err = toml.Unmarshal(data, &cfg) + opml, err := opml.Load("./subs-opml.xml") if err != nil { panic(err) } - pUrl := cfg.Provider["youtube"].Url - - fmt.Printf("provider url: %s", pUrl) - - opml := opml.Unmarshal("./subs-opml.xml") - - fmt.Printf("XMLName: %#v\n", opml.XMLName) + provider := cfg.Provider["youtube"] for _, outlines := range opml.Body.Outline { - fmt.Printf("%s\n", outlines.Title) + log.Printf("Archiving videos from OPML: %s", outlines.Title) for _, outline := range outlines.Outlines { - curl := strings.TrimPrefix(outline.XmlUrl, "/feed/") - furl, err := url.JoinPath(pUrl, curl) - if err != nil { - panic(err) - } - - fmt.Printf("%s - %s\n", outline.Text, furl) - fullUrl, err := url.Parse(furl) - if err != nil { - panic(err) - } - dl.Get(dl.Download{ - Name: outline.Title, - Url: fullUrl, - OutDir: cfg.Out_dir, - AfterDate: "20250326", - }) + Url: outline.XmlUrl, + Name: outline.Title, + OutDir: cfg.Out_dir, + DryRun: cfg.Dry_run, + }, provider) } } }