Documentation ¶
Overview ¶
Package app contains the core functionality of the aplication.
This package makes heavy use of the Command pattern: Functions are encapsulated in individual small structs that do exactly one thing and nothing else. The Command and Query types are both commands in this sense, their names reflecting whether they perform read (query) or write (command) actions.
Index ¶
- Constants
- Variables
- type AccountPrefs
- type Activate
- type AddDiaryEntries
- type Authenticate
- type Authorize
- type ChangeName
- type ChangePassword
- type Command
- type CreateFood
- type CreateRecipe
- type CreateUser
- type Crypter
- type DB
- type DeleteUser
- type DiaryDays
- type DiaryEntries
- type GetFood
- type GetFoods
- type Log
- type Logger
- type MacroPrefs
- type Notification
- type NotificationData
- type Notifier
- type Preferences
- type Prefs
- type Query
- type RDIPrefs
- type Recipe
- type RecipeAccess
- type RecipeInstructions
- type Recipes
- type RequestEmailChange
- type ResetPassword
- type SaveDiaryEntries
- type SaveFood
- type SaveIngredient
- type SavePreferences
- type SaveRecipe
- type SaveRecipeAccess
- type SaveRecipeInstructions
- type SaveShoppingListDone
- type ShoppingList
- type StoredPrefs
- type SwitchLanguage
- type Token
- type Tokenizer
- type Translator
- type UIPrefs
- type User
- type Validator
Constants ¶
const ( PermNone = 0x00000000 PermLogin = 0x00000001 PermCreate = 0x00000100 PermRead = 0x00000200 PermEdit = 0x00000400 PermDelete = 0x00000800 PermOwner = PermCreate | PermRead | PermEdit | PermDelete PermCreateFood = 0x00010000 PermEditFood = 0x00020000 PermAdmin = PermCreateFood | PermEditFood )
Variables ¶
Functions ¶
This section is empty.
Types ¶
type AccountPrefs ¶
AccountPrefs holds all user settings directly related to the user's account.
type Activate ¶
type Activate struct {
Token string
}
Activate is a command to unlock a user's ability to log into the application and to change their e-mail address after a change request was issued. If successful, the token is deleted and cannot be used again.
type AddDiaryEntries ¶
type AddDiaryEntries struct { Date time.Time Food []core.DiaryEntry ID int }
AddDiaryEntries is a command to add several food items to the diary identified by ID and the day identified by Date. If any of the food already exists, the amount is added on top, otherwise a new entry is created.
Any food with an amount of 0 or a date that does not actually fall on the same day with Date is silently dropped.
func (*AddDiaryEntries) Execute ¶
func (c *AddDiaryEntries) Execute(db DB) error
type Authenticate ¶
Authenticate is a query that authenticates a user by checking against e-mail and password. If successful, the user's id, language, and permissions are stored in the command.
func (*Authenticate) Fetch ¶
func (q *Authenticate) Fetch(db DB) error
type Authorize ¶
Authorize is a query that issues a challenge to pass in order to make sure a user identified by ID has the right to perform a given action. It is intentionally not tied to a specific action or resource. The type of challenge is expressed through the fields of the query.
If successful, the Ok field will be set to true. There is no error if the challenge itself fails, so you still have to check Ok to ultimately know the final result.
Supported types of challenges are:
- Password: Make sure the user is still the same user by asking for the password again. This type of challenge is often issued before dangerous actions or those with far-reaching consequences.
type ChangeName ¶
ChangeName is a command to assign a new user name to the user identified by ID. The name is randomly generated. If successful, Name contains the new name.
func (*ChangeName) Execute ¶
func (c *ChangeName) Execute(db DB) error
type ChangePassword ¶
ChangePassword is a command to change a registered user's password. It expects either the ID or the Token field to be set, where ID points to a valid user id or the token can be used to retrieve such an id.
func (*ChangePassword) Execute ¶
func (c *ChangePassword) Execute(db DB) error
type Command ¶
A Command encapsulates a single action that changes the underlying data. It can carry input and output parameters.
type CreateFood ¶
CreateFood is a command to create a new food item in the food database. If successful, the new item id is stored in the command.
func (*CreateFood) Execute ¶
func (c *CreateFood) Execute(db DB) error
type CreateRecipe ¶
CreateRecipe is a command to create a new named recipe in the food database. If successful, the new item is stored in the command.
func (*CreateRecipe) Execute ¶
func (c *CreateRecipe) Execute(db DB) error
type CreateUser ¶
CreateUser is a command to create a new user with a unique id and e-mail address. If successful, the new user's id is stored in the command.
func (*CreateUser) Execute ¶
func (c *CreateUser) Execute(db DB) error
type Crypter ¶
Crypter decrypts and encrypts passwords.
func NewCrypter ¶
func NewCrypter() Crypter
NewCrypter returns a default implementation of the Crypter interface. The cost parameter is used for the cost of the underlying hash function.
type DB ¶
type DB interface { Execute(Command) error Fetch(Query) error NewUser(email, hash, token string) (int, error) SetUser(User) error DelUser(id int) error UserByEmail(email string) (User, error) UserByName(name string) (User, error) UserByID(id int) (User, error) UserNames(prefix string) ([]string, error) SetUserPrefs(id int, prefs StoredPrefs) error UserPrefs(id int) (StoredPrefs, error) NewToken(id int, hash string, data interface{}) error DelToken(string) error Token(string) (Token, error) NewFood() (int, error) SetFood(core.Food) error Food(id int) (core.Food, error) Foods(core.Filter) ([]core.Food, error) FoodExists(id int) (bool, error) NewRecipe(string) (int, error) SetRecipe(core.Recipe) error SetRecipeAccess(user, rec, perms int) error SetRecipeInstructions(id int, text string) error DelRecipeInstructions(id int) error Recipe(id int) (core.Recipe, error) Recipes(uid int, f core.Filter) ([]core.Recipe, error) RecipeAccess(user, rec int) (int, error) RecipeInstructions(id int) (string, error) NewDiaryEntries(id int, entries ...core.DiaryEntry) error SetDiaryEntries(id int, entries ...core.DiaryEntry) error DelDiaryEntries(id int, entries ...core.DiaryEntry) error DiaryEntries(id int, date time.Time) ([]core.DiaryEntry, error) DiaryDays(id, year, month, day int) ([]core.DiaryDay, error) SetShoppingListDone(id int, done map[int]bool) error ShoppingList(id int, date ...time.Time) ([]core.ShopItem, error) }
DB provides access to persistent storage.
type DeleteUser ¶
type DeleteUser struct {
ID int
}
DeleteUser is a command to delete an existing user from the system. No error is returned if the user doesn't exist.
func (*DeleteUser) Execute ¶
func (c *DeleteUser) Execute(db DB) error
type DiaryDays ¶
DiaryDays is a query to fetch diary summaries for all days that fit the Year and Month query fields. The diary that is searched belongs to the user identified by ID.
type DiaryEntries ¶
type DiaryEntries struct { Date time.Time Entries []core.DiaryEntry ID int }
DiaryEntries is a query to fetch diary entries for a given date and a user identified by ID from the food database.
func (*DiaryEntries) Fetch ¶
func (q *DiaryEntries) Fetch(db DB) error
type GetFood ¶
GetFood is a query to retrieve a single food item from the food database. The item's ID is expected to be set before the query is executed.
type MacroPrefs ¶
type MacroPrefs struct { KCal float32 `json:"kcal"` Fat float32 `json:"fat"` Carbs float32 `json:"carb"` Protein float32 `json:"prot"` }
MacroPrefs holds all user settings related to personal macronutrient targets.
func BaseMacroPrefs ¶
func BaseMacroPrefs() [7]MacroPrefs
This contains the average recommended macro targets for an average human being. Implemented as a function to ensure constness.
func EmptyMacroPrefs ¶
func EmptyMacroPrefs() [7]MacroPrefs
This contains all zeroed-out macro targets and represents the weekly macro prefs' zero value. Implemented as a function to ensure constness.
type Notification ¶
type Notification int
const ( RegisterNotification Notification = iota + 1 RenameNotification ResetNotification )
type NotificationData ¶
type NotificationData map[string]interface{}
type Notifier ¶
type Notifier interface {
Send(to string, msg Notification, data NotificationData) error
}
Notifier provides functions for sending messages to users of the application.
type Preferences ¶
Preferences is a query to collect all user preferences from the database. If successful, the Prefs field will contain all preferences that were found.
As long as the user exists, a valid set of preferences will be generated. For users who never changed their settings in any way, this is identical to the set of default preferences.
func (*Preferences) Fetch ¶
func (q *Preferences) Fetch(db DB) error
type Prefs ¶
type Prefs struct { Account AccountPrefs `json:"account"` Macros [7]MacroPrefs `json:"macros"` RDI RDIPrefs `json:"rdi"` UI UIPrefs `json:"ui"` }
Prefs holds all individual preferences types and is the object that gets passed around the application.
type Query ¶
A Query encapsulates a single read action on the underlying data. It should not make any changes to the data. It can carry input and output parameters.
type RDIPrefs ¶
type RDIPrefs struct { FatSat float32 `json:"fatsat"` FatO3 float32 `json:"fato3"` FatO6 float32 `json:"fato6"` Fiber float32 `json:"fib"` Salt float32 `json:"salt"` Potassium float32 `json:"pot"` Chlorine float32 `json:"chl"` Sodium float32 `json:"sod"` Calcium float32 `json:"calc"` Phosphorus float32 `json:"phos"` Magnesium float32 `json:"mag"` Iron float32 `json:"iron"` Zinc float32 `json:"zinc"` Manganse float32 `json:"mang"` Copper float32 `json:"cop"` Iodine float32 `json:"iod"` Chromium float32 `json:"chr"` Molybdenum float32 `json:"mol"` Selenium float32 `json:"sel"` VitA float32 `json:"vita"` VitB1 float32 `json:"vitb1"` VitB2 float32 `json:"vitb2"` VitB3 float32 `json:"vitb3"` VitB5 float32 `json:"vitb5"` VitB6 float32 `json:"vitb6"` VitB7 float32 `json:"vitb7"` VitB9 float32 `json:"vitb9"` VitB12 float32 `json:"vitb12"` VitC float32 `json:"vitc"` VitD float32 `json:"vitd"` VitE float32 `json:"vite"` VitK float32 `json:"vitk"` }
RDIPrefs holds all user settings related to the recommended daily intake of various nutrients.
func BaseRDIPrefs ¶
func BaseRDIPrefs() RDIPrefs
This contains an average person's recommended daily intake for all the nutrients tracked by the system. It should be multiplied by values computed from a person's specific body composition and living circumstances in order to represent a correct estimation of their actual needs. Implemented as a function to ensure constness.
type Recipe ¶
Recipe is a query to retrieve a single recipe from the food database. The item's ID is expected to be set before the query is executed.
type RecipeAccess ¶
RecipeAccess is a query that fetches a user's access rights for a given recipe. If successful, the permission value is stored in the query.
func (*RecipeAccess) Fetch ¶
func (q *RecipeAccess) Fetch(db DB) error
func (*RecipeAccess) HasPerms ¶
func (q *RecipeAccess) HasPerms(perms int) bool
type RecipeInstructions ¶
RecipeInstructions is a query that fetches preparation instructions for a given recipe. If successful, the text is stored in the query.
func (*RecipeInstructions) Fetch ¶
func (q *RecipeInstructions) Fetch(db DB) error
type RequestEmailChange ¶
RequestEmailChange is a command to start the process of changing a user's e-mail address. When successful, the Token field contains a token that can be used to confirm and complete the request.
func (*RequestEmailChange) Execute ¶
func (c *RequestEmailChange) Execute(db DB) error
type ResetPassword ¶
ResetPassword is a command to create a password reset token that allows an anonymous user to change the password that's associated with a registered user.
func (*ResetPassword) Execute ¶
func (c *ResetPassword) Execute(db DB) error
type SaveDiaryEntries ¶
type SaveDiaryEntries struct { Date time.Time Food []core.DiaryEntry ID int }
SaveDiaryEntries is a command to update existing food items in the diary identified by ID with the given amount. The old amount is always replaced with the new one.
Any food with an amount of 0 will be removed from the database. Any food with a date that does not fall on the same day with Date is silently dropped.
func (*SaveDiaryEntries) Execute ¶
func (c *SaveDiaryEntries) Execute(db DB) error
type SaveFood ¶
SaveFood is a command that changes the specified values of a food item identified by ID.
type SaveIngredient ¶
SaveIngredient is a command to make changes to a recipe's list of ingredients. If Amount is 0, the ingredient will be removed from the recipe, otherwise it will be added or updated. If Replace is true, it will replace the current amount, otherwise it will add to it. In any case, the recipe's cached nutrients will be recalculated after the operation.
func (*SaveIngredient) Execute ¶
func (c *SaveIngredient) Execute(db DB) error
type SavePreferences ¶
SavePreferences is a command to store all user preferences in the database. If successful, the Prefs field will contain an updated set of preferences. When the command fails, the value of Prefs is undefined and should not be relied on!
func (*SavePreferences) Execute ¶
func (c *SavePreferences) Execute(db DB) error
type SaveRecipe ¶
SaveRecipe is a command that upates a recipe's data, including the name and the number of servings but never the list of ingredients.
func (*SaveRecipe) Execute ¶
func (c *SaveRecipe) Execute(db DB) error
type SaveRecipeAccess ¶
SaveRecipeAccess is a command that changes a user's access rights for a given recipe.
func (*SaveRecipeAccess) Execute ¶
func (c *SaveRecipeAccess) Execute(db DB) error
type SaveRecipeInstructions ¶
SaveRecipeInstructions is a command to make changes to a recipe's preparation instructions. An empty instructions string will delete the instructions for this recipe along with all associated data like images and videos.
NOTE: images and video storage for recipe instructions is not yet implemented as of 2024-02-22.
func (*SaveRecipeInstructions) Execute ¶
func (c *SaveRecipeInstructions) Execute(db DB) error
type SaveShoppingListDone ¶
func (*SaveShoppingListDone) Execute ¶
func (c *SaveShoppingListDone) Execute(db DB) error
type ShoppingList ¶
func (*ShoppingList) Fetch ¶
func (q *ShoppingList) Fetch(db DB) error
type StoredPrefs ¶
type StoredPrefs struct { Macros [7]MacroPrefs `json:"macros"` UIPrefs }
StoredPrefs contains preferences that cannot be inferred from other objects. These are the absolute minimum that need to be stored in persistent storage in order to reconstruct a complete set of user preferences.
Most notably, we really don't want to store individual RDI values because doing so would bloat the stored data size with largely the same values for most users.
type SwitchLanguage ¶
SwitchLanguage is a command to change a user's UI language preference.
func (*SwitchLanguage) Execute ¶
func (c *SwitchLanguage) Execute(db DB) error
type Token ¶
type Token struct { Data interface{} `json:"data,omitempty"` ID int `json:"id"` }
Token is a piece of data used for anonymous authorization.
type Tokenizer ¶
type Tokenizer interface {
Create() string
}
Tokenizer creates cryptographically secure tokens.
func NewTokenizer ¶
func NewTokenizer() Tokenizer
NewTokenizer returns a default implementation of the Tokenizer interface.
type Translator ¶
type Translator interface { Translate(input interface{}, lang string) string Get(lang string) map[string]interface{} Default() string }
Translator defines functions for text localization.
type UIPrefs ¶
type UIPrefs struct { NeutralCharts bool `json:"neutralCharts"` TrackSaltAsSodium bool `json:"trackSaltAsSodium"` }
UIPrefs holds all user settings related to the presentation of data in a client application. It contains options for filtering, sorting, and display preferences.
type User ¶
type User struct { Email string `json:"email"` Name string `json:"name"` Pass string `json:"pass"` Lang string `json:"lang"` Perm int `json:"perm"` ID int `json:"id"` }
User represents a human user of the system, identified by their e-mail address or id. The password is always stored as an encrypted hash.
type Validator ¶
type Validator struct {
// contains filtered or unexported fields
}
Validator provides validation for different types of user input.
func (Validator) MatchEmail ¶
MatchEmail returns true when s is a valid e-mail address.