summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@helsinki.at>2016-01-05 16:39:25 (GMT)
committerChristian Pointner <equinox@helsinki.at>2016-01-05 16:39:25 (GMT)
commit1f7c2b415a67049fa217ac1b7495e78267ec4808 (patch)
tree50c3c50ed83e9ae815d78d5edba3d8618e35e024
parent2383f77970c87504b96677e010a8aa954d6955f5 (diff)
added initial watch-dir control interface
-rw-r--r--src/helsinki.at/rhimportd/ctrlWatchDir.go191
-rw-r--r--src/helsinki.at/rhimportd/main.go44
2 files changed, 221 insertions, 14 deletions
diff --git a/src/helsinki.at/rhimportd/ctrlWatchDir.go b/src/helsinki.at/rhimportd/ctrlWatchDir.go
new file mode 100644
index 0000000..f4e3a54
--- /dev/null
+++ b/src/helsinki.at/rhimportd/ctrlWatchDir.go
@@ -0,0 +1,191 @@
+//
+// rhimportd
+//
+// The Radio Helsinki Rivendell Import Daemon
+//
+//
+// Copyright (C) 2015-2016 Christian Pointner <equinox@helsinki.at>
+//
+// This file is part of rhimportd.
+//
+// rhimportd is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// any later version.
+//
+// rhimportd is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with rhimportd. If not, see <http://www.gnu.org/licenses/>.
+//
+
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "helsinki.at/rhimport"
+ "net/http"
+ "os"
+ "time"
+)
+
+type watchDirRequestData struct {
+ UserName string `json:"LOGIN_NAME"`
+ ShowId uint `json:"SHOW_ID"`
+ 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"`
+ AutotrimLevel int `json:"AUTOTRIM_LEVEL"`
+ UseMetaData bool `json:"USE_METADATA"`
+ SourceUri string `json:"SOURCE_URI"`
+}
+
+func newWatchDirRequestData(conf *rhimport.Config) *watchDirRequestData {
+ rd := new(watchDirRequestData)
+ rd.UserName = ""
+ rd.ShowId = 0
+ rd.ClearShowCarts = false
+ rd.MusicPoolGroup = ""
+ rd.Cart = 0
+ rd.ClearCart = false
+ rd.Cut = 0
+ rd.Channels = conf.ImportParamDefaults.Channels
+ rd.NormalizationLevel = conf.ImportParamDefaults.NormalizationLevel
+ rd.AutotrimLevel = conf.ImportParamDefaults.AutotrimLevel
+ rd.UseMetaData = conf.ImportParamDefaults.UseMetaData
+ rd.SourceUri = ""
+
+ return rd
+}
+
+type watchDirResponseData struct {
+ ResponseCode int `json:"REPONSE_CODE"`
+ ErrorString string `json:"ERROR_STRING"`
+ Cart uint `json:"CART_NUMBER"`
+ Cut uint `json:"CUT_NUMBER"`
+}
+
+func watchDirErrorResponse(code int, errStr string) {
+ encoder := json.NewEncoder(os.Stdout)
+ respdata := watchDirResponseData{code, errStr, 0, 0}
+ encoder.Encode(respdata)
+}
+
+func watchDirResponse(result *rhimport.Result) {
+ encoder := json.NewEncoder(os.Stdout)
+ respdata := watchDirResponseData{result.ResponseCode, result.ErrorString, result.Cart, result.Cut}
+ encoder.Encode(respdata)
+}
+
+func watchDirParseRequest(conf *rhimport.Config, rddb *rhimport.RdDbChan, filename string) (ctx *rhimport.Context, err error) {
+
+ decoder := json.NewDecoder(os.Stdin)
+ reqdata := newWatchDirRequestData(conf)
+ if jsonerr := decoder.Decode(reqdata); jsonerr != nil {
+ err = fmt.Errorf("Error parsing JSON response: %s", jsonerr)
+ return
+ }
+
+ ctx = rhimport.NewContext(conf, rddb)
+ ctx.UserName = reqdata.UserName
+ ctx.Trusted = true
+ ctx.ShowId = reqdata.ShowId
+ 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
+ ctx.AutotrimLevel = reqdata.AutotrimLevel
+ ctx.UseMetaData = reqdata.UseMetaData
+ ctx.SourceUri = reqdata.SourceUri
+ return
+}
+
+func watchDirHandler(conf *rhimport.Config, rddb *rhimport.RdDbChan, filename string) {
+ rhdl.Printf("WatchDirHandler: request for '%s'", filename)
+
+ var ctx *rhimport.Context
+ var err error
+ if ctx, err = watchDirParseRequest(conf, rddb, filename); err != nil {
+ watchDirErrorResponse(http.StatusBadRequest, err.Error())
+ return
+ }
+
+ if err = ctx.SanityCheck(); err != nil {
+ watchDirErrorResponse(http.StatusBadRequest, err.Error())
+ return
+ }
+
+ var res *rhimport.Result
+ if res, err = rhimport.FetchFile(ctx); err != nil {
+ watchDirErrorResponse(http.StatusInternalServerError, err.Error())
+ return
+ }
+ if res.ResponseCode != http.StatusOK {
+ watchDirErrorResponse(res.ResponseCode, res.ErrorString)
+ return
+ }
+
+ if res, err = rhimport.ImportFile(ctx); err != nil {
+ watchDirErrorResponse(http.StatusInternalServerError, err.Error())
+ return
+ }
+ if res.ResponseCode == http.StatusOK {
+ rhl.Println("ImportFile succesfully imported", ctx.SourceFile)
+ } else {
+ rhl.Println("ImportFile import of", ctx.SourceFile, "was unsuccesful")
+ }
+
+ watchDirResponse(res)
+ return
+}
+
+func watchDirRun(dir *os.File, conf *rhimport.Config, rddb *rhimport.RdDbChan) {
+ rhl.Printf("watch-dir-ctrl: watching for files in %s", dir.Name())
+ for {
+ var err error
+ if _, err = dir.Seek(0, 0); err != nil {
+ rhl.Printf("watch-dir-ctrl: reading directory contents failed: %s", err)
+ return
+ }
+
+ var names []string
+ if names, err = dir.Readdirnames(0); err != nil {
+ rhl.Printf("watch-dir-ctrl: reading directory contents failed: %s", err)
+ return
+ }
+ rhdl.Printf("watch-dir-ctrl: got: %q", names)
+ time.Sleep(1 * time.Second)
+ }
+}
+
+func StartWatchDir(dirname string, conf *rhimport.Config, rddb *rhimport.RdDbChan) {
+ for {
+ time.Sleep(5 * time.Second)
+ dir, err := os.Open(dirname)
+ if err != nil {
+ rhl.Printf("watch-dir-ctrl: %s", err)
+ continue
+ }
+ if i, err := dir.Stat(); err != nil {
+ rhl.Printf("watch-dir-ctrl: %s", err)
+ continue
+ } else {
+ if !i.IsDir() {
+ rhl.Printf("watch-dir-ctrl: %s is not a directory", dirname)
+ continue
+ }
+ }
+ watchDirRun(dir, conf, rddb)
+ }
+}
diff --git a/src/helsinki.at/rhimportd/main.go b/src/helsinki.at/rhimportd/main.go
index 4bd779e..d941b05 100644
--- a/src/helsinki.at/rhimportd/main.go
+++ b/src/helsinki.at/rhimportd/main.go
@@ -70,6 +70,8 @@ func main() {
flag.Var(webAddr, "web-addr", "addr:port to listen on (environment: RHIMPORTD_WEB_ADDR)")
telnetAddr := newEnvStringValue("RHIMPORTD_TELNET_ADDR", "localhost:4023")
flag.Var(telnetAddr, "telnet-addr", "addr:port to listen on (environment: RHIMPORTD_TELNET_ADDR)")
+ watchDir := newEnvStringValue("RHIMPORTD_WATCH_DIR", "")
+ flag.Var(watchDir, "watch-dir", "directory to look for file based requests (environment: RHIMPORTD_WATCH_DIR)")
rdconf := newEnvStringValue("RHIMPORTD_RD_CONF", "/etc/rd.conf")
flag.Var(rdconf, "rdconf", "path to the Rivendell config file (environment: RHIMPORTD_RD_CONF)")
rdxportUrl := newEnvStringValue("RHIMPORTD_RDXPORT_URL", "http://localhost/rd-bin/rdxport.cgi")
@@ -108,21 +110,35 @@ func main() {
var wg sync.WaitGroup
- wg.Add(1)
- go func() {
- defer wg.Done()
- rhl.Println("starting web-ctrl")
- StartControlWeb(webAddr.Get().(string), conf, rddb.GetInterface(), sessions.GetInterface())
- rhl.Println("web-ctrl finished")
- }()
+ if webAddr.Get().(string) != "" {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ rhl.Println("starting web-ctrl")
+ StartControlWeb(webAddr.Get().(string), conf, rddb.GetInterface(), sessions.GetInterface())
+ rhl.Println("web-ctrl finished")
+ }()
+ }
- wg.Add(1)
- go func() {
- defer wg.Done()
- rhl.Println("starting telnet-ctrl")
- StartControlTelnet(telnetAddr.Get().(string), conf, rddb.GetInterface(), sessions.GetInterface())
- rhl.Println("telnet-ctrl finished")
- }()
+ if telnetAddr.Get().(string) != "" {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ rhl.Println("starting telnet-ctrl")
+ StartControlTelnet(telnetAddr.Get().(string), conf, rddb.GetInterface(), sessions.GetInterface())
+ rhl.Println("telnet-ctrl finished")
+ }()
+ }
+
+ if watchDir.Get().(string) != "" {
+ wg.Add(1)
+ go func() {
+ defer wg.Done()
+ rhl.Println("starting watch-dir-ctrl")
+ StartWatchDir(watchDir.Get().(string), conf, rddb.GetInterface())
+ rhl.Println("watch-dir-ctrl finished")
+ }()
+ }
alldone := make(chan bool)
go func() {