summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Pointner <equinox@helsinki.at>2015-12-15 18:47:22 (GMT)
committerChristian Pointner <equinox@helsinki.at>2015-12-15 18:47:22 (GMT)
commitd33cf1f6738a3c3771247dd29e764c296b806f4c (patch)
tree288aed9f17e25a6426b5b8f070239f9b9077a0c8 /src
parent764c1939b3cf995fd98e4dc27b5709d3b494702b (diff)
improved error handling and overall resilience to different situations
Diffstat (limited to 'src')
-rw-r--r--src/helsinki.at/rhimport/fetcher.go2
-rw-r--r--src/helsinki.at/rhimport/importer.go132
-rw-r--r--src/helsinki.at/rhimport/rddb.go2
-rw-r--r--src/helsinki.at/rhimportd/ctrlWeb.go2
-rw-r--r--src/helsinki.at/rhimportd/ctrlWebSimple.go3
-rw-r--r--src/helsinki.at/rhimportd/main.go5
6 files changed, 123 insertions, 23 deletions
diff --git a/src/helsinki.at/rhimport/fetcher.go b/src/helsinki.at/rhimport/fetcher.go
index ae7c910..38e1d7f 100644
--- a/src/helsinki.at/rhimport/fetcher.go
+++ b/src/helsinki.at/rhimport/fetcher.go
@@ -134,6 +134,8 @@ func FetchFileCurl(ctx *ImportContext, uri *url.URL) (err error) {
// still: let's make a special configurable directory the local:/// dir
// and only allow absolute paths here which will be based on the
// 'local' directory
+// TODO: also check if file exists and is accessable!!! otherwise curl will blow up
+// with a not-easy-to-understand error
func FetchFileLocal(ctx *ImportContext, uri *url.URL) (err error) {
rhl.Printf("Local fetcher called for '%s'", ctx.SourceUri)
if ctx.ProgressCallBack != nil {
diff --git a/src/helsinki.at/rhimport/importer.go b/src/helsinki.at/rhimport/importer.go
index aa5343d..94065f6 100644
--- a/src/helsinki.at/rhimport/importer.go
+++ b/src/helsinki.at/rhimport/importer.go
@@ -49,6 +49,7 @@ type ImportContext struct {
ClearShowCarts bool
GroupName string
Cart uint
+ ClearCart bool
Cut uint
Channels uint
NormalizationLevel int
@@ -73,6 +74,7 @@ func NewImportContext(conf *Config, rddb *RdDb, user string) *ImportContext {
ctx.ClearShowCarts = false
ctx.GroupName = ""
ctx.Cart = 0
+ ctx.ClearCart = false
ctx.Cut = 0
ctx.Channels = conf.ImportParamDefaults.Channels
ctx.NormalizationLevel = conf.ImportParamDefaults.NormalizationLevel
@@ -210,6 +212,14 @@ func (self *ImportResult) fromRDWebResult(rdres *RDWebResult) {
}
func add_cart(ctx *ImportContext, res *ImportResult) (err error) {
+ rhdl.Printf("importer: add_cart() called for cart: %d", ctx.Cart)
+
+ if ctx.GroupName == "" {
+ if err = ctx.getGroupOfCart(); err != nil {
+ return
+ }
+ }
+
var b bytes.Buffer
w := multipart.NewWriter(&b)
@@ -247,6 +257,7 @@ func add_cart(ctx *ImportContext, res *ImportResult) (err error) {
return
}
res.fromRDWebResult(rdres)
+ res.Cart = ctx.Cart
return
}
var cartadd *RDCartAdd
@@ -261,6 +272,7 @@ func add_cart(ctx *ImportContext, res *ImportResult) (err error) {
}
func add_cut(ctx *ImportContext, res *ImportResult) (err error) {
+ rhdl.Printf("importer: add_cut() called for cart/cut: %d/%d", ctx.Cart, ctx.Cut)
var b bytes.Buffer
w := multipart.NewWriter(&b)
@@ -290,6 +302,8 @@ func add_cut(ctx *ImportContext, res *ImportResult) (err error) {
return
}
res.fromRDWebResult(rdres)
+ res.Cart = ctx.Cart
+ res.Cut = ctx.Cut
return
}
var cutadd *RDCutAdd
@@ -298,12 +312,14 @@ func add_cut(ctx *ImportContext, res *ImportResult) (err error) {
}
res.ResponseCode = resp.StatusCode
res.ErrorString = "OK"
+ res.Cart = ctx.Cart
res.Cut = cutadd.Cuts[0].Number
ctx.Cut = cutadd.Cuts[0].Number
return
}
func remove_cart(ctx *ImportContext, res *ImportResult) (err error) {
+ rhdl.Printf("importer: remove_cart() called for cart: %d", ctx.Cart)
var b bytes.Buffer
w := multipart.NewWriter(&b)
@@ -332,10 +348,49 @@ func remove_cart(ctx *ImportContext, res *ImportResult) (err error) {
return
}
res.fromRDWebResult(rdres)
+ res.Cart = ctx.Cart
+ return
+}
+
+func remove_cut(ctx *ImportContext, res *ImportResult) (err error) {
+ rhdl.Printf("importer: remove_cut() called for cart/cut: %d/%d", ctx.Cart, ctx.Cut)
+ var b bytes.Buffer
+ w := multipart.NewWriter(&b)
+
+ if err = w.WriteField("COMMAND", "11"); err != nil {
+ return
+ }
+ if err = w.WriteField("LOGIN_NAME", ctx.UserName); err != nil {
+ return
+ }
+ if err = w.WriteField("PASSWORD", ctx.Password); err != nil {
+ return
+ }
+ if err = w.WriteField("CART_NUMBER", fmt.Sprintf("%d", ctx.Cart)); err != nil {
+ return
+ }
+ if err = w.WriteField("CUT_NUMBER", fmt.Sprintf("%d", ctx.Cut)); err != nil {
+ return
+ }
+ w.Close()
+
+ var resp *http.Response
+ if resp, err = send_post_request(ctx.Config.RDXportEndpoint, &b, w.FormDataContentType()); err != nil {
+ return
+ }
+ defer resp.Body.Close()
+
+ var rdres *RDWebResult
+ if rdres, err = NewRDWebResultFromXML(resp.Body); err != nil {
+ return
+ }
+ res.fromRDWebResult(rdres)
+ res.Cart = ctx.Cart
+ res.Cut = ctx.Cut
return
}
-func send_post_request(url string, b *bytes.Buffer, contenttype string) (res *http.Response, err error) {
+func send_post_request(url string, b *bytes.Buffer, contenttype string) (resp *http.Response, err error) {
var req *http.Request
if req, err = http.NewRequest("POST", url, b); err != nil {
return
@@ -345,7 +400,7 @@ func send_post_request(url string, b *bytes.Buffer, contenttype string) (res *ht
}
client := &http.Client{}
- if res, err = client.Do(req); err != nil {
+ if resp, err = client.Do(req); err != nil {
return
}
return
@@ -388,7 +443,8 @@ func import_audio_create_request(ctx *ImportContext, easy *curl.CURL) (form *cur
return
}
-func import_audio(ctx *ImportContext, result *ImportResult) (err error) {
+func import_audio(ctx *ImportContext, res *ImportResult) (err error) {
+ rhdl.Printf("importer: import_audio() called for cart/cut: %d/%d", ctx.Cart, ctx.Cut)
easy := curl.EasyInit()
if easy != nil {
@@ -431,8 +487,9 @@ func import_audio(ctx *ImportContext, result *ImportResult) (err error) {
if rdres, err = NewRDWebResultFromXML(bufio.NewReader(&resbody)); err != nil {
return
}
- result.fromRDWebResult(rdres)
- return
+ res.fromRDWebResult(rdres)
+ res.Cart = ctx.Cart
+ res.Cut = ctx.Cut
} else {
err = fmt.Errorf("Error initializing libcurl")
}
@@ -440,14 +497,21 @@ 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) {
+func add_cart_cut(ctx *ImportContext, res *ImportResult) (err error) {
+ if err = add_cart(ctx, res); err != nil || res.ResponseCode != http.StatusOK {
return
}
- if err = add_cart(ctx, res); err != nil || res.ResponseCode != http.StatusOK {
+ if err = add_cut(ctx, res); err != nil || res.ResponseCode != http.StatusOK {
+ return remove_cart(ctx, &ImportResult{ResponseCode: http.StatusOK})
+ }
+ 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
}
- return add_cut(ctx, res)
+ return add_cart_cut(ctx, res)
}
func is_cart_member_of_show(ctx *ImportContext, res *ImportResult, carts []uint) (found bool) {
@@ -484,7 +548,10 @@ func add_show_cart_cut(ctx *ImportContext, res *ImportResult, carts []uint) (err
}
for _, cart := range carts {
if cart == ctx.Cart {
- return add_cut(ctx, res)
+ if err = add_cut(ctx, res); err != nil || res.ResponseCode != http.StatusOK {
+ return remove_cart(ctx, &ImportResult{ResponseCode: http.StatusOK})
+ }
+ return
}
}
if err = remove_cart(ctx, res); err != nil || res.ResponseCode != http.StatusOK {
@@ -516,6 +583,8 @@ func cleanup_files(ctx *ImportContext) {
func ImportFile(ctx *ImportContext) (res *ImportResult, err error) {
defer cleanup_files(ctx)
+ rhdl.Printf("importer: ImportFile called with: show-id: %d, pool-name: '%s', cart/cut: %d/%d", ctx.ShowId, ctx.GroupName, ctx.Cart, ctx.Cut)
+
if ctx.ProgressCallBack != nil {
ctx.ProgressCallBack(2, "importing", 0.0, ctx.ProgressCallBackData)
}
@@ -526,6 +595,8 @@ func ImportFile(ctx *ImportContext) (res *ImportResult, err error) {
}
}
+ rmCartOnErr := false
+ rmCutOnErr := false
res = &ImportResult{ResponseCode: http.StatusOK}
if ctx.ShowId != 0 {
var show_carts []uint
@@ -541,6 +612,7 @@ func ImportFile(ctx *ImportContext) (res *ImportResult, err error) {
if err = add_show_cart_cut(ctx, res, show_carts); err != nil || res.ResponseCode != http.StatusOK {
return
}
+ rmCartOnErr = true
} else if ctx.GroupName != "" {
if err = ctx.getMusicInfo(); err != nil {
return
@@ -548,12 +620,25 @@ func ImportFile(ctx *ImportContext) (res *ImportResult, err error) {
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
+ rmCartOnErr = true
+ } else if ctx.Cart != 0 && ctx.Cut == 0 {
+ if ctx.ClearCart {
+ if err = remove_add_cart_cut(ctx, res); err != nil || res.ResponseCode != http.StatusOK {
+ return
+ }
+ rmCartOnErr = true
+ } else {
+ if err = add_cut(ctx, res); err != nil {
+ return
+ }
+ if res.ResponseCode != http.StatusOK {
+ if err = add_cart_cut(ctx, res); err != nil || res.ResponseCode != http.StatusOK {
+ return
+ }
+ rmCartOnErr = true
+ } else {
+ rmCutOnErr = true
+ }
}
}
@@ -561,13 +646,22 @@ func ImportFile(ctx *ImportContext) (res *ImportResult, err error) {
if err = import_audio(ctx, res); err != nil {
return
}
- res.Cart = ctx.Cart
- res.Cut = ctx.Cut
+ if res.ResponseCode != http.StatusOK {
+ rmres := ImportResult{ResponseCode: http.StatusOK}
+ if rmCartOnErr {
+ if err = remove_cart(ctx, &rmres); err != nil {
+ return
+ }
+ } else if rmCutOnErr {
+ if err = remove_cut(ctx, &rmres); err != nil {
+ return
+ }
+ }
+ }
} else {
res.ResponseCode = http.StatusBadRequest
res.ErrorString = "The request doesn't contain enough information to be processed"
}
- rhdl.Printf("ImportResult: %+v\n", res)
return
}
diff --git a/src/helsinki.at/rhimport/rddb.go b/src/helsinki.at/rhimport/rddb.go
index 34019e8..28fa6bd 100644
--- a/src/helsinki.at/rhimport/rddb.go
+++ b/src/helsinki.at/rhimport/rddb.go
@@ -33,7 +33,7 @@ import (
)
var (
- showMacroRe = regexp.MustCompile(`^LL 1 ([^ ]+) 0\!$`)
+ showMacroRe = regexp.MustCompile(`^LL 1 ([^ ]+) 0\!$`)
mysqlTableNameRe = regexp.MustCompile(`^[_0-9a-zA-Z-]+$`)
)
diff --git a/src/helsinki.at/rhimportd/ctrlWeb.go b/src/helsinki.at/rhimportd/ctrlWeb.go
index 6475a96..0341a95 100644
--- a/src/helsinki.at/rhimportd/ctrlWeb.go
+++ b/src/helsinki.at/rhimportd/ctrlWeb.go
@@ -46,5 +46,5 @@ func StartControlWeb(addr_s string, conf *rhimport.Config, rddb *rhimport.RdDb)
http.Handle("/trusted/simple", webHandler{conf, rddb, true, webSimpleHandler})
rhl.Println("listening on", addr_s)
- http.ListenAndServe(addr_s, nil)
+ http.ListenAndServe(addr_s, nil) // TODO: reader.Timeout, writer.Timeout???
}
diff --git a/src/helsinki.at/rhimportd/ctrlWebSimple.go b/src/helsinki.at/rhimportd/ctrlWebSimple.go
index 41e4f81..2de324f 100644
--- a/src/helsinki.at/rhimportd/ctrlWebSimple.go
+++ b/src/helsinki.at/rhimportd/ctrlWebSimple.go
@@ -40,6 +40,7 @@ type webSimpleRequestData struct {
ClearShowCarts bool `json:"CLEAR_SHOW_CARTS"`
MusicPoolGroup string `json:"MUSIC_POOL_GROUP"`
Cart uint `json:"CART_NUMBER"`
+ ClearCart bool `json:"CLEAR_CART"`
Cut uint `json:"CUT_NUMBER"`
Channels uint `json:"CHANNELS"`
NormalizationLevel int `json:"NORMALIZATION_LEVEL"`
@@ -56,6 +57,7 @@ func newWebSimpleRequestData(conf *rhimport.Config) *webSimpleRequestData {
rd.ClearShowCarts = false
rd.MusicPoolGroup = ""
rd.Cart = 0
+ rd.ClearCart = false
rd.Cut = 0
rd.Channels = conf.ImportParamDefaults.Channels
rd.NormalizationLevel = conf.ImportParamDefaults.NormalizationLevel
@@ -113,6 +115,7 @@ func webSimpleParseRequest(conf *rhimport.Config, rddb *rhimport.RdDb, trusted b
ctx.ClearShowCarts = reqdata.ClearShowCarts
ctx.GroupName = reqdata.MusicPoolGroup
ctx.Cart = reqdata.Cart
+ ctx.ClearCart = reqdata.ClearCart
ctx.Cut = reqdata.Cut
ctx.Channels = reqdata.Channels
ctx.NormalizationLevel = reqdata.NormalizationLevel
diff --git a/src/helsinki.at/rhimportd/main.go b/src/helsinki.at/rhimportd/main.go
index 5184870..1b9e5e0 100644
--- a/src/helsinki.at/rhimportd/main.go
+++ b/src/helsinki.at/rhimportd/main.go
@@ -26,12 +26,13 @@ package main
import (
"flag"
- "helsinki.at/rhimport"
"log"
"os"
"os/signal"
"sync"
- // "io/ioutil"
+
+ "helsinki.at/rhimport"
+ // "io/ioutil"
)
var (