summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikolaus Gotsche <n@softwarefools.com>2020-11-15 17:33:51 +0100
committerNikolaus Gotsche <n@softwarefools.com>2020-11-15 17:33:51 +0100
commit30551f147d9648e42eddb95ff8eda2d7d33d09be (patch)
tree4f7fd3268cba39c8abe795780f6c4381e2f7d810
CovidDataFetcher 1.0HEADmaster
-rw-r--r--README.md7
-rw-r--r--coviddata.go346
2 files changed, 353 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..c4d60c8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,7 @@
+# Covid-19 Data Fetcher
+
+This little go program fetches all EU, US, India, Brazil, Russia data from api.covidapi.com and prints them in pdf charts.
+To prevent JSON Overflows US data is requested for 2 or 3 days at a time.
+
+## Coming soon:
+ - Make Gifs and movies with Imagemagick
diff --git a/coviddata.go b/coviddata.go
new file mode 100644
index 0000000..ad848be
--- /dev/null
+++ b/coviddata.go
@@ -0,0 +1,346 @@
+package main
+
+import (
+ "github.com/tidwall/gjson"
+ "github.com/sbinet/go-gnuplot"
+ "fmt"
+// "encoding/json"
+ "io/ioutil"
+ "net/http"
+ "time"
+// "log"
+)
+type Country struct {
+ Name string
+ Einwohner float64
+ Data []CountryData
+}
+
+type CountryData struct {
+ Date string
+ Cases int64
+ Deaths int64
+ Recovered int64
+}
+
+var euCountrys = []string{"austria","belgium","bulgaria","croatia","cyprus","czech-republic","denmark","estonia","finland","france","germany","greece","hungary","ireland","italy","latvia","lithuania","luxembourg","malta","netherlands","poland","portugal","romania","slovakia","slovenia","spain","sweden"}
+var restCountrys = []string{"brazil","russia","india","mexico"}
+var einwohner = []float64{211834,146877,1380004,128649,328239,447100} // in Tausend
+//var euCountrys = []string{"austria","belgium","cyprus","czech-republic","denmark","estonia","finland","france","germany","greece","hungary","ireland","italy","latvia","lithuania","luxemburg","malta","netherlands","poland","portugal","romania","slovakia","slovenia","spain","sweden"}
+var myClient = &http.Client{Timeout: time.Second*1000} //timeout after 200 seconds
+
+func getJson(url,param string) gjson.Result {
+ r, err := myClient.Get(url)
+ if err != nil {
+ panic(err.Error())
+ }
+ defer r.Body.Close()
+ body, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ panic(err.Error())
+ }
+
+ value := gjson.Get(string(body),param)
+ //return json.NewDecoder(r.Body).Decoder(target)
+// gjson.ForEachLine(string(body), func(line gjson.Result) bool{
+// fmt.Println(line.String())
+// return true
+// })
+// fmt.Println(value)
+ return value
+}
+
+func main() {
+ i := 0
+// test := new(Data)
+ currentDate := time.Now()
+ dateStr := currentDate.Format("2006-01-02")
+ baseurl := "https://api.covid19api.com/country/"
+ cstr := "confirmed"
+ dstr := "deaths"
+ sstr := "recovered"
+ //baseurl := "https://api.covid19api.com/country/austria/status/confirmed?from=2020-08-25T00:00:00Z&to=2020-08-25T00:00:00Z"
+ // ############# FETCH EU ##############
+ var eu []Country
+ var compare []Country
+ for _,c := range euCountrys{
+ caseurl := baseurl+c+"/status/"+cstr+"?from="+dateStr+"T00:00:00Z&to="+dateStr+"T00:00:00Z"
+ deathurl := baseurl+c+"/status/"+dstr+"?from="+dateStr+"T00:00:00Z&to="+dateStr+"T00:00:00Z"
+ recoverurl := baseurl+c+"/status/"+sstr+"?from="+dateStr+"T00:00:00Z&to="+dateStr+"T00:00:00Z"
+ cases := getJson(caseurl,"#.Cases").Array()
+ dates := getJson(caseurl,"#.Date").Array()
+ ccnt := len(cases)
+ death := getJson(deathurl,"#.Cases").Array()
+ dcnt := len(death)
+ rec := getJson(recoverurl,"#.Cases").Array()
+ rcnt := len(rec)
+ fmt.Println(c,ccnt,dcnt,rcnt)
+ var cData []CountryData
+ for idx,d := range dates{
+ tst := alreadyExists(cData,d.String())
+ if tst > -1 {
+ cData[tst].Cases += cases[idx].Int()
+ cData[tst].Deaths += death[idx].Int()
+ cData[tst].Recovered += rec[idx].Int()
+ }else{
+ var newData = CountryData{dates[idx].String(),cases[idx].Int(),death[idx].Int(),rec[idx].Int()}
+ cData = append(cData,newData)
+ }
+ }
+ eu = append(eu, Country{c,0.0,cData})
+ i += ccnt + dcnt + rcnt
+ fmt.Println(c,"Dates Added",len(cData))
+ time.Sleep(3 * time.Second)
+ }
+ // ################ FETCH REST COUNTRYS ###################
+ for j,c := range restCountrys{
+ caseurl := baseurl+c+"/status/"+cstr+"?from="+dateStr+"T00:00:00Z&to="+dateStr+"T00:00:00Z"
+ deathurl := baseurl+c+"/status/"+dstr+"?from="+dateStr+"T00:00:00Z&to="+dateStr+"T00:00:00Z"
+ recoverurl := baseurl+c+"/status/"+sstr+"?from="+dateStr+"T00:00:00Z&to="+dateStr+"T00:00:00Z"
+ cases := getJson(caseurl,"#.Cases").Array()
+ dates := getJson(caseurl,"#.Date").Array()
+ ccnt := len(cases)
+ death := getJson(deathurl,"#.Cases").Array()
+ dcnt := len(death)
+ rec := getJson(recoverurl,"#.Cases").Array()
+ rcnt := len(rec)
+ fmt.Println(c,ccnt,dcnt,rcnt)
+ var cData []CountryData
+ for idx,d := range dates{
+ tst := alreadyExists(cData,d.String())
+ if tst > -1 {
+ cData[tst].Cases += cases[idx].Int()
+ cData[tst].Deaths += death[idx].Int()
+ cData[tst].Recovered += rec[idx].Int()
+ }else{
+ var newData = CountryData{dates[idx].String(),cases[idx].Int(),death[idx].Int(),rec[idx].Int()}
+ cData = append(cData,newData)
+ }
+ }
+ compare = append(compare, Country{c,einwohner[j],cData})
+ i += ccnt + dcnt + rcnt
+ fmt.Println(c,"Dates Added",len(cData))
+ time.Sleep(3 * time.Second)
+ }
+ // ############### FETCH THE FUCKING UNITED STATES ###################
+ t0 := Date(2020,1,22)
+ days := int(currentDate.Sub(t0).Hours() / 24)
+ fmt.Println("DAYS FOR FUCKING US",days)
+ var cData []CountryData
+ for idx:=0; idx<days; idx++ {
+ startdate := t0.AddDate(0,0,idx)
+ if idx==0 && days%2!=0{
+ idx += 2
+ }else{
+ idx++
+ }
+ enddate := t0.AddDate(0,0,idx)
+ startStr := startdate.Format("2006-01-02")
+ endStr := enddate.Format("2006-01-02")
+ fmt.Println(startStr,endStr)
+ caseurl := baseurl+"united-states"+"/status/"+cstr+"?from="+startStr+"T00:00:00Z&to="+endStr+"T00:00:00Z"
+ deathurl := baseurl+"united-states"+"/status/"+dstr+"?from="+startStr+"T00:00:00Z&to="+endStr+"T00:00:00Z"
+ recoverurl := baseurl+"united-states"+"/status/"+sstr+"?from="+startStr+"T00:00:00Z&to="+endStr+"T00:00:00Z"
+ cases := getJson(caseurl,"#.Cases").Array()
+ dates := getJson(caseurl,"#.Date").Array()
+ ccnt := len(cases)
+ death := getJson(deathurl,"#.Cases").Array()
+ dcnt := len(death)
+ rec := getJson(recoverurl,"#.Cases").Array()
+ rcnt := len(rec)
+ for idx,d := range dates{
+ tst := alreadyExists(cData,d.String())
+ if tst > -1 {
+ cData[tst].Cases += cases[idx].Int()
+ cData[tst].Deaths += death[idx].Int()
+ cData[tst].Recovered += rec[idx].Int()
+ }else{
+ var newData = CountryData{dates[idx].String(),cases[idx].Int(),death[idx].Int(),rec[idx].Int()}
+ cData = append(cData,newData)
+ }
+ }
+ i += ccnt + dcnt + rcnt
+ time.Sleep(4 * time.Second)
+ }
+ for idx,_ := range cData{
+ cData[idx].Cases = cData[idx].Cases/2
+ cData[idx].Deaths = cData[idx].Deaths/2
+ cData[idx].Recovered = cData[idx].Recovered/2
+ }
+ fmt.Println("United States","Dates Added",len(cData))
+ compare = append(compare, Country{"United States of America",einwohner[len(einwohner)-2],cData})
+ fmt.Println("Bits of Data Collected:",i)
+ // ############# SUM EU #################
+ //var sumc int64 = 0
+ //var sumd int64 = 0
+ //var sumr int64 = 0
+ var euData []CountryData
+ for _,country := range eu {
+ for _,dat := range country.Data {
+ tst := alreadyExists(euData,dat.Date)
+ if tst > -1 {
+ euData[tst].Cases += dat.Cases
+ euData[tst].Deaths += dat.Deaths
+ euData[tst].Recovered += dat.Recovered
+ }else{
+ euData = append(euData,dat)
+ }
+ }
+ //sumc += country.Data[len(country.Data)-1].Cases
+ //sumd += country.Data[len(country.Data)-1].Deaths
+ //sumr += country.Data[len(country.Data)-1].Recovered
+ }
+ compare = append(compare, Country{"EU",einwohner[len(einwohner)-1],euData})
+ //fmt.Println("----IN EU----")
+ //fmt.Println("Total Cases:",sumc," - Check:",euData[len(euData)-1].Cases)
+ //fmt.Println("Total Deaths:",sumd," - Check:",euData[len(euData)-1].Deaths)
+ //fmt.Println("Total Recoverys:",sumr," - Check:",euData[len(euData)-1].Recovered)
+ // ################### PLOT DATA #########################
+ casespic,err := gnuplot.NewPlotter("",false,false)
+ deathpic,err := gnuplot.NewPlotter("",false,false)
+ recoverpic,err := gnuplot.NewPlotter("",false,false)
+ casespkpic,err := gnuplot.NewPlotter("",false,false)
+ deathpkpic,err := gnuplot.NewPlotter("",false,false)
+ recoverpkpic,err := gnuplot.NewPlotter("",false,false)
+ dltcasespic,err := gnuplot.NewPlotter("",false,false)
+ dltdeathpic,err := gnuplot.NewPlotter("",false,false)
+ if err != nil {
+ panic(err.Error())
+ }
+ casespic.SetStyle("lines")
+ deathpic.SetStyle("lines")
+ recoverpic.SetStyle("lines")
+ casespkpic.SetStyle("lines")
+ deathpkpic.SetStyle("lines")
+ recoverpkpic.SetStyle("lines")
+ dltcasespic.SetStyle("lines")
+ dltdeathpic.SetStyle("lines")
+ defer casespic.Close()
+ defer deathpic.Close()
+ defer recoverpic.Close()
+ for _,c := range compare {
+ var xdat []string
+ var ydatc []float64
+ var ydatd []float64
+ var ydatr []float64
+ var ydatcpk []float64
+ var ydatdpk []float64
+ var ydatrpk []float64
+ var ydatdeltac []float64
+ var ydatdeltad []float64
+ for j,d := range c.Data {
+ if j>0 {
+ ydatdeltac = append(ydatdeltac, float64(d.Cases)-float64(c.Data[j-1].Cases))
+ ydatdeltad = append(ydatdeltad, float64(d.Deaths)-float64(c.Data[j-1].Deaths))
+ }
+ xdat = append(xdat,d.Date[0:9])
+ ydatc = append(ydatc,float64(d.Cases))
+ ydatd = append(ydatd,float64(d.Deaths))
+ ydatr = append(ydatr,float64(d.Recovered))
+ ydatcpk = append(ydatcpk,float64(d.Cases)/c.Einwohner)
+ ydatdpk = append(ydatdpk,float64(d.Deaths)/c.Einwohner)
+ ydatrpk = append(ydatrpk,float64(d.Recovered)/c.Einwohner)
+ }
+ // ###### 5Day Mean #########
+ ydatdeltacm := meanData(ydatdeltac)
+ ydatdeltadm := meanData(ydatdeltad)
+ //casespic.PlotXY(xdat,ydatc,c.Name)
+ casespic.PlotX(ydatc,c.Name)
+ deathpic.PlotX(ydatd,c.Name)
+ recoverpic.PlotX(ydatr,c.Name)
+ casespkpic.PlotX(ydatcpk,c.Name)
+ deathpkpic.PlotX(ydatdpk,c.Name)
+ recoverpkpic.PlotX(ydatrpk,c.Name)
+ dltcasespic.PlotX(ydatdeltacm,c.Name)
+ dltdeathpic.PlotX(ydatdeltadm,c.Name)
+ }
+ plotOutData(dltcasespic,"Daily Cases","Days","Daily Cases","daycases")
+ plotOutData(dltdeathpic,"Daily Deaths","Days","Daily Deaths","daydeath")
+ plotOutData(casespic,"Total Cases","Days","Cases","cases")
+ plotOutData(deathpic,"Total Death","Days","Deaths","death")
+ plotOutData(casespkpic,"Cases per 1000","Days","Cases/1000","casespk")
+ plotOutData(deathpkpic,"Death per 1000","Days","Deaths/1000","deathpk")
+ plotOutData(recoverpic,"Total Recoverys","Days","Recoverýs","recover")
+ plotOutData(recoverpkpic,"Recoverys per 1000","Days","Recoverys/1000","recoverpk")
+ //casespic.SetXLabel("Days")
+ //casespic.SetYLabel("Cases")
+ //casespkpic.SetXLabel("Days")
+ //casespkpic.SetYLabel("Cases/1000")
+ //deathpic.SetXLabel("Days")
+ //deathpic.SetYLabel("Death")
+ //deathpkpic.SetXLabel("Days")
+ //deathpkpic.SetYLabel("Death/1000")
+ //recoverpic.SetXLabel("Days")
+ //recoverpic.SetYLabel("Recovered")
+/* recoverpkpic.SetXLabel("Days")
+ recoverpkpic.SetYLabel("Recovered/1000")
+ casespic.CheckedCmd("set key left top")
+ casespic.CheckedCmd("set terminal pdf")
+ casespic.CheckedCmd("set output'cases.pdf'")
+ casespic.CheckedCmd("replot")
+ casespic.CheckedCmd("q")
+ deathpic.CheckedCmd("set key left top")
+ deathpic.CheckedCmd("set terminal pdf")
+ deathpic.CheckedCmd("set output'death.pdf'")
+ deathpic.CheckedCmd("replot")
+ deathpic.CheckedCmd("q")
+ recoverpic.CheckedCmd("set key left top")
+ recoverpic.CheckedCmd("set terminal pdf")
+ recoverpic.CheckedCmd("set output'recovered.pdf'")
+ recoverpic.CheckedCmd("replot")
+ recoverpic.CheckedCmd("q")
+ casespkpic.CheckedCmd("set key left top")
+ casespkpic.CheckedCmd("set terminal pdf")
+ casespkpic.CheckedCmd("set output'casespk.pdf'")
+ casespkpic.CheckedCmd("replot")
+ casespkpic.CheckedCmd("q")
+ deathpkpic.CheckedCmd("set key left top")
+ deathpkpic.CheckedCmd("set terminal pdf")
+ deathpkpic.CheckedCmd("set output'deathpk.pdf'")
+ deathpkpic.CheckedCmd("replot")
+ deathpkpic.CheckedCmd("q")
+ recoverpkpic.CheckedCmd("set key left top")
+ recoverpkpic.CheckedCmd("set terminal pdf")
+ recoverpkpic.CheckedCmd("set output'recoveredpk.pdf'")
+ recoverpkpic.CheckedCmd("replot")
+ recoverpkpic.CheckedCmd("q")
+*/
+ fmt.Println("----COMPARISON----")
+ fmt.Println("As of",compare[0].Data[len(compare[0].Data)-1].Date[0:9])
+ fmt.Println("Country --- Cases --- Deaths --- Recovered")
+ for _,c := range compare{
+ fmt.Println(c.Name,c.Data[len(c.Data)-1].Cases,c.Data[len(c.Data)-1].Deaths,c.Data[len(c.Data)-1].Recovered)
+ }
+}
+func meanData(in []float64) []float64{
+ var out []float64
+ for k,_ := range in {
+ if k>2 && k<len(in)-3 {
+ tmp := float64(in[k-2]+in[k-1]+in[k]+in[k+1]+in[k+2])/5
+ out = append(out,tmp)
+ }
+ }
+ return out
+}
+
+func plotOutData(pl *gnuplot.Plotter, title,xlabel,ylabel,filename string){
+ pl.SetXLabel(xlabel)
+ pl.SetYLabel(ylabel)
+ pl.CheckedCmd("set key left top")
+ pl.CheckedCmd("set terminal pdf")
+ nstr := "set output'"+filename+".pdf'"
+ pl.CheckedCmd(nstr)
+ pl.CheckedCmd("replot")
+ pl.CheckedCmd("q")
+}
+func alreadyExists(indat []CountryData,date string) int{
+ for i,val := range indat{
+ if val.Date == date {
+ return i
+ }
+ }
+ return -1
+}
+func Date(year, month, day int) time.Time {
+ return time.Date(year, time.Month(month), day, 0, 0, 0, 0, time.UTC)
+}