Skip to content
This repository has been archived by the owner on Jan 29, 2023. It is now read-only.

Commit

Permalink
Feat: Add filter by GeoIP
Browse files Browse the repository at this point in the history
Added a new filter based on your IP to get your country.
  • Loading branch information
renanbastos93 committed Apr 12, 2020
1 parent 5101be0 commit e0b86a4
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 23 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,5 @@ bin
cover
alertcovid19
coverage.html
dist
dist
*.zip
69 changes: 51 additions & 18 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,37 +5,44 @@ import (
"encoding/json"
"flag"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
"time"

"github.com/gen2brain/beeep"
)

// Exported ...
const (
IMG string = "https://static.poder360.com.br/2020/03/23312-868x644.png"
URL = "https://covid19-brazil-api.now.sh/api/report/v1/brazil"
myIP = "http://ip-api.com/json"
IMG = "https://static.poder360.com.br/2020/03/23312-868x644.png"
URL = "https://corona.lmao.ninja/countries/"
StateBrazil = "https://covid19-brazil-api.now.sh/api/report/v1/brazil/uf/"
TIMEOUT = time.Second * 2
)

type geoIP struct {
CountryCode string `json:"countryCode"`
Region string `json:"region"`
}

// LastValues ...
type LastValues struct {
Confirmed int `json:"confirmed"`
Cases int `json:"cases"`
Deaths int `json:"deaths"`
Recovered int `json:"recovered"`
}

func (l LastValues) String() string {
return fmt.Sprintf("Confirmed: %d, Deaths: %d, Recovered: %d", l.Confirmed, l.Deaths, l.Recovered)
message := "Cases: %d, Deaths: %d, Recovered: %d"
return fmt.Sprintf(message, l.Cases, l.Deaths, l.Recovered)
}

// fetch runs on its own goroutine
func fetch(ctx context.Context, req *http.Request, ch chan LastValues) error {
defer close(ch)
var r struct {
Data LastValues `json:"data"`
}
var r LastValues
body, err := http.DefaultClient.Do(req)
if err != nil {
log.Printf("fetchCOVID19Data: %v", err)
Expand All @@ -48,33 +55,38 @@ func fetch(ctx context.Context, req *http.Request, ch chan LastValues) error {
return err
}

bodyBytes, _ := ioutil.ReadAll(body.Body)
log.Println("WOOW: :: ", string(bodyBytes))

select {
case ch <- LastValues{r.Data.Confirmed, r.Data.Deaths, r.Data.Recovered}:
case ch <- LastValues{r.Cases, r.Deaths, r.Recovered}:
case <-ctx.Done():
}
return nil
}

// fetchCOVID19Data ...
func fetchCOVID19Data(ctx context.Context) <-chan LastValues {
func fetchCOVID19Data(ctx context.Context, country string) <-chan LastValues {
ch := make(chan LastValues)
req, err := http.NewRequestWithContext(ctx, "GET", URL, nil)
url := URL + country
log.Println("URL ::: ", url)
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
panic("internal error - misuse of NewRequestWithContext")
}
go fetch(ctx, req, ch)
return ch
}

func routine(sleep time.Duration) {
func routine(sleep time.Duration, country string) {
cachedVal := LastValues{}
const timeout = time.Second * 2
for {
ctx, cancel := context.WithTimeout(context.Background(), timeout)
ctx, cancel := context.WithTimeout(context.Background(), TIMEOUT)
select {
case newVal := <-fetchCOVID19Data(ctx):
case newVal := <-fetchCOVID19Data(ctx, country):
log.Println("newval :: ", newVal)
if cachedVal != newVal {
err := beeep.Alert("COVID-19 Brazil", newVal.String(), IMG)
err := beeep.Alert("COVID-19 "+country, newVal.String(), IMG)
if err != nil {
log.Printf("rountine: %v", err)
}
Expand All @@ -89,11 +101,32 @@ func routine(sleep time.Duration) {
}
}

func getCountryByGeoIP() geoIP {
client := http.Client{Timeout: TIMEOUT}
resp, err := client.Post(
myIP,
"application/json; charset=utf8",
nil,
)
if err != nil {
log.Fatal(err)
}
defer resp.Body.Close()
var ip geoIP
err = json.NewDecoder(resp.Body).Decode(&ip)
if err != nil {
log.Fatalf("Oops, we cannot get your location, please verify your network.")
}
log.Println("IP :: ", ip)
return ip
}

func main() {
log.SetPrefix(os.Args[0] + ": ")
// log.SetPrefix(os.Args[0] + ": ")
log.SetFlags(0)
var timer time.Duration
flag.DurationVar(&timer, "t", time.Hour, "interval between each api request")
flag.Parse()
routine(timer)
ip := getCountryByGeoIP()
routine(timer, ip.CountryCode)
}
8 changes: 4 additions & 4 deletions main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@ func TestLastValues_String(t *testing.T) {
{
name: "Test format message to show in the notification",
fields: LastValues{
Confirmed: 100,
Cases: 100,
Deaths: 7,
Recovered: 1,
},
want: "Confirmed: 100, Deaths: 7, Recovered: 1",
want: "Cases: 100, Deaths: 7, Recovered: 1",
},
}
for _, v := range tests {
Expand All @@ -42,8 +42,8 @@ func TestFetch(t *testing.T) {
input io.Reader
want bool
}{
{"ok json", strings.NewReader(`{"data": {"confirmed": 10, "deaths": 10, "recovered": 10}}`), true},
{"bad json", strings.NewReader(`{"data": "confirmed": 10, "deaths": 10, "recovered": 10}}`), false},
{"ok json", strings.NewReader(`{"data": {"cases": 10, "deaths": 10, "recovered": 10}}`), true},
{"bad json", strings.NewReader(`{"data": "cases": 10, "deaths": 10, "recovered": 10}}`), false},
}
for _, v := range tests {
v := v
Expand Down

0 comments on commit e0b86a4

Please sign in to comment.