-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathfoods.go
More file actions
332 lines (285 loc) · 9.68 KB
/
foods.go
File metadata and controls
332 lines (285 loc) · 9.68 KB
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
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
package fitbit
import (
"encoding/json"
"errors"
"fmt"
"strconv"
"time"
)
// MealUnit describes the unit of a meal
type MealUnit struct {
Id uint64 `json:"id"`
Name string `json:"name"`
Plural string `json:"plural"`
}
// Meal holds all the details for a specific meal containing one or more food items
type Meal struct {
AccessLevel string `json:"accessLevel"`
Amount uint64 `json:"amount"`
Brand string `json:"brand"`
Calories uint64 `json:"calories"`
FoodId uint64 `json:"foodId"`
MealTypeId uint64 `json:"mealTypeId"`
Locale string `json:"locale"`
Name string `json:"name"`
Unit *MealUnit `json:"unit"`
Units []int `json:"units"`
}
// MealFood holds the details about a meal
type MealFood struct {
Name string `json:"name"`
Description string `json:"description"`
Id uint64 `json:"id"`
MealsFoods []*Meal `json:"mealFoods"`
}
// GetMeals is a collection of all the meals of the given user
type GetMeals struct {
Meals []*MealFood `json:"mealFoods"`
}
// GetMeals gets all the meals of the given user
// It returns an collection of Meal or an error if one occours
func (c *Client) GetMeals() (*GetMeals, error) {
//Build requestURL and GET data
responseBody, err := c.getData("user/-/meals.json")
if err != nil {
return nil, err
}
//Parse data
mealData := &GetMeals{}
err = json.NewDecoder(responseBody).Decode(mealData)
if err != nil {
return nil, err
}
return mealData, nil
}
type NutritionValues struct {
Biotin uint64 `json:"biotin"`
Calcium uint64 `json:"calcium"`
Calories uint64 `json:"calories"`
CaloriesFromFat uint64 `json:"caloriesFromFat"`
Cholesterol uint64 `json:"cholesterol"`
Copper uint64 `json:"copper"`
DietaryFiber uint64 `json:"dietaryFiber"`
FolicAcid uint64 `json:"folicAcid"`
Iodine uint64 `json:"iodine"`
Iron uint64 `json:"iron"`
Magnesium uint64 `json:"magnesium"`
Niacin uint64 `json:"niacin"`
PantothenicAcid uint64 `json:"pantothenicAcid"`
Phosphorus uint64 `json:"phosphorus"`
Potassium uint64 `json:"potassium"`
Protein uint64 `json:"protein"`
Riboflavin uint64 `json:"riboflavin"`
SaturatedFat float64 `json:"saturatedFat"`
Sodium uint64 `json:"sodium"`
Sugars uint64 `json:"sugars"`
Thiamin uint64 `json:"thiamin"`
TotalCarbohydrate uint64 `json:"totalCarbohydrate"`
TotalFat uint64 `json:"totalFat"`
TransFat uint64 `json:"transFat"`
VitaminA uint64 `json:"vitaminA"`
VitaminB12 uint64 `json:"vitaminB12"`
VitaminB6 uint64 `json:"vitaminB6"`
VitaminC uint64 `json:"vitaminC"`
VitaminD uint64 `json:"vitaminD"`
VitaminE uint64 `json:"vitaminE"`
Zinc uint64 `json:"zinc"`
}
// Food holds the details about a piece of food
type Food struct {
IsFavorite bool `json:"isFavorite"`
LogDate string `json:"logDate"`
LogID uint64 `json:"logId"`
LoggedFood *Meal `json:"loggedFood"`
NutritionValues *NutritionValues `json:"nutritionValues"`
}
// FoodGoals holds all the goals for food the user wants to achieve
type FoodGoals struct {
Calories uint64 `json:"calories"`
EstimatedCaloriesOut uint64 `json:"estamatedCaloriesOut"`
}
// GetFoods holds all the details about the foods for a specific date
type GetFoods struct {
Foods []*Food `json:"foods"`
Summary *NutritionValues `json:"summary"`
Goals *FoodGoals `json:"goals"`
}
// GetFoods gets all the foods for a specific date
// It returns an collection of Food or an error if one occours
func (c *Client) GetFoodLogs(date time.Time) (*GetFoods, error) {
//Build requestURL and GET data
requestURL := fmt.Sprintf("user/-/foods/log/date/%s.json", date.Format("2006-01-02"))
responseBody, err := c.getData(requestURL)
if err != nil {
return nil, err
}
//Parse data
foodsData := &GetFoods{}
err = json.NewDecoder(responseBody).Decode(foodsData)
if err != nil {
return nil, err
}
return foodsData, nil
}
// RecentFoods holds the details for the recent pieces of food taken by the user
type RecentFoods []*Meal
// GetRecentFoods gets all the recent foods for the given user
// It returns an collection of Food or an error if one occours
func (c *Client) GetRecentFoods() (*RecentFoods, error) {
//Build requestURL and GET data
responseBody, err := c.getData("user/-/foods/log/recent.json")
if err != nil {
return nil, err
}
//Parse data
recentFoodData := &RecentFoods{}
err = json.NewDecoder(responseBody).Decode(recentFoodData)
if err != nil {
return nil, err
}
return recentFoodData, nil
}
type FrequentFoods []*Meal
// GetFrequentFoods gets all the recent foods for the given user
// It returns an collection of Food or an error if one occours
func (c *Client) GetFrequentFoods() (*FrequentFoods, error) {
//Build requestURL and GET data
responseBody, err := c.getData("user/-/foods/log/frequent.json")
if err != nil {
return nil, err
}
//Parse data
frequentFoodData := &FrequentFoods{}
err = json.NewDecoder(responseBody).Decode(frequentFoodData)
if err != nil {
return nil, err
}
return frequentFoodData, nil
}
type Serving struct {
Multiplier uint64 `json:"multiplier"`
ServingSize uint64 `json:"servingSize"`
UnitId uint64 `json:"unitId"`
Unit *MealUnit `json:"unit"`
}
// FavoriteFoods holds all the details for every favorite piece of food of the given user
type FavoriteFoods struct {
AccessLevel string `json:"accessLevel"`
Brand string `json:"brand"`
Calories uint64 `json:"calories"`
DefaultServingSize uint64 `json:"defaultServingSize"`
FoodId uint64 `json:"foodId"`
Name string `json:"name"`
Servings []*Serving `json:"servings"`
Units []int `json:"units"`
NutritionValues *NutritionValues `json:"nutritionValues"`
}
type FavoriteFoodsArray []*FavoriteFoods
// GetFavoriteFoods gets all the recent foods for the given user
// It returns an collection of Food or an error if one occours
func (c *Client) GetFavoriteFoods() (*FavoriteFoodsArray, error) {
//Build requestURL and GET data
responseBody, err := c.getData("user/-/foods/log/favorite.json")
if err != nil {
return nil, err
}
//Parse data
favoriteFoodData := &FavoriteFoodsArray{}
err = json.NewDecoder(responseBody).Decode(favoriteFoodData)
if err != nil {
return nil, err
}
return favoriteFoodData, nil
}
type LogFood struct {
FoodLog *Food `json:"foodLog"`
}
// LogFood makes it possible to add food to the user's Fitbit account
// It returns an error if one occours
func (c *Client) LogFood(date time.Time, foodName, brandName string, foodId, mealTypeId, unitId, calories uint64, amount float64, favorite bool) (*LogFood, error) {
//Build dataArguments
dataArguments := map[string]string{
"mealTypeId": strconv.FormatUint(mealTypeId, 10),
"unitId": strconv.FormatUint(unitId, 10),
"amount": strconv.FormatFloat(amount, 'f', 2, 32),
"date": date.Format("2006-01-02"),
"favorite": strconv.FormatBool(favorite),
}
if foodId == 0 && len(foodName) == 0 {
return nil, errors.New("missing parameters")
}
if foodId > 0 {
dataArguments["foodId"] = strconv.FormatUint(foodId, 10)
} else {
dataArguments["foodName"] = foodName
//Set calories
dataArguments["calories"] = strconv.FormatUint(calories, 10)
//Set brandname
if len(brandName) > 0 {
dataArguments["brandName"] = brandName
}
}
//Buid requestURL and POST data
responseBody, err := c.postData("user/-/foods/log.json", dataArguments)
if err != nil {
return nil, err
}
//Parse data
logFoodData := &LogFood{}
err = json.NewDecoder(responseBody).Decode(logFoodData)
if err != nil {
return nil, err
}
return logFoodData, nil
}
// DeleteFood makes it possible to remove food from the user's Fitbit account
// It returns an error if one occours
func (c *Client) DeleteFood(foodId uint64) error {
//Build requestURL and DELETE data
requestURL := fmt.Sprintf("user/-/foods/log/%d.json", foodId)
_, err := c.deleteData(requestURL, nil)
if err != nil {
return err
}
return nil
}
// SearchFood contains all the results of a search query in the user's database
type SearchFood struct {
Foods []*Meal `json:"foods"`
}
// SearchFood makes it possible to search the user's food list with a query
// It returns an collection of Food or an error if one occours
func (c *Client) SearchFood(query string) (*SearchFood, error) {
//Build requestURL and GET data
requestURL := fmt.Sprintf("foods/search.json?query=%s", query)
responseBody, err := c.getData(requestURL)
//Parse data
searchFoodData := &SearchFood{}
err = json.NewDecoder(responseBody).Decode(searchFoodData)
if err != nil {
return nil, err
}
return searchFoodData, nil
}
// AddFavoriteFood adds a record to the list of favorite foods of the given user
// It returns an error if one occours
func (c *Client) AddFavoriteFood(foodId uint64) error {
//Build requestURL and POST data
requestURL := fmt.Sprintf("user/-/foods/log/favorite/%d.json", foodId)
_, err := c.postData(requestURL, nil)
if err != nil {
return err
}
return nil
}
// DeleteFavoriteFood removes a record from the list of favorite foods of the given user
// It returns an error if one occours
func (c *Client) DeleteFavoriteFood(foodId uint64) error {
//Build requestURL and POST data
requestURL := fmt.Sprintf("user/-/foods/log/favorite/%d.json", foodId)
_, err := c.deleteData(requestURL, nil)
if err != nil {
return err
}
return nil
}