diff options
Diffstat (limited to 'rhimport/fetcher.go')
-rw-r--r-- | rhimport/fetcher.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/rhimport/fetcher.go b/rhimport/fetcher.go index 469d36b..3933105 100644 --- a/rhimport/fetcher.go +++ b/rhimport/fetcher.go @@ -25,6 +25,7 @@ package rhimport import ( + "bytes" "fmt" "io" "io/ioutil" @@ -32,6 +33,7 @@ import ( "net/http" "net/url" "os" + "os/exec" "os/user" "path" "path/filepath" @@ -134,9 +136,51 @@ func curlProgressCallback(dltotal, dlnow, ultotal, ulnow float64, userdata inter return true } +func checkYoutubeDL(ctx *Context, res *Result, uri *url.URL) *YoutubeDLInfo { + cmd := exec.Command("youtube-dl", "--no-playlist", "-f", "bestaudio/best", "--prefer-free-formats", "-J", ctx.SourceUri) + var stderr, stdout bytes.Buffer + cmd.Stdout = &stdout + cmd.Stderr = &stderr + + done := make(chan *YoutubeDLInfo) + go func() { + defer func() { + done <- nil + }() + if err := cmd.Run(); err != nil { + rhdl.Printf("youtube-dl: %v, stderr: %s", err, strings.TrimSpace(stderr.String())) + return + } + info, err := NewYoutubeDLInfoFromJSON(&stdout) + if err != nil { + rhdl.Printf("youtube-dl: %v, stderr: %s", err, strings.TrimSpace(stderr.String())) + return + } + rhl.Printf("youtube-dl: extractor: %s -> %s", info.Extractor, info.URL) + ctx.SourceUri = info.URL + done <- info + }() + + select { + case info := <-done: + return info + case <-ctx.Cancel: + cmd.Process.Kill() + res.ResponseCode = http.StatusNoContent + res.ErrorString = "canceled" + return nil + } +} + func fetchFileCurl(ctx *Context, res *Result, uri *url.URL) (err error) { rhl.Printf("curl-based fetcher called for '%s'", ctx.SourceUri) + info := checkYoutubeDL(ctx, res, uri) + if res.ResponseCode == http.StatusNoContent { + rhl.Printf("download of '%s' got canceled", ctx.SourceUri) + return nil + } + easy := curl.EasyInit() if easy == nil { err = fmt.Errorf("Error initializing libcurl") @@ -148,10 +192,28 @@ func fetchFileCurl(ctx *Context, res *Result, uri *url.URL) (err error) { easy.Setopt(curl.OPT_URL, ctx.SourceUri) easy.Setopt(curl.OPT_USERAGENT, "Radio Helsinki Import") + if info != nil && (info.Protocol == "http" || info.Protocol == "https") { + if len(info.HTTPHeaders) > 0 { + var h []string + for key, value := range info.HTTPHeaders { + h = append(h, key+": "+value) + } + easy.Setopt(curl.OPT_HTTPHEADER, h) + rhdl.Printf("added HTTP header: %q", h) + } + } + cbdata := &FetcherCurlCBData{ctx: ctx, res: res, remotename: path.Base(uri.Path)} if cbdata.basepath, err = ioutil.TempDir(ctx.conf.TempDir, "rhimportd-"); err != nil { return } + if info != nil { + if info.Title == "" { + cbdata.remotename = info.ID + "." + info.Ext + } else { + cbdata.remotename = info.Title + "." + info.Ext + } + } easy.Setopt(curl.OPT_HEADERFUNCTION, curlHeaderCallback) easy.Setopt(curl.OPT_HEADERDATA, cbdata) |