// // rhimportd // // The Radio Helsinki Rivendell Import Daemon // // // Copyright (C) 2015-2016 Christian Pointner // // 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 . // 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) } }