-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathweather.go
133 lines (121 loc) · 3.02 KB
/
weather.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package main
import (
"encoding/json"
"errors"
"fmt"
"log"
"net/http"
"net/url"
"time"
)
type Weather struct {
LocalObservationDateTime time.Time `json:"LocalObservationDateTime"`
EpochTime int `json:"EpochTime"`
WeatherText string `json:"WeatherText"`
WeatherIcon int `json:"WeatherIcon"`
HasPrecipitation bool `json:"HasPrecipitation"`
PrecipitationType string `json:"PrecipitationType"`
IsDayTime bool `json:"IsDayTime"`
Temperature struct {
Metric struct {
Value float64 `json:"Value"`
Unit string `json:"Unit"`
UnitType int `json:"UnitType"`
} `json:"Metric"`
Imperial struct {
Value float64 `json:"Value"`
Unit string `json:"Unit"`
UnitType int `json:"UnitType"`
} `json:"Imperial"`
} `json:"Temperature"`
MobileLink string `json:"MobileLink"`
Link string `json:"Link"`
}
type ErrResponse struct {
Code string `json:"Code"`
Message string `json:"Message"`
Reference string `json:"Reference"`
}
var (
API_KEY = "16cnkfx4543vJI1mMnV7RmXAmYAnQyrT"
locationKey string
postcode = "N2 9LU"
)
func (w Weather) String() string {
return fmt.Sprintf("%s %v℃", w.WeatherText, w.Temperature.Metric.Value)
}
func GetWeather() ([]Weather, error) {
if locationKey == "" {
var err error
locationKey, err = GetLocationCode(postcode)
if err != nil {
return nil, err
}
}
var w []Weather
u := "https://dataservice.accuweather.com/currentconditions/v1/" + locationKey
uu, err := url.Parse(u)
if err != nil {
panic(err)
}
args := uu.Query()
args.Add("apikey", API_KEY)
uu.RawQuery = args.Encode()
r, err := http.Get(uu.String())
if err != nil {
log.Println(err)
return nil, err
}
defer r.Body.Close()
left := r.Header.Get("RateLimit-Remaining")
log.Println("weather update returned", r.Status, "remaining", left)
if r.StatusCode != 200 {
var resp ErrResponse
err = json.NewDecoder(r.Body).Decode(&resp)
if err != nil {
return nil, err
}
return nil, fmt.Errorf(resp.Message)
}
err = json.NewDecoder(r.Body).Decode(&w)
return w, err
}
type locResp struct {
Key string
}
func GetLocationCode(postcode string) (string, error) {
var w []locResp
u := "http://dataservice.accuweather.com/locations/v1/postalcodes/search"
uu, err := url.Parse(u)
if err != nil {
panic(err)
}
args := uu.Query()
args.Add("apikey", API_KEY)
args.Add("q", postcode)
uu.RawQuery = args.Encode()
r, err := http.Get(uu.String())
if err != nil {
log.Println(err)
return "", err
}
defer r.Body.Close()
left := r.Header.Get("RateLimit-Remaining")
log.Println("GetLocationCode returned", r.Status, "remaining", left)
if r.StatusCode != 200 {
var resp ErrResponse
err = json.NewDecoder(r.Body).Decode(&resp)
if err != nil {
return "", err
}
return "", fmt.Errorf(resp.Message)
}
err = json.NewDecoder(r.Body).Decode(&w)
if err != nil {
return "", err
}
if len(w) == 0 {
return "", errors.New("no results")
}
return w[0].Key, nil
}