|
1 | 1 | package openweathermap |
2 | 2 |
|
| 3 | +import ( |
| 4 | + "errors" |
| 5 | + "fmt" |
| 6 | + "net/http" |
| 7 | + "time" |
| 8 | + "io/ioutil" |
| 9 | + "encoding/json" |
| 10 | +) |
| 11 | + |
3 | 12 | /* |
4 | 13 | Define API response fields |
5 | 14 | */ |
6 | 15 | type OpenWeatherMap struct { |
7 | 16 | API_KEY string |
8 | 17 | } |
9 | 18 |
|
10 | | -type coord struct { |
11 | | - lon int |
12 | | - lat int |
| 19 | +type City struct { |
| 20 | + Id int `json:"id"` |
| 21 | + Name string `json:"name"` |
| 22 | +} |
| 23 | + |
| 24 | +type Coord struct { |
| 25 | + Lon float64 `json:"lon"` |
| 26 | + Lat float64 `json:"lat"` |
13 | 27 | } |
14 | 28 |
|
15 | | -type weather struct { |
16 | | - id int |
17 | | - main string |
18 | | - description string |
| 29 | +type Weather struct { |
| 30 | + Id int `json:"id"` |
| 31 | + Main string `json:"main"` |
| 32 | + Description string `json:"description"` |
19 | 33 | } |
20 | 34 |
|
21 | | -type wind struct { |
22 | | - speed float64 |
23 | | - deg float64 |
| 35 | +type Wind struct { |
| 36 | + Speed float64 `json:"speed"` |
| 37 | + Deg float64 `json:"deg"` |
24 | 38 | } |
25 | 39 |
|
26 | | -type clouds struct { |
27 | | - all int |
| 40 | +type Clouds struct { |
| 41 | + All int `json:"all"` |
28 | 42 | } |
29 | 43 |
|
30 | | -type rain struct { |
31 | | - threehr int `json:"3h"` |
| 44 | +type Rain struct { |
| 45 | + Threehr int `json:"3h"` |
32 | 46 | } |
33 | 47 |
|
34 | | -type visibility string |
| 48 | +type Visibility string |
| 49 | + |
| 50 | +type Dt int |
| 51 | + |
| 52 | +type Id int |
| 53 | + |
| 54 | +type Name string |
35 | 55 |
|
36 | | -type dt int |
| 56 | +type Country string |
37 | 57 |
|
38 | | -type id int |
| 58 | +type Main struct { |
| 59 | + Temp float64 `json:"temp"` |
| 60 | + Pressure int `json:"pressure"` |
| 61 | + Humidity int `json:"humidity"` |
| 62 | + Temp_min float64 `json:"temp_min"` |
| 63 | + Temp_max float64 `json:"temp_max"` |
| 64 | +} |
| 65 | + |
| 66 | +/* |
| 67 | +Define API response objects (compose of the above fields) |
| 68 | + */ |
39 | 69 |
|
40 | | -type name string |
| 70 | +type CurrentWeatherResponse struct { |
| 71 | + Coord `json:"coord"` |
| 72 | + Weather []Weather `json:"weather"` |
| 73 | + Main `json:"main"` |
| 74 | + Wind `json:"wind"` |
| 75 | + Rain `json:"rain"` |
| 76 | + Clouds `json:"clouds"` |
| 77 | + Dt `json:"dt"` |
| 78 | + Id `json:"id"` |
| 79 | + Name `json:"name"` |
| 80 | +} |
41 | 81 |
|
42 | | -type main struct { |
43 | | - temp float64 |
44 | | - pressure int |
45 | | - humidity int |
46 | | - temp_min float64 |
47 | | - temp_max float64 |
| 82 | +type ForecastResponse struct { |
| 83 | + City `json:"city"` |
| 84 | + Coord `json:"coord"` |
| 85 | + Country `json:"country"` |
| 86 | + List [] struct { |
| 87 | + Dt `json:"dt"` |
| 88 | + Main `json:"main"` |
| 89 | + Weather `json:"weather"` |
| 90 | + Clouds `json:"clouds"` |
| 91 | + Wind `json:"wind"` |
| 92 | + } `json:"list"` |
48 | 93 | } |
49 | 94 |
|
50 | | -type forecastResponse struct { |
51 | | - city struct { |
52 | | - id int |
53 | | - name string |
| 95 | +const ( |
| 96 | + API_URL string = "api.openweathermap.org" |
| 97 | +) |
| 98 | + |
| 99 | +func (owm *OpenWeatherMap) CurrentWeatherFromCity(city string) (*CurrentWeatherResponse, error) { |
| 100 | + if (owm.API_KEY == "") { |
| 101 | + // No API keys present, return error |
| 102 | + return nil, errors.New("No API keys present") |
54 | 103 | } |
55 | | - coord |
56 | | - |
57 | | - country string |
58 | | - cnt int |
59 | | - list [] struct { |
60 | | - dt string |
61 | | - main struct { |
62 | | - temp float64 |
63 | | - temp_min float64 |
64 | | - temp_max float64 |
65 | | - humidity float64 |
66 | | - } |
67 | | - weather []weather |
68 | | - |
69 | | - clouds struct { |
70 | | - all int |
71 | | - } |
72 | | - wind struct { |
73 | | - speed float64 |
74 | | - deg float64 |
75 | | - } |
| 104 | + url := fmt.Sprintf("http://%s/data/2.5/weather?q=%s&units=imperial&APPID=%s", API_URL, city, owm.API_KEY) |
| 105 | + |
| 106 | + // Build an http client so we can have control over timeout |
| 107 | + client := &http.Client{ |
| 108 | + Timeout: time.Second * 2, |
76 | 109 | } |
77 | | -} |
78 | 110 |
|
79 | | -func (owm *OpenWeatherMap) currentWeather() { |
| 111 | + res, getErr := client.Get(url) |
| 112 | + if getErr != nil { |
| 113 | + return nil, getErr |
| 114 | + } |
| 115 | + |
| 116 | + // defer the closing of the res body |
| 117 | + defer res.Body.Close() |
| 118 | + |
| 119 | + // read the http response body into a byte stream |
| 120 | + body, readErr := ioutil.ReadAll(res.Body) |
| 121 | + if readErr != nil { |
| 122 | + return nil, readErr |
| 123 | + } |
80 | 124 |
|
| 125 | + fmt.Println(string(body)) |
| 126 | + |
| 127 | + var cwr CurrentWeatherResponse |
| 128 | + |
| 129 | + // unmarshal the byte stream into a Go data type |
| 130 | + jsonErr := json.Unmarshal(body, &cwr) |
| 131 | + if jsonErr != nil { |
| 132 | + return nil, jsonErr |
| 133 | + } |
| 134 | + |
| 135 | + return &cwr, nil |
81 | 136 | } |
| 137 | + |
0 commit comments