-
Notifications
You must be signed in to change notification settings - Fork 0
/
meteocat.go
237 lines (207 loc) · 5.89 KB
/
meteocat.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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
package meteocat
import (
"errors"
"fmt"
"net/http"
)
var errEstacioUnavailable = errors.New("station code unavailable")
var errVariableUnavailable = errors.New("variable code unavailable")
var errInvalidKey = errors.New("invalid api key")
var errInvalidOption = errors.New("invalid option")
var errInvalidHttpClient = errors.New("invalid http client")
// DataUnits represents the character chosen to represent the temperature notation
// var DataUnits = map[string]string{"C": "metric"}
var (
baseURL = "https://api.meteo.cat/xema/v1%s"
url string // helper variable to hold url values
sFlag bool // helper variable to check where to handle JSON that varies between an array or a single item
// Its worth to note that the single item corresponds to a lecture of a single station whereas an array is a lecture
// containing data of all stations. See the endpoint of MeasurementByDay function.
)
// Config will hold default settings
type Config struct {
APIKey string // API Key for connecting to the OWM
}
// Data struct holds the time settings in general the time format will be YYYY/MM/D or YYYY-MM-DZ but this is transparent
// for the final user.
type Data struct {
Any string
Mes string
Dia string
}
type TimeDate struct {
Hour string
Minute string
Seconds string
Milliseconds string
}
// Parameters holds all the options to be passed in to the methods
type Parameters struct {
codiEstacio string // should reference a key in the CodisEstacions map
codiVariable string // should reference a key in the CodisVariables map
codiEstat string // should reference a key in the CodisEstat map
Data
TimeDate
}
// NewParameters generates a new Parameters config.
func NewParameters(options ...func(*Parameters) error) (*Parameters, error) {
p := &Parameters{}
// Default values...
p.codiEstacio = ""
p.codiVariable = ""
p.codiEstat = ""
p.Any = ""
p.Mes = ""
p.Dia = ""
// Option paremeters values:
for _, op := range options {
err := op(p)
if err != nil {
return nil, err
}
}
return p, nil
}
// OptionCodiEstat is a helper function to set up the value of CodiEstat to be passed in Parameters struct
func OptionCodiEstat(codiEstat string) func(p *Parameters) error {
return func(p *Parameters) error {
p.codiEstat = codiEstat
return nil
}
}
// OptionCodiEstacio is a helper function to set up the value of CodiEstacio to be passed in Parameters struct
func OptionCodiEstacio(codiEstacio string) func(p *Parameters) error {
return func(p *Parameters) error {
p.codiEstacio = codiEstacio
return nil
}
}
// OptionCodiVariable is a helper function to set up the value of CodiVariable to be passed in Parameters struct
func OptionCodiVariable(codiVariable string) func(p *Parameters) error {
return func(p *Parameters) error {
p.codiVariable = codiVariable
return nil
}
}
// OptionData is a helper function to set up the value of Data to be passed in Parameters struct
func OptionData(d Data) func(p *Parameters) error {
return func(p *Parameters) error {
p.Any = d.Any
p.Mes = d.Mes
p.Dia = d.Dia
return nil
}
}
// Option TimeData is a helper function to set up the value of Timedate to be passed in Parameters struct
func OptionTimeDate(d TimeDate) func(p *Parameters) error {
return func(p *Parameters) error {
p.Hour = d.Hour
p.Minute = d.Minute
p.Seconds = d.Seconds
p.Milliseconds = d.Milliseconds
return nil
}
}
// APIError returned on failed API calls.
type APIError struct {
Message string `json:"message"`
COD string `json:"cod"`
}
// ApiKey setter function to be passed in the Settings struct, necessary to perform the request
func setKey(key string) (string, error) {
if err := ValidAPIKey(key); err != nil {
return "", err
}
return key, nil
}
// ValidData validates that we set a correct data
func ValidData(d Data) bool {
if d.Mes != "" && d.Any != "" && d.Dia != "" {
return true
} else if d.Mes == "" || d.Any == "" || d.Dia == "" {
fmt.Println("To use the data parameter all the fields must be filled. Leave empty if its not used")
}
return false
}
// ValidAPIKey makes sure that the key given is a valid one
func ValidAPIKey(key string) error {
if len(key) != 40 {
return errors.New("invalid key")
}
return nil
}
// ValidCodiEstat makes sure the string passed in is an
// acceptable estat code.
func ValidCodiEstat(c string) bool {
for d := range CodisEstat {
if c == d {
return true
}
}
return false
}
// ValidCodiEstacio makes sure the string passed in is an
// acceptable station code.
func ValidCodiEstacio(c string) bool {
for d := range CodisEstacions {
if c == d {
return true
}
}
return false
}
// ValidCodiVariable makes sure the string passed in is an
// acceptable variable code.
func ValidCodiVariable(c string) bool {
for d := range CodisVariables {
if c == d {
return true
}
}
return false
}
// CheckAPIKeyExists will see if an API key has been set.
func CheckAPIKeyExists(apiKey string) bool { return len(apiKey) > 1 }
// Settings holds the client settings
type Settings struct {
client *http.Client
req *http.Request
//cr *resty.Client
}
// NewSettings returns a new Setting pointer with default http client.
func NewSettings() *Settings {
return &Settings{
client: http.DefaultClient,
}
}
//func OptionURL(url string) Option {
// return func(s *Settings) error {
// s.url = url
// return nil
// }
//}
// Optional client settings
type Option func(s *Settings) error
// // WithHttpClient sets custom http client when creating a new Client.
func WithHttpClient(c *http.Client) Option {
return func(s *Settings) error {
if c == nil {
return errInvalidHttpClient
}
s.client = c
return nil
}
}
// setOptions sets Optional client settings to the Settings pointer
func setOptions(settings *Settings, options []Option) error {
for _, option := range options {
if option == nil {
return errInvalidOption
}
err := option(settings)
if err != nil {
return err
}
}
return nil
}