package main import ( "bufio" "bytes" "fmt" "io" "io/ioutil" "log" "net/http" "net/smtp" "os" "os/exec" "path" "time" "github.com/BurntSushi/toml" homedir "github.com/mitchellh/go-homedir" "github.com/domodwyer/mailyak" ) type Config struct { MailHost, Username, Password string MailPort int Len int64 } var conf Config var confFile string func getConf() Config { confDir := path.Dir(confFile) if _, err := os.Stat(confDir); os.IsNotExist(err) { log.Printf("Creating config directory") err = os.MkdirAll(confDir, 0777) if err != nil { log.Fatal("Cannot create config directory: ", err) } } if _, err := os.Stat(confFile); os.IsNotExist(err) { log.Printf("Creating config file") f, err := os.Create(confFile) if err != nil { log.Fatal("Cannot create config file: ", err) } err = f.Close() if err != nil { log.Fatal("Error closing config file: ", err) } } if _, err := toml.DecodeFile(confFile, &conf); err != nil { log.Fatal("Error reading config file: ", err) } of, err := os.Create(path.Join(confDir, "c.R")) if err != nil { log.Fatal("Error creating R source file: ", err) } _, err = of.WriteString(rCode()) if err != nil { log.Fatal("Error writing R source code: ", err) } return conf } func save() { of, err := os.Create(confFile) if err != nil { log.Fatal("Cannot open config file: ", err) } var buf bytes.Buffer w := bufio.NewWriter(&buf) enc := toml.NewEncoder(w) enc.Encode(conf) io.Copy(of, &buf) err = of.Close() if err != nil { log.Fatal("Error closing config file: ", err) } } func fetch() { url := "https://health.data.ny.gov/api/views/xdss-u53e/rows.csv?accessType=DOWNLOAD" resp, err := http.Get(url) if err != nil { log.Printf("HTTP error: ", err) return } body, err := ioutil.ReadAll(resp.Body) if err != nil { log.Printf("Read error: ", err) return } if int64(len(body)) == conf.Len { log.Printf("Equal length, returning") return } log.Printf("Length differs: body = %d", len(body)) conf.Len = int64(len(body)) save() of, err := os.Create(path.Join(path.Dir(confFile), "rows.csv")) if err != nil { log.Fatal("Cannot create rows.csv: ", err) } _, err = of.Write(body) if err != nil { log.Fatal("Error writing rows.csv: ", err) } confDir := path.Dir(confFile) cmd := exec.Command("R", "--no-save", "-f", path.Join(confDir, "c.R")) log.Printf("Running R") err = cmd.Run() if err != nil { log.Fatal("Error running R: ", err) } log.Printf("R completed") if conf.MailHost == "" { log.Print("No mail host set, returning") return } f, err := os.Open("Rplots.pdf") if err != nil { log.Fatal("Error opening Rplots.pdf: ", err) } defer f.Close() email := mailyak.New(fmt.Sprintf("%s:%d", conf.MailHost, conf.MailPort), smtp.PlainAuth("", conf.Username, conf.Password, conf.MailHost)) email.To("gmp@wow.st") email.From("covid@wow.st") msg := "Covid dashboard update for " + time.Now().Format("Monday, January 2 2006") email.Subject(msg) email.Plain().Set(msg) email.Attach("dashboard.pdf", f) err = email.Send() if err != nil { log.Print("Error sending email: ", err) } } func main() { log.Printf("starting") homeDir, err := homedir.Dir() if err != nil { log.Fatal("Cannot locate user's home directory") } confFile = path.Join(homeDir, ".config", "cget", "cget.conf") os.Chdir(path.Dir(confFile)) getConf() for { fetch() time.Sleep(time.Minute * 30) } log.Printf("done") }