diff options
| author | Nikolaus Gotsche <n@softwarefools.com> | 2020-11-15 17:33:51 +0100 |
|---|---|---|
| committer | Nikolaus Gotsche <n@softwarefools.com> | 2020-11-15 17:33:51 +0100 |
| commit | 30551f147d9648e42eddb95ff8eda2d7d33d09be (patch) | |
| tree | 4f7fd3268cba39c8abe795780f6c4381e2f7d810 | |
| -rw-r--r-- | README.md | 7 | ||||
| -rw-r--r-- | coviddata.go | 346 |
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) +} |
