package main import ( "archive/zip" "bytes" "flag" "fmt" "io/ioutil" "log" "net/http" "os" "strconv" "strings" "github.com/antchfx/xmlquery" "gopkg.in/ini.v1" ) // ParseArgs is not yet implemented func ParseArgs() error { return nil } // GetConfig fetch config from ini file func GetConfig(configfile string, fuelpricesconfig *FuelPricesConfig) error { flag.Usage = Usage flag.Parse() config, err := ini.Load(configfile) HandleFatalError(err) var fpc FuelPricesConfig fuelpricesSection := config.Section("fuelprices") fpc.RemoteURL = fuelpricesSection.Key("remote_url").String() fpc.RemoteFilename = fuelpricesSection.Key("remote_filename").String() fpc.XPathBase = fuelpricesSection.Key("xpath_base").String() fpc.InfluxHost = fuelpricesSection.Key("influx_host").String() fpc.InfluxPort, err = fuelpricesSection.Key("influx_port").Int() HandleError(err) fpc.InfluxUser = fuelpricesSection.Key("influx_user").String() fpc.InfluxPass = fuelpricesSection.Key("influx_pass").String() HandleError(err) fpc.InfluxDB = fuelpricesSection.Key("influx_db").String() fpc.Pos = strings.Split(fuelpricesSection.Key("pos").String(), ",") fpc.Types = strings.Split(fuelpricesSection.Key("types").String(), ",") *fuelpricesconfig = fpc return err } // DownloadFile fetch file from webserver func DownloadFile(url string) error { resp, err := http.Get(url) HandleError(err) szip.Content, err = ioutil.ReadAll(resp.Body) HandleError(err) err = resp.Body.Close() HandleError(err) return err } // ExtractZip get the XML file to be processed func ExtractZip() error { zipfile, err = zip.NewReader(bytes.NewReader(szip.Content), int64(len(szip.Content))) if err != nil { log.Fatal("Unable to open zipfile") } for _, f := range zipfile.File { if f.Name == fpc.RemoteFilename { rc, err := f.Open() if err != nil { return err } ofile.Content, err = ioutil.ReadAll(rc) rc.Close() } else { log.Fatal("File not found") } } return err } // GetPrices parses the XML file and get values of prices func GetPrices(prices **[]Price, spos []string, stypes []string, sxpathbase string) error { var pr []Price var xml *xmlquery.Node f := bytes.NewReader(ofile.Content) xml, err = xmlquery.Parse(f) HandleError(err) for _, station := range spos { for _, fuel := range stypes { query := fmt.Sprintf(sxpathbase, station, fuel) list := xmlquery.FindOne(xml, query) for _, i := range list.Attr { if i.Name.Local == "valeur" { var val float64 if s, err := strconv.ParseFloat(i.Value, 64); err == nil { val = s } pr = append(pr, Price{ID: station, Fuel: fuel, Amount: val}) } } } } *prices = &pr return err } // HandleError handles errors to return err func HandleError(err error) error { if err != nil { return err } return nil } // HandleFatalError fatal errors func HandleFatalError(err error) { if err != nil { log.Fatal(err) os.Exit(2) } } // Usage displays possible arguments func Usage() { fmt.Fprintf(os.Stderr, "Usage: fuelprices [configfile]\n") flag.PrintDefaults() os.Exit(1) }