From 2367ba3dab31b1d6de0e6432e5b6640797b13808 Mon Sep 17 00:00:00 2001 From: Christian Pointner Date: Fri, 11 Dec 2015 03:57:49 +0100 Subject: curl based importer diff --git a/src/helsinki.at/rhimport/fetcher.go b/src/helsinki.at/rhimport/fetcher.go index ccbca43..05074b1 100644 --- a/src/helsinki.at/rhimport/fetcher.go +++ b/src/helsinki.at/rhimport/fetcher.go @@ -35,14 +35,14 @@ import ( "strings" ) -type CurlCBData struct { +type FetcherCurlCBData struct { basepath string filename string remotename string *os.File } -func (self *CurlCBData) Cleanup() { +func (self *FetcherCurlCBData) Cleanup() { if self.File != nil { self.File.Close() } @@ -50,7 +50,7 @@ func (self *CurlCBData) Cleanup() { func curlHeaderCallback(ptr []byte, userdata interface{}) bool { hdr := fmt.Sprintf("%s", ptr) - data := userdata.(*CurlCBData) + data := userdata.(*FetcherCurlCBData) if strings.HasPrefix(hdr, "Content-Disposition:") { if mediatype, params, err := mime.ParseMediaType(strings.TrimPrefix(hdr, "Content-Disposition:")); err == nil { @@ -63,7 +63,7 @@ func curlHeaderCallback(ptr []byte, userdata interface{}) bool { } func curlWriteCallback(ptr []byte, userdata interface{}) bool { - data := userdata.(*CurlCBData) + data := userdata.(*FetcherCurlCBData) if data.File == nil { if data.filename == "" { data.filename = data.basepath + "/" + data.remotename @@ -86,14 +86,13 @@ func FetchFileCurl(ctx *ImportContext, uri *url.URL) (err error) { rhl.Printf("curl-based fetcher called for '%s'", ctx.SourceUri) easy := curl.EasyInit() - defer easy.Cleanup() - if easy != nil { + defer easy.Cleanup() easy.Setopt(curl.OPT_FOLLOWLOCATION, true) easy.Setopt(curl.OPT_URL, ctx.SourceUri) - cbdata := &CurlCBData{remotename: path.Base(uri.Path)} + cbdata := &FetcherCurlCBData{remotename: path.Base(uri.Path)} defer cbdata.Cleanup() if cbdata.basepath, err = ioutil.TempDir(ctx.Config.TempDir, "rhimportd-"); err != nil { return @@ -118,12 +117,14 @@ func FetchFileCurl(ctx *ImportContext, uri *url.URL) (err error) { if err = easy.Perform(); err != nil { return } - fmt.Printf("\n") ctx.SourceFile = cbdata.filename ctx.DeleteSourceFile = true ctx.DeleteSourceDir = true + } else { + err = fmt.Errorf("Error initializing libcurl") } + return } diff --git a/src/helsinki.at/rhimport/importer.go b/src/helsinki.at/rhimport/importer.go index 8995717..bbe4874 100644 --- a/src/helsinki.at/rhimport/importer.go +++ b/src/helsinki.at/rhimport/importer.go @@ -27,6 +27,7 @@ package rhimport import ( "bytes" "fmt" + "github.com/golang-basic/go-curl" "io" "mime/multipart" "net/http" @@ -114,30 +115,6 @@ func (ctx *ImportContext) getShowInfo() (err error) { return } -func send_post_request(url string, b *bytes.Buffer, contenttype string) (err error) { - var req *http.Request - if req, err = http.NewRequest("POST", url, b); err != nil { - return - } - if contenttype != "" { - req.Header.Set("Content-Type", contenttype) - } - - client := &http.Client{} - var res *http.Response - if res, err = client.Do(req); err != nil { - return - } - defer res.Body.Close() - - if res.StatusCode != http.StatusOK { - // TODO: better error output - err = fmt.Errorf("bad status: %s", res.Status) - } - return -} - - func add_cart(ctx *ImportContext) (err error) { var b bytes.Buffer w := multipart.NewWriter(&b) @@ -206,54 +183,113 @@ func remove_cart(ctx *ImportContext) (err error) { return send_post_request(ctx.Config.RDXportEndpoint, &b, w.FormDataContentType()) } - -func import_audio(ctx *ImportContext) (err error) { - var b bytes.Buffer - w := multipart.NewWriter(&b) - - if err = w.WriteField("COMMAND", "2"); err != nil { +func send_post_request(url string, b *bytes.Buffer, contenttype string) (err error) { + var req *http.Request + if req, err = http.NewRequest("POST", url, b); err != nil { return } - if err = w.WriteField("LOGIN_NAME", ctx.UserName); err != nil { + if contenttype != "" { + req.Header.Set("Content-Type", contenttype) + } + + client := &http.Client{} + var res *http.Response + if res, err = client.Do(req); err != nil { return } - if err = w.WriteField("PASSWORD", ctx.Password); err != nil { + defer res.Body.Close() + + fmt.Printf("Response Code: %d\nBody:\n", res.StatusCode) + io.Copy(os.Stdout, res.Body) + return +} + +func import_audio_create_request(ctx *ImportContext, easy *curl.CURL) (form *curl.Form, err error) { + form = curl.NewForm() + + if err = form.Add("COMMAND", "2"); err != nil { return } - if err = w.WriteField("CART_NUMBER", fmt.Sprintf("%d", ctx.Cart)); err != nil { + if err = form.Add("LOGIN_NAME", ctx.UserName); err != nil { return } - if err = w.WriteField("CUT_NUMBER", fmt.Sprintf("%d", ctx.Cut)); err != nil { + if err = form.Add("PASSWORD", ctx.Password); err != nil { return } - if err = w.WriteField("CHANNELS", fmt.Sprintf("%d", ctx.Channels)); err != nil { + if err = form.Add("CART_NUMBER", fmt.Sprintf("%d", ctx.Cart)); err != nil { return } - if err = w.WriteField("NORMALIZATION_LEVEL", fmt.Sprintf("%d", ctx.NormalizationLevel)); err != nil { + if err = form.Add("CUT_NUMBER", fmt.Sprintf("%d", ctx.Cut)); err != nil { return } - if err = w.WriteField("AUTOTRIM_LEVEL", fmt.Sprintf("%d", ctx.AutotrimLevel)); err != nil { + if err = form.Add("CHANNELS", fmt.Sprintf("%d", ctx.Channels)); err != nil { return } - if err = w.WriteField("USE_METADATA", bool2str[ctx.UseMetaData]); err != nil { + if err = form.Add("NORMALIZATION_LEVEL", fmt.Sprintf("%d", ctx.NormalizationLevel)); err != nil { return } - - var f *os.File - var fw io.Writer - if f, err = os.Open(ctx.SourceFile); err != nil { + if err = form.Add("AUTOTRIM_LEVEL", fmt.Sprintf("%d", ctx.AutotrimLevel)); err != nil { return } - if fw, err = w.CreateFormFile("FILENAME", path.Base(ctx.SourceFile)); err != nil { + if err = form.Add("USE_METADATA", bool2str[ctx.UseMetaData]); err != nil { return } - if _, err = io.Copy(fw, f); err != nil { + if err = form.AddFile("FILENAME", ctx.SourceFile); err != nil { return } - f.Close() - w.Close() - return send_post_request(ctx.Config.RDXportEndpoint, &b, w.FormDataContentType()) + return +} + +func import_audio(ctx *ImportContext) (err error) { + easy := curl.EasyInit() + + if easy != nil { + defer easy.Cleanup() + + easy.Setopt(curl.OPT_URL, ctx.Config.RDXportEndpoint) + easy.Setopt(curl.OPT_POST, true) + + var form *curl.Form + if form, err = import_audio_create_request(ctx, easy); err != nil { + return + } + easy.Setopt(curl.OPT_HTTPPOST, form) + easy.Setopt(curl.OPT_HTTPHEADER, []string{"Expect:"}) + + var resbody bytes.Buffer + easy.Setopt(curl.OPT_WRITEFUNCTION, func(ptr []byte, userdata interface{}) bool { + b := userdata.(*bytes.Buffer) + b.Write(ptr) + return true + }) + easy.Setopt(curl.OPT_WRITEDATA, &resbody) + + easy.Setopt(curl.OPT_NOPROGRESS, false) + easy.Setopt(curl.OPT_PROGRESSFUNCTION, func(dltotal, dlnow, ultotal, ulnow float64, userdata interface{}) bool { + ctx := userdata.(*ImportContext) + if ctx.ProgressCallBack != nil { + ctx.ProgressCallBack(2, "importing", ulnow/ultotal, ctx.ProgressCallBackData) + } + return true + }) + easy.Setopt(curl.OPT_PROGRESSDATA, ctx) + + if err = easy.Perform(); err != nil { + return + } + + var status_code interface{} + if status_code, err = easy.Getinfo(curl.INFO_RESPONSE_CODE); err != nil { + return + } + fmt.Printf("Response Code: %d\nBody:\n", status_code.(int)) + resbody.WriteTo(os.Stdout) + } else { + err = fmt.Errorf("Error initializing libcurl") + } + + return } func cleanup_files(ctx *ImportContext) { -- cgit v0.10.2