diff options
-rw-r--r-- | src/helsinki.at/rhimport/importer.go | 191 | ||||
-rw-r--r-- | src/helsinki.at/rhimport/rddb.go | 15 | ||||
-rw-r--r-- | src/helsinki.at/rhimportd/ctrlWebSimple.go | 17 | ||||
-rw-r--r-- | test/simple1.json | 1 | ||||
-rw-r--r-- | test/simple2.json | 1 | ||||
-rw-r--r-- | test/simple3.json | 1 | ||||
-rw-r--r-- | test/simple4.json | 1 | ||||
-rw-r--r-- | test/simple5.json | 1 |
8 files changed, 144 insertions, 84 deletions
diff --git a/src/helsinki.at/rhimport/importer.go b/src/helsinki.at/rhimport/importer.go index 61c2b64..925722e 100644 --- a/src/helsinki.at/rhimport/importer.go +++ b/src/helsinki.at/rhimport/importer.go @@ -45,7 +45,7 @@ type ImportContext struct { UserName string Password string Trusted bool - ShowId int + ShowId uint ClearShowCarts bool GroupName string Cart uint @@ -144,7 +144,7 @@ func (ctx *ImportContext) getGroupOfCart() error { return nil } -func (ctx *ImportContext) getShowInfo() (err error) { +func (ctx *ImportContext) getShowInfo() (carts []uint, err error) { req := getShowInfoRequest{} req.showid = ctx.ShowId req.response = make(chan getShowInfoResult) @@ -155,12 +155,11 @@ func (ctx *ImportContext) getShowInfo() (err error) { err = res.err return } - - rhdl.Printf("Show %d:\n", ctx.ShowId) - rhdl.Printf(" Title: '%s'\n", res.title) - rhdl.Printf(" Normalization Level: %d\n", res.norm_lvl) - rhdl.Printf(" Autotrim Level: %d\n", res.trim_lvl) - rhdl.Printf(" Carts: %v\n", res.carts) + ctx.GroupName = res.group + ctx.NormalizationLevel = res.norm_lvl + ctx.AutotrimLevel = res.trim_lvl + ctx.UseMetaData = true + carts = res.carts return } @@ -189,6 +188,7 @@ func (ctx *ImportContext) getMusicInfo() (err error) { } ctx.NormalizationLevel = res.norm_lvl ctx.AutotrimLevel = res.trim_lvl + ctx.UseMetaData = true return } @@ -203,11 +203,11 @@ func (self *ImportResult) fromRDWebResult(rdres *RDWebResult) { self.ResponseCode = rdres.ResponseCode self.ErrorString = rdres.ErrorString if rdres.AudioConvertError != 0 { - self.ErrorString += fmt.Sprint(", Audio Convert Error: %d", rdres.AudioConvertError) + self.ErrorString += fmt.Sprintf(", Audio Convert Error: %d", rdres.AudioConvertError) } } -func add_cart(ctx *ImportContext, result *ImportResult) (err error) { +func add_cart(ctx *ImportContext, res *ImportResult) (err error) { var b bytes.Buffer w := multipart.NewWriter(&b) @@ -220,7 +220,7 @@ func add_cart(ctx *ImportContext, result *ImportResult) (err error) { if err = w.WriteField("PASSWORD", ctx.Password); err != nil { return } - if err = w.WriteField("GRPOUP_NAME", ctx.GroupName); err != nil { + if err = w.WriteField("GROUP_NAME", ctx.GroupName); err != nil { return } if err = w.WriteField("TYPE", "audio"); err != nil { @@ -233,32 +233,32 @@ func add_cart(ctx *ImportContext, result *ImportResult) (err error) { } w.Close() - var res *http.Response - if res, err = send_post_request(ctx.Config.RDXportEndpoint, &b, w.FormDataContentType()); err != nil { + var resp *http.Response + if resp, err = send_post_request(ctx.Config.RDXportEndpoint, &b, w.FormDataContentType()); err != nil { return } - defer res.Body.Close() + defer resp.Body.Close() - if res.StatusCode != http.StatusOK { + if resp.StatusCode != http.StatusOK { var rdres *RDWebResult - if rdres, err = NewRDWebResultFromXML(res.Body); err != nil { + if rdres, err = NewRDWebResultFromXML(resp.Body); err != nil { return } - result.fromRDWebResult(rdres) + res.fromRDWebResult(rdres) return } var cartadd *RDCartAdd - if cartadd, err = NewRDCartAddFromXML(res.Body); err != nil { + if cartadd, err = NewRDCartAddFromXML(resp.Body); err != nil { return } - result.ResponseCode = res.StatusCode - result.ErrorString = "OK" - result.Cart = cartadd.Carts[0].Number - ctx.Cart = result.Cart + res.ResponseCode = resp.StatusCode + res.ErrorString = "OK" + res.Cart = cartadd.Carts[0].Number + ctx.Cart = res.Cart return } -func add_cut(ctx *ImportContext, result *ImportResult) (err error) { +func add_cut(ctx *ImportContext, res *ImportResult) (err error) { var b bytes.Buffer w := multipart.NewWriter(&b) @@ -276,32 +276,32 @@ func add_cut(ctx *ImportContext, result *ImportResult) (err error) { } w.Close() - var res *http.Response - if res, err = send_post_request(ctx.Config.RDXportEndpoint, &b, w.FormDataContentType()); err != nil { + var resp *http.Response + if resp, err = send_post_request(ctx.Config.RDXportEndpoint, &b, w.FormDataContentType()); err != nil { return } - defer res.Body.Close() + defer resp.Body.Close() - if res.StatusCode != http.StatusOK { + if resp.StatusCode != http.StatusOK { var rdres *RDWebResult - if rdres, err = NewRDWebResultFromXML(res.Body); err != nil { + if rdres, err = NewRDWebResultFromXML(resp.Body); err != nil { return } - result.fromRDWebResult(rdres) + res.fromRDWebResult(rdres) return } var cutadd *RDCutAdd - if cutadd, err = NewRDCutAddFromXML(res.Body); err != nil { + if cutadd, err = NewRDCutAddFromXML(resp.Body); err != nil { return } - result.ResponseCode = res.StatusCode - result.ErrorString = "OK" - result.Cut = cutadd.Cuts[0].Number + res.ResponseCode = resp.StatusCode + res.ErrorString = "OK" + res.Cut = cutadd.Cuts[0].Number ctx.Cut = cutadd.Cuts[0].Number return } -func remove_cart(ctx *ImportContext, result *ImportResult) (err error) { +func remove_cart(ctx *ImportContext, res *ImportResult) (err error) { var b bytes.Buffer w := multipart.NewWriter(&b) @@ -319,17 +319,17 @@ func remove_cart(ctx *ImportContext, result *ImportResult) (err error) { } w.Close() - var res *http.Response - if res, err = send_post_request(ctx.Config.RDXportEndpoint, &b, w.FormDataContentType()); err != nil { + var resp *http.Response + if resp, err = send_post_request(ctx.Config.RDXportEndpoint, &b, w.FormDataContentType()); err != nil { return } - defer res.Body.Close() + defer resp.Body.Close() var rdres *RDWebResult - if rdres, err = NewRDWebResultFromXML(res.Body); err != nil { + if rdres, err = NewRDWebResultFromXML(resp.Body); err != nil { return } - result.fromRDWebResult(rdres) + res.fromRDWebResult(rdres) return } @@ -438,6 +438,61 @@ func import_audio(ctx *ImportContext, result *ImportResult) (err error) { return } +func remove_add_cart_cut(ctx *ImportContext, res *ImportResult) (err error) { + if err = remove_cart(ctx, res); err != nil || (res.ResponseCode != http.StatusOK && res.ResponseCode != http.StatusNotFound) { + return + } + if err = add_cart(ctx, res); err != nil || res.ResponseCode != http.StatusOK { + return + } + return add_cut(ctx, res) +} + +func is_cart_member_of_show(ctx *ImportContext, res *ImportResult, carts []uint) (found bool) { + if ctx.Cart == 0 { + return true + } + for _, cart := range carts { + if cart == ctx.Cart { + return true + } + } + res.ResponseCode = http.StatusBadRequest + res.ErrorString = fmt.Sprintf("Requested cart %d is not a member of show: %d", ctx.Cart, ctx.ShowId) + return false +} + +func clear_show_carts(ctx *ImportContext, res *ImportResult, carts []uint) (err error) { + if ctx.ClearShowCarts { + orig_cart := ctx.Cart + for _, cart := range carts { + ctx.Cart = cart + if err = remove_cart(ctx, res); err != nil || (res.ResponseCode != http.StatusOK && res.ResponseCode != http.StatusNotFound) { + return + } + } + ctx.Cart = orig_cart + } + return +} + +func add_show_cart_cut(ctx *ImportContext, res *ImportResult, carts []uint) (err error) { + if err = add_cart(ctx, res); err != nil || res.ResponseCode != http.StatusOK { + return + } + for _, cart := range carts { + if cart == ctx.Cart { + return add_cut(ctx, res) + } + } + if err = remove_cart(ctx, res); err != nil || res.ResponseCode != http.StatusOK { + return + } + res.ResponseCode = http.StatusForbidden + res.ErrorString = fmt.Sprintf("Show %d has no free carts left", ctx.ShowId) + return +} + func cleanup_files(ctx *ImportContext) { if ctx.DeleteSourceFile { rhdl.Printf("importer: removing file: %s", ctx.SourceFile) @@ -457,7 +512,6 @@ func cleanup_files(ctx *ImportContext) { } func ImportFile(ctx *ImportContext) (res *ImportResult, err error) { - rhl.Println("ImportFile called for", ctx.SourceFile) defer cleanup_files(ctx) if ctx.ProgressCallBack != nil { @@ -470,32 +524,35 @@ func ImportFile(ctx *ImportContext) (res *ImportResult, err error) { } } - res = &ImportResult{} + res = &ImportResult{ResponseCode: http.StatusOK} if ctx.ShowId != 0 { - res.ResponseCode = 500 - res.ErrorString = "Importing to shows using the show-id is not yet implemented" - // TODO: fetch info from dropboxes (cartlist, groupname, import-params) - // - if (ctx.Cart not in cartlist) -> Error - // - if (ClearShowCarts == true): foreach(cart in cartlist): remove_cart(cart) [200 || 404 -> OK] - // - add_cart(ctx, res) [200 -> OK] - // - add_cut(ctx, res) [200 -> OK] - return + var show_carts []uint + if show_carts, err = ctx.getShowInfo(); err != nil { + return + } + if !is_cart_member_of_show(ctx, res, show_carts) { + return + } + if err = clear_show_carts(ctx, res, show_carts); err != nil || (res.ResponseCode != http.StatusOK && res.ResponseCode != http.StatusNotFound) { + return + } + if err = add_show_cart_cut(ctx, res, show_carts); err != nil || res.ResponseCode != http.StatusOK { + return + } } else if ctx.GroupName != "" { - res.ResponseCode = 500 - res.ErrorString = "Importing to music pools is not yet implemented" - // TODO: fetch info from dropboxes (import-params) - // - add_cart(ctx, res) [200 -> OK] - // - add_cut(ctx, res) [200 -> OK] - return - } else if ctx.Cart != 0 && ctx.Cut == 0 { - res.ResponseCode = 500 - res.ErrorString = "Importing to a Cart which might not exist is not yet implemented" - // TODO: (everything except Cut, GroupName and ShowId must be in context) - // - ctx.getGroupOfCart(ctx.Cart) - // - remove_cart(ctx, res) [200 || 404 -> OK] - // - add_cart(ctx, res) [200 -> OK] - // - add_cut(ctx, res) [200 -> OK] - return + if err = ctx.getMusicInfo(); err != nil { + return + } + if err = remove_add_cart_cut(ctx, res); err != nil || res.ResponseCode != http.StatusOK { + return + } + } else if ctx.Cart != 0 && ctx.Cut == 0 { // TODO: we should add a DeleteCart option... + if err = ctx.getGroupOfCart(); err != nil { + return + } + if err = remove_add_cart_cut(ctx, res); err != nil || res.ResponseCode != http.StatusOK { + return + } } if ctx.Cart != 0 && ctx.Cut != 0 { @@ -510,11 +567,5 @@ func ImportFile(ctx *ImportContext) (res *ImportResult, err error) { } rhdl.Printf("ImportResult: %+v\n", res) - - if res.ResponseCode == http.StatusOK { - rhl.Println("ImportFile succesfully imported", ctx.SourceFile) - } else { - rhl.Println("ImportFile import of", ctx.SourceFile, "was unsuccesful") - } return } diff --git a/src/helsinki.at/rhimport/rddb.go b/src/helsinki.at/rhimport/rddb.go index 0a9e21e..b693c47 100644 --- a/src/helsinki.at/rhimport/rddb.go +++ b/src/helsinki.at/rhimport/rddb.go @@ -63,14 +63,15 @@ type getGroupOfCartRequest struct { type getShowInfoResult struct { title string - carts []int + group string + carts []uint norm_lvl int trim_lvl int err error } type getShowInfoRequest struct { - showid int + showid uint response chan getShowInfoResult } @@ -135,7 +136,7 @@ func (self *RdDb) init(conf *Config) (err error) { if self.getGroupOfCartStmt, err = self.dbh.Prepare("select NAME,DEFAULT_LOW_CART,DEFAULT_HIGH_CART from GROUPS where DEFAULT_LOW_CART <= ? and DEFAULT_HIGH_CART >= ?;"); err != nil { return } - if self.getShowInfoStmt, err = self.dbh.Prepare("select CART.TITLE,CART.MACROS,DROPBOXES.NORMALIZATION_LEVEL,DROPBOXES.AUTOTRIM_LEVEL,GROUPS.DEFAULT_LOW_CART,GROUPS.DEFAULT_HIGH_CART from CART, DROPBOXES, GROUPS where CART.NUMBER = DROPBOXES.TO_CART and GROUPS.NAME = DROPBOXES.GROUP_NAME and CART.NUMBER = ?;"); err != nil { + if self.getShowInfoStmt, err = self.dbh.Prepare("select CART.TITLE,CART.MACROS,DROPBOXES.GROUP_NAME,DROPBOXES.NORMALIZATION_LEVEL,DROPBOXES.AUTOTRIM_LEVEL,GROUPS.DEFAULT_LOW_CART,GROUPS.DEFAULT_HIGH_CART from CART, DROPBOXES, GROUPS where CART.NUMBER = DROPBOXES.TO_CART and GROUPS.NAME = DROPBOXES.GROUP_NAME and CART.NUMBER = ?;"); err != nil { return } if self.checkMusicGroupStmt, err = self.dbh.Prepare("select count(*) from DROPBOXES where GROUP_NAME = ? and SET_USER_DEFINED like \"M;%\";"); err != nil { @@ -199,7 +200,7 @@ func (self *RdDb) getLogTableName(log string) string { return strings.Replace(log, " ", "_", -1) + "_LOG" // TODO: this should get escaped for mySQL but golang doesn't support it!!! } -func (self *RdDb) getShowCarts(log string, low_cart, high_cart int) (carts []int, err error) { +func (self *RdDb) getShowCarts(log string, low_cart, high_cart int) (carts []uint, err error) { q := fmt.Sprintf("select CART_NUMBER from %s where CART_NUMBER >= %d and CART_NUMBER <= %d order by COUNT;", self.getLogTableName(log), low_cart, high_cart) var rows *sql.Rows if rows, err = self.dbh.Query(q); err != nil { @@ -207,7 +208,7 @@ func (self *RdDb) getShowCarts(log string, low_cart, high_cart int) (carts []int } defer rows.Close() for rows.Next() { - var cart int + var cart uint if err = rows.Scan(&cart); err != nil { return } @@ -217,10 +218,10 @@ func (self *RdDb) getShowCarts(log string, low_cart, high_cart int) (carts []int return } -func (self *RdDb) getShowInfo(showid int) (result getShowInfoResult) { +func (self *RdDb) getShowInfo(showid uint) (result getShowInfoResult) { var macros string var low_cart, high_cart int - result.err = self.getShowInfoStmt.QueryRow(showid).Scan(&result.title, ¯os, &result.norm_lvl, &result.trim_lvl, &low_cart, &high_cart) + result.err = self.getShowInfoStmt.QueryRow(showid).Scan(&result.title, ¯os, &result.group, &result.norm_lvl, &result.trim_lvl, &low_cart, &high_cart) if result.err != nil { if result.err == sql.ErrNoRows { result.err = fmt.Errorf("show '%d' not found", showid) diff --git a/src/helsinki.at/rhimportd/ctrlWebSimple.go b/src/helsinki.at/rhimportd/ctrlWebSimple.go index 40fe808..5be760c 100644 --- a/src/helsinki.at/rhimportd/ctrlWebSimple.go +++ b/src/helsinki.at/rhimportd/ctrlWebSimple.go @@ -36,6 +36,9 @@ import ( type webSimpleRequestData struct { UserName string `json:"LOGIN_NAME"` Password string `json:"PASSWORD"` + ShowId uint `json:"SHOW_ID"` + ClearShowCarts bool `json:"CLEAR_SHOW_CARTS"` + MusicPoolGroup string `json:"MUSIC_POOL_GROUP"` Cart uint `json:"CART_NUMBER"` Cut uint `json:"CUT_NUMBER"` Channels uint `json:"CHANNELS"` @@ -48,13 +51,15 @@ type webSimpleRequestData struct { type webSimpleResponseData struct { ResponseCode int `json:"REPONSE_CODE"` ErrorString string `json:"ERROR_STRING"` + Cart uint `json:"CART_NUMBER"` + Cut uint `json:"CUT_NUMBER"` } func webSimpleErrorResponse(w http.ResponseWriter, code int, error_str string) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) encoder := json.NewEncoder(w) - respdata := webSimpleResponseData{code, error_str} + respdata := webSimpleResponseData{code, error_str, 0, 0} encoder.Encode(respdata) } @@ -62,7 +67,7 @@ func webSimpleResponse(w http.ResponseWriter, result *rhimport.ImportResult) { w.Header().Set("Content-Type", "application/json") w.WriteHeader(http.StatusInternalServerError) encoder := json.NewEncoder(w) - respdata := webSimpleResponseData{result.ResponseCode, result.ErrorString} + respdata := webSimpleResponseData{result.ResponseCode, result.ErrorString, result.Cart, result.Cut} encoder.Encode(respdata) } @@ -86,6 +91,9 @@ func webSimpleParseRequest(conf *rhimport.Config, rddb *rhimport.RdDb, trusted b ctx = rhimport.NewImportContext(conf, rddb, username) ctx.Password = reqdata.Password ctx.Trusted = trusted + ctx.ShowId = reqdata.ShowId + ctx.ClearShowCarts = reqdata.ClearShowCarts + ctx.GroupName = reqdata.MusicPoolGroup ctx.Cart = reqdata.Cart ctx.Cut = reqdata.Cut ctx.Channels = reqdata.Channels @@ -122,6 +130,11 @@ func webSimpleHandler(conf *rhimport.Config, rddb *rhimport.RdDb, trusted bool, webSimpleErrorResponse(w, http.StatusInternalServerError, err.Error()) return } + if result.ResponseCode == http.StatusOK { + rhl.Println("ImportFile succesfully imported", ctx.SourceFile) + } else { + rhl.Println("ImportFile import of", ctx.SourceFile, "was unsuccesful") + } webSimpleResponse(w, result) return diff --git a/test/simple1.json b/test/simple1.json index db3f2aa..edd70b4 100644 --- a/test/simple1.json +++ b/test/simple1.json @@ -2,7 +2,6 @@ "LOGIN_NAME": "heslinki", "PASSWORD": "123456", "CART_NUMBER": 100000, - "CUT_NUMBER": 1, "CHANNELS": 2, "NORMALIZATION_LEVEL": -1200, "AUTOTRIM_LEVEL": 0, diff --git a/test/simple2.json b/test/simple2.json index e97379e..194bba3 100644 --- a/test/simple2.json +++ b/test/simple2.json @@ -2,7 +2,6 @@ "LOGIN_NAME": "heslinki", "PASSWORD": "123456", "CART_NUMBER": 100000, - "CUT_NUMBER": 1, "CHANNELS": 2, "NORMALIZATION_LEVEL": -1200, "AUTOTRIM_LEVEL": 0, diff --git a/test/simple3.json b/test/simple3.json index eaebab9..a378b1b 100644 --- a/test/simple3.json +++ b/test/simple3.json @@ -2,7 +2,6 @@ "LOGIN_NAME": "heslinki", "PASSWORD": "123456", "CART_NUMBER": 100000, - "CUT_NUMBER": 1, "CHANNELS": 2, "NORMALIZATION_LEVEL": -1200, "AUTOTRIM_LEVEL": 0, diff --git a/test/simple4.json b/test/simple4.json index abd8b30..7bf5b41 100644 --- a/test/simple4.json +++ b/test/simple4.json @@ -2,7 +2,6 @@ "LOGIN_NAME": "heslinki", "PASSWORD": "123456", "CART_NUMBER": 100000, - "CUT_NUMBER": 1, "CHANNELS": 2, "NORMALIZATION_LEVEL": -1200, "AUTOTRIM_LEVEL": 0, diff --git a/test/simple5.json b/test/simple5.json index d74e2c4..811d210 100644 --- a/test/simple5.json +++ b/test/simple5.json @@ -2,7 +2,6 @@ "LOGIN_NAME": "heslinki", "PASSWORD": "123456", "CART_NUMBER": 100000, - "CUT_NUMBER": 1, "CHANNELS": 2, "NORMALIZATION_LEVEL": -1200, "AUTOTRIM_LEVEL": 0, |