Documentation ¶
Index ¶
- Constants
- Variables
- func Connect(driver, dsn string, debug bool, logger *slog.Logger) (*gorm.DB, error)
- func GetDateLimitExpression(sqlDialect string) string
- func NewMemoryCache() *caches.Caches
- func RouteSegmentFromPoints(workout *Workout, params *RoutSegmentCreationParams) ([]byte, error)
- type BreakdownItem
- type Bucket
- type Buckets
- type Config
- type DurationRecord
- type EnvConfig
- type Equipment
- type ExtraMetrics
- type Float64Record
- type GPXData
- type MapCenter
- type MapData
- type MapDataDetails
- type MapPoint
- type Model
- type Profile
- type RoutSegmentCreationParams
- type RouteSegment
- func AddRouteSegment(db *gorm.DB, notes string, filename string, content []byte) (*RouteSegment, error)
- func GetRouteSegment(db *gorm.DB, id int) (*RouteSegment, error)
- func GetRouteSegments(db *gorm.DB) ([]*RouteSegment, error)
- func NewRouteSegment(notes string, filename string, content []byte) (*RouteSegment, error)
- func (rs *RouteSegment) Address() string
- func (rs *RouteSegment) Create(db *gorm.DB) error
- func (rs *RouteSegment) Delete(db *gorm.DB) error
- func (rs *RouteSegment) FindMatches(workouts []*Workout) []*RouteSegmentMatch
- func (rs *RouteSegment) HasFile() bool
- func (rs *RouteSegment) MarkdownNotes() string
- func (rs *RouteSegment) Match(workout *Workout) *RouteSegmentMatch
- func (rs *RouteSegment) MatchSegment(workout *Workout, start int, forward bool) (int, bool)
- func (rs *RouteSegment) NewRouteSegmentMatch(workout *Workout, p, last int) *RouteSegmentMatch
- func (rs *RouteSegment) Save(db *gorm.DB) error
- func (rs *RouteSegment) StartingPoints(points []MapPoint) []int
- func (rs *RouteSegment) UpdateFromContent() error
- type RouteSegmentMatch
- type StatConfig
- type Statistics
- type User
- func (u *User) APIActive() bool
- func (u *User) AddSalt(password string) string
- func (u *User) AddWorkout(db *gorm.DB, workoutType WorkoutType, notes string, filename string, ...) (*Workout, error)
- func (u *User) BeforeSave(_ *gorm.DB) error
- func (u *User) Create(db *gorm.DB) error
- func (u *User) Delete(db *gorm.DB) error
- func (u *User) GenerateAPIKey(force bool)
- func (u *User) GenerateSalt()
- func (u *User) GetAllEquipment(db *gorm.DB) ([]*Equipment, error)
- func (u *User) GetAllRecords() ([]*WorkoutRecord, error)
- func (u *User) GetContext() context.Context
- func (u *User) GetDefaultStatistics() (*Statistics, error)
- func (u *User) GetDefaultTotals() (*Bucket, error)
- func (u *User) GetEquipment(db *gorm.DB, id int) (*Equipment, error)
- func (u *User) GetHighestWorkoutType() (*WorkoutType, error)
- func (u *User) GetRecords(t WorkoutType) (*WorkoutRecord, error)
- func (u *User) GetStatistics(statConfig StatConfig) (*Statistics, error)
- func (u *User) GetStatisticsFor(since, per string) (*Statistics, error)
- func (u *User) GetTotals(t WorkoutType) (*Bucket, error)
- func (u *User) GetTranslator() *i18n.Locale
- func (u *User) GetWorkout(db *gorm.DB, id int) (*Workout, error)
- func (u *User) GetWorkouts(db *gorm.DB) ([]*Workout, error)
- func (u *User) I18n(message string, vars ...any) string
- func (u *User) IsActive() bool
- func (u *User) IsAnonymous() bool
- func (u *User) IsValid() error
- func (u *User) MarkWorkoutsDirty(db *gorm.DB) error
- func (u *User) PreferredUnits() *UserPreferredUnits
- func (u *User) Save(db *gorm.DB) error
- func (u *User) SetContext(ctx context.Context)
- func (u *User) SetDB(db *gorm.DB)
- func (u *User) SetPassword(password string) error
- func (u *User) ShowFullDate() bool
- func (u *User) Timezone() *time.Location
- func (u *User) ValidLogin(password string) bool
- type UserConfig
- type UserPreferredUnits
- func (u UserPreferredUnits) Cadence() string
- func (u UserPreferredUnits) Distance() string
- func (u UserPreferredUnits) DistanceToDatabase(d float64) float64
- func (u UserPreferredUnits) Elevation() string
- func (u UserPreferredUnits) HeartRate() string
- func (u UserPreferredUnits) Speed() string
- func (u UserPreferredUnits) Tempo() string
- func (u UserPreferredUnits) Weight() string
- type Workout
- func GetRecentWorkouts(db *gorm.DB, count int) ([]*Workout, error)
- func GetWorkout(db *gorm.DB, id int) (*Workout, error)
- func GetWorkoutByUUID(db *gorm.DB, u uuid.UUID) (*Workout, error)
- func GetWorkoutDetails(db *gorm.DB, id int) (*Workout, error)
- func GetWorkoutDetailsByUUID(db *gorm.DB, u uuid.UUID) (*Workout, error)
- func GetWorkoutWithGPX(db *gorm.DB, id int) (*Workout, error)
- func GetWorkoutWithGPXByUUID(db *gorm.DB, u uuid.UUID) (*Workout, error)
- func GetWorkouts(db *gorm.DB) ([]*Workout, error)
- func NewWorkout(u *User, workoutType WorkoutType, notes string, filename string, ...) (*Workout, error)
- func (w *Workout) Address() string
- func (w *Workout) AsGPX() (*gpx.GPX, error)
- func (w *Workout) AverageSpeed() float64
- func (w *Workout) AverageSpeedNoPause() float64
- func (w *Workout) CaloriesBurned() float64
- func (w *Workout) Center() *MapCenter
- func (w *Workout) City() string
- func (w *Workout) Create(db *gorm.DB) error
- func (w *Workout) Creator() string
- func (w *Workout) Delete(db *gorm.DB) error
- func (w *Workout) Details() *MapDataDetails
- func (w *Workout) Distance() float64
- func (w *Workout) Duration() time.Duration
- func (w *Workout) EquipmentIDs() []uint
- func (w *Workout) Filename() string
- func (w *Workout) FindMatches(routeSegments []*RouteSegment) []*RouteSegmentMatch
- func (w *Workout) FullAddress() string
- func (w *Workout) GetDate() time.Time
- func (w *Workout) HasAccuracy() bool
- func (w *Workout) HasCadence() bool
- func (w *Workout) HasCalories() bool
- func (w *Workout) HasElevation() bool
- func (w *Workout) HasElevationData() bool
- func (w *Workout) HasExtraMetric(name string) bool
- func (w *Workout) HasExtraMetrics() bool
- func (w *Workout) HasFile() bool
- func (w *Workout) HasHeading() bool
- func (w *Workout) HasHeartRate() bool
- func (w *Workout) HasPause() bool
- func (w *Workout) HasTracks() bool
- func (w *Workout) MET() float64
- func (w *Workout) MarkdownNotes() string
- func (w *Workout) MaxElevation() float64
- func (w *Workout) MaxSpeed() float64
- func (w *Workout) MinElevation() float64
- func (w *Workout) PauseDuration() time.Duration
- func (w *Workout) RepetitionFrequencyPerMinute() float64
- func (w *Workout) Repetitions() int
- func (w *Workout) Save(db *gorm.DB) error
- func (w *Workout) StatisticsPer(count float64, unit string) (WorkoutBreakdown, error)
- func (w *Workout) Timezone() string
- func (w *Workout) TotalDistance() float64
- func (w *Workout) TotalDown() float64
- func (w *Workout) TotalDuration() time.Duration
- func (w *Workout) TotalRepetitions() int
- func (w *Workout) TotalUp() float64
- func (w *Workout) UpdateAverages()
- func (w *Workout) UpdateData(db *gorm.DB) error
- func (w *Workout) UpdateExtraMetrics()
- func (w *Workout) UpdateRouteSegmentMatches(db *gorm.DB) error
- func (w *Workout) Uses(e Equipment) bool
- func (w *Workout) Weight() float64
- type WorkoutBreakdown
- type WorkoutEquipment
- type WorkoutFilters
- type WorkoutRecord
- type WorkoutTotals
- type WorkoutType
- type WorkoutTypeConfiguration
Constants ¶
const ( PasswordMinimumLength = 4 PasswordMaximumLength = 128 UsernameMinimumLength = 1 UsernameMaximumLength = 32 )
const MaxDeltaMeter = 20
MaxDeltaMeter is the maximum distance in meters that a point can be away from the route segment
const MaxTotalDistancePercentage = 0.02
MaxTotalDistancePercentage is the maximum percentage of the total distance of the route segment that can be exceeded by the total distance matching part of the route
const UnknownLocation = "(unknown location)"
Variables ¶
var ( ErrPasswordInvalidLength = errors.New("password has invalid length") ErrUsernameInvalidLength = errors.New("username has invalid length") ErrUsernameInvalid = errors.New("username is not valid") ErrNoUser = errors.New("no user attached") )
var ErrAnonymousUser = errors.New("no statistics available for anonymous user")
var ErrInvalidData = errors.New("could not convert data to a GPX structure")
var ErrInvalidDataInCache = errors.New("invalid cache data")
var ErrUnsuportedDriver = errors.New("unsupported driver")
Functions ¶
func GetDateLimitExpression ¶
func NewMemoryCache ¶
func NewMemoryCache() *caches.Caches
func RouteSegmentFromPoints ¶
func RouteSegmentFromPoints(workout *Workout, params *RoutSegmentCreationParams) ([]byte, error)
Types ¶
type BreakdownItem ¶
type BreakdownItem struct { FirstPoint *MapPoint // First GPS point in this item LastPoint *MapPoint // Last GPS point in this item UnitName string // Unit name UnitCount float64 // Count of the unit per item Counter int // Counter of this item in the list of items Distance float64 // Distance in this item TotalDistance float64 // Total distance in all items up to and including this item Duration time.Duration // Duration in this item TotalDuration time.Duration // Total duration in all items up to and including this item Speed float64 // Speed in this item IsBest bool // Whether this item is the best of the list IsWorst bool // Whether this item is the worst of the list LocalTotalDistance string `json:",omitempty"` // Total distance in all items up to and including this item LocalDistance string `json:",omitempty"` // The total distance in the bucket, localized LocalAverageSpeed string `json:",omitempty"` // The average speed in the bucket, localized LocalElevation string `json:",omitempty"` // The starting elevation in the bucket, localized LocalHeartRate string `json:",omitempty"` // The starting heart rate in the bucket, localized LocalCadence string `json:",omitempty"` // The starting cadence in the bucket, localized TotalDurationSeconds float64 `json:",omitempty"` // The total duration in the bucket, in seconds }
func (*BreakdownItem) CalcultateSpeed ¶
func (bi *BreakdownItem) CalcultateSpeed()
func (*BreakdownItem) Localize ¶
func (bi *BreakdownItem) Localize(units *UserPreferredUnits)
type Bucket ¶
type Bucket struct { Bucket string `json:",omitempty"` // The name of the bucket WorkoutType WorkoutType // The type of the workout Workouts int // The number of workouts in the bucket Distance float64 `json:",omitempty"` // The total distance in the bucket Up float64 `json:",omitempty"` // The total up elevation in the bucket Duration time.Duration `json:",omitempty"` // The total duration in the bucket AverageSpeed float64 `json:",omitempty"` // The average speed in the bucket AverageSpeedNoPause float64 `json:",omitempty"` // The average speed without pause in the bucket MaxSpeed float64 `json:",omitempty"` // The max speed in the bucket LocalDistance string `json:",omitempty"` // The total distance in the bucket, localized LocalUp string `json:",omitempty"` // The total up elevation in the bucket, localized LocalDuration string `json:",omitempty"` // The total duration in the bucket, localized LocalAverageSpeed string `json:",omitempty"` // The average speed in the bucket, localized LocalAverageSpeedNoPause string `json:",omitempty"` // The average speed without pause in the bucket, localized LocalMaxSpeed string `json:",omitempty"` // The max speed in the bucket, localized DurationSeconds float64 `json:",omitempty"` // The total duration in the bucket, in seconds }
Bucket is the consolidation of workout information for a given time bucket
func (*Bucket) Localize ¶
func (b *Bucket) Localize(units *UserPreferredUnits)
type Buckets ¶
type Buckets struct { WorkoutType WorkoutType LocalWorkoutType string Buckets map[string]Bucket }
type Config ¶
type Config struct { Model EnvConfig `mapstructure:",squash"` UserConfig `mapstructure:",squash"` }
type DurationRecord ¶
type DurationRecord struct { Date time.Time // The timestamp of the record Value time.Duration // The value of the record ID uint // The workout ID of the record }
DurationRecord is a single record if the value is a time.Duration
type EnvConfig ¶
type EnvConfig struct { Bind string `mapstructure:"bind" gorm:"-"` // Which address to bind to JWTEncryptionKey string `mapstructure:"jwt_encryption_key" gorm:"-"` // Encryption key for JWT Dev bool `mapstructure:"dev" gorm:"-"` // Development mode DatabaseDriver string `mapstructure:"database_driver" gorm:"-"` // Which database driver to use DSN string `mapstructure:"dsn" gorm:"-"` // Database DSN Logging bool `mapstructure:"logging" gorm:"-"` // Enable logging Debug bool `mapstructure:"debug" gorm:"-"` // Debug logging mode }
EnvConfig are options that are read from the config file or environment only
type Equipment ¶
type Equipment struct { Model Name string `gorm:"not null;uniqueIndex" json:"name" form:"name"` // The name of the gear Description string `gorm:"" json:"description" form:"description"` // More information about the equipment DefaultFor []WorkoutType `gorm:"serializer:json;column:default_for" form:"default_for"` // Which workout types to add this equipment by default Workouts []Workout `gorm:"many2many:workout_equipment"` User User UserID uint `gorm:"not null;index"` // The ID of the user who owns the workout Active bool `gorm:"default:true" json:"active" form:"active"` // Whether this equipment is active // contains filtered or unexported fields }
func GetEquipmentByIDs ¶
func (*Equipment) GetTotals ¶
func (e *Equipment) GetTotals() (WorkoutTotals, error)
func (*Equipment) ValidFor ¶
func (e *Equipment) ValidFor(wt *WorkoutType) bool
type ExtraMetrics ¶
func (ExtraMetrics) Get ¶
func (em ExtraMetrics) Get(key string) float64
func (ExtraMetrics) ParseGPXExtensions ¶
func (em ExtraMetrics) ParseGPXExtensions(extension gpx.Extension)
func (ExtraMetrics) Set ¶
func (em ExtraMetrics) Set(key string, value float64)
type Float64Record ¶
type Float64Record struct { Date time.Time // The timestamp of the record Value float64 // The value of the record ID uint // The workout ID of the record }
Float64Record is a single record if the value is a float64
type GPXData ¶
type MapData ¶
type MapData struct { Model Address *geo.Address `gorm:"serializer:json"` // The address of the workout Details *MapDataDetails `gorm:"constraint:OnDelete:CASCADE" json:",omitempty"` // The details of the workout Workout *Workout `gorm:"foreignKey:WorkoutID" json:"-"` // The user who owns this profile Creator string // The tool that created this workout Name string // The name of the workout AddressString string // The generic location of the workout Center MapCenter `gorm:"serializer:json"` // The center of the workout (in coordinates) WorkoutID uint `gorm:"not null;uniqueIndex"` // The workout this data belongs to TotalDistance float64 // The total distance of the workout TotalDuration time.Duration // The total duration of the workout MaxSpeed float64 // The maximum speed of the workout AverageSpeed float64 // The average speed of the workout AverageSpeedNoPause float64 // The average speed of the workout without pausing PauseDuration time.Duration // The total pause duration of the workout MinElevation float64 // The minimum elevation of the workout MaxElevation float64 // The maximum elevation of the workout TotalUp float64 // The total distance up of the workout TotalDown float64 // The total distance down of the workout TotalRepetitions int // The number of repetitions of the workout TotalWeight float64 // The weight of the workout ExtraMetrics []string `gorm:"serializer:json"` // Extra metrcis available }
func (*MapData) UpdateAddress ¶
func (m *MapData) UpdateAddress()
func (*MapData) UpdateExtraMetrics ¶
func (m *MapData) UpdateExtraMetrics()
type MapDataDetails ¶
type MapPoint ¶
type MapPoint struct { Time time.Time // The time the point was recorded ExtraMetrics ExtraMetrics // Extra metrics at this point Lat float64 // The latitude of the point Lng float64 // The longitude of the point Distance float64 // The distance from the previous point TotalDistance float64 // The total distance of the workout up to this point Duration time.Duration // The duration from the previous point TotalDuration time.Duration // The total duration of the workout up to this point }
func (*MapPoint) AverageSpeed ¶
func (*MapPoint) DistanceTo ¶
func (*MapPoint) ToOrbPoint ¶
type Profile ¶
type Profile struct { Model User *User `gorm:"foreignKey:UserID" json:"-"` // The user who owns this profile PreferredUnits UserPreferredUnits `gorm:"serializer:json"` // The user's preferred units Language string `form:"language"` // The user's preferred language Theme string `form:"theme"` // The user's preferred color scheme TotalsShow WorkoutType `form:"totals_show"` // What workout type of totals to show Timezone string `form:"timezone"` // The user's preferred timezone AutoImportDirectory string `form:"auto_import_directory"` // The user's preferred directory for auto-import UserID uint // The ID of the user who owns this profile APIActive bool `form:"api_active"` // Whether the user's API key is active SocialsDisabled bool `form:"socials_disabled"` // Whether social sharing buttons are disabled when viewing a workout PreferFullDate bool `form:"prefer_full_date"` // Whether to show full dates in the workout details }
func (*Profile) CanImportFromDirectory ¶
func (*Profile) ResetBools ¶
func (p *Profile) ResetBools()
type RoutSegmentCreationParams ¶
type RoutSegmentCreationParams struct { Name string `form:"name"` Start int `form:"start"` End int `form:"end"` }
func (*RoutSegmentCreationParams) Filename ¶
func (rscp *RoutSegmentCreationParams) Filename() string
type RouteSegment ¶
type RouteSegment struct { Model GeoAddress *geo.Address `gorm:"serializer:json"` // The address of the workout Name string `gorm:"not null"` // The name of the workout Notes string // The notes associated with the workout, in markdown AddressString string // The generic location of the workout Filename string // The filename of the file Points []MapPoint `gorm:"serializer:json"` // The GPS points of the workout Content []byte `gorm:"type:text"` // The file content Checksum []byte `gorm:"not null;uniqueIndex"` // The checksum of the content RouteSegmentMatches []*RouteSegmentMatch // The matches of the route segment Center MapCenter `gorm:"serializer:json"` // The center of the workout (in coordinates) TotalDistance float64 // The total distance of the workout MinElevation float64 // The minimum elevation of the workout MaxElevation float64 // The maximum elevation of the workout TotalUp float64 // The total distance up of the workout TotalDown float64 // The total distance down of the workout Bidirectional bool // Whether the route segment is bidirectional Circular bool // Whether the route segment is circular Dirty bool // Whether the route segment should be recalculated }
func AddRouteSegment ¶
func GetRouteSegment ¶
func GetRouteSegment(db *gorm.DB, id int) (*RouteSegment, error)
func GetRouteSegments ¶
func GetRouteSegments(db *gorm.DB) ([]*RouteSegment, error)
func NewRouteSegment ¶
func NewRouteSegment(notes string, filename string, content []byte) (*RouteSegment, error)
func (*RouteSegment) Address ¶
func (rs *RouteSegment) Address() string
func (*RouteSegment) FindMatches ¶
func (rs *RouteSegment) FindMatches(workouts []*Workout) []*RouteSegmentMatch
FindMatches will find all workouts that match the current route segment The result will contain a list of RouteSegmentMatches, which will contain the workout, the point of the workout along the segment, and the total distance and duration of the segment for this workout.
func (*RouteSegment) HasFile ¶
func (rs *RouteSegment) HasFile() bool
func (*RouteSegment) MarkdownNotes ¶
func (rs *RouteSegment) MarkdownNotes() string
func (*RouteSegment) Match ¶
func (rs *RouteSegment) Match(workout *Workout) *RouteSegmentMatch
Match will find the best match (if any) of the route segment in the workout First calculate all possible starting points, then find the best one that actually matches the segment.
func (*RouteSegment) MatchSegment ¶
MatchSegment starts at a point and continues the workout track while it finds each next point of the route segment, assuming there are many more points in the workout track than the route segment. If it can't find all points of the segment in the correct order, it returns false. Otherwise it returns the last point index of the route that matches the final point of the route segment. If forward is true, we increment the index, otherwise we decrement it
func (*RouteSegment) NewRouteSegmentMatch ¶
func (rs *RouteSegment) NewRouteSegmentMatch(workout *Workout, p, last int) *RouteSegmentMatch
NewRouteSegmentMatch will create a new route segment match from a workout and the first and last point of the route along the route segment
func (*RouteSegment) StartingPoints ¶
func (rs *RouteSegment) StartingPoints(points []MapPoint) []int
StartingPoints finds all points that are closer than MaxDeltaMeter to the segment's starting point
func (*RouteSegment) UpdateFromContent ¶
func (rs *RouteSegment) UpdateFromContent() error
type RouteSegmentMatch ¶
type RouteSegmentMatch struct { Workout *Workout RouteSegment *RouteSegment RouteSegmentID uint `gorm:"primaryKey"` // The ID of the route segment WorkoutID uint `gorm:"primaryKey"` // The ID of the workout FirstID, LastID int // The index of the first and last point of the route Distance float64 // The total distance of the route segment for this workout Duration time.Duration // The total duration of the route segment for this workout Points int // The total number of points of the route segment for this workout // contains filtered or unexported fields }
RouteSegmentMatch is a match between a route segment and a workout
func (*RouteSegmentMatch) AverageSpeed ¶
func (rsm *RouteSegmentMatch) AverageSpeed() float64
func (*RouteSegmentMatch) IsBetterThan ¶
func (rsm *RouteSegmentMatch) IsBetterThan(current *RouteSegmentMatch) bool
IsBetterThan returns true if the new route segment match is better than the current one
func (*RouteSegmentMatch) MatchesDistance ¶
func (rsm *RouteSegmentMatch) MatchesDistance(distance float64) bool
MatchesDistance returns true if the distance of the route segment match is within MaxTotalDistancePercentage of the distance of the current route segment
type StatConfig ¶
func (*StatConfig) GetBucketFormatExpression ¶
func (sc *StatConfig) GetBucketFormatExpression(sqlDialect string) string
func (*StatConfig) GetBucketString ¶
func (sc *StatConfig) GetBucketString(sqlDialect string) string
func (*StatConfig) GetSince ¶
func (sc *StatConfig) GetSince() string
type Statistics ¶
type Statistics struct { Buckets map[WorkoutType]Buckets // The statistics buckets BucketFormat string // The bucket format in strftime format UserID uint // The user ID }
Statistics represents the statistics for a user for a given time range and bucket size, per workout type
type User ¶
type User struct { Model LastVersion string `gorm:"last_version"` // Which version of the app the user has last seen and acknowledged Password string `form:"-" gorm:"type:varchar(128);not null"` // The user's password as bcrypt hash Salt string `form:"-" gorm:"type:varchar(16);not null"` // The salt used to hash the user's password Username string `form:"username" gorm:"uniqueIndex;not null;type:varchar(32)"` // The user's username Name string `form:"name" gorm:"type:varchar(64);not null"` // The user's name APIKey string `gorm:"type:varchar(32)"` // The user's API key Workouts []Workout `gorm:"constraint:OnDelete:CASCADE" json:"-"` // The user's workouts Equipment []Equipment `gorm:"constraint:OnDelete:CASCADE" json:"-"` // The user's equipment Profile Profile `gorm:"constraint:OnDelete:CASCADE"` // The user's profile settings Active bool `form:"active"` // Whether the user is active Admin bool `form:"admin"` // Whether the user is an admin // contains filtered or unexported fields }
func AnonymousUser ¶
func AnonymousUser() *User
func (*User) AddWorkout ¶
func (*User) GenerateAPIKey ¶
func (*User) GenerateSalt ¶
func (u *User) GenerateSalt()
func (*User) GetAllRecords ¶
func (u *User) GetAllRecords() ([]*WorkoutRecord, error)
func (*User) GetContext ¶
func (*User) GetDefaultStatistics ¶
func (u *User) GetDefaultStatistics() (*Statistics, error)
func (*User) GetDefaultTotals ¶
func (*User) GetHighestWorkoutType ¶
func (u *User) GetHighestWorkoutType() (*WorkoutType, error)
func (*User) GetRecords ¶
func (u *User) GetRecords(t WorkoutType) (*WorkoutRecord, error)
func (*User) GetStatistics ¶
func (u *User) GetStatistics(statConfig StatConfig) (*Statistics, error)
func (*User) GetStatisticsFor ¶
func (u *User) GetStatisticsFor(since, per string) (*Statistics, error)
func (*User) GetTranslator ¶
func (*User) IsAnonymous ¶
func (*User) PreferredUnits ¶
func (u *User) PreferredUnits() *UserPreferredUnits
func (*User) SetContext ¶
func (*User) SetPassword ¶
func (*User) ShowFullDate ¶
func (*User) ValidLogin ¶
type UserConfig ¶
type UserConfig struct { RegistrationDisabled bool `mapstructure:"registration_disabled" form:"registration_disabled"` SocialsDisabled bool `mapstructure:"socials_disabled" form:"socials_disabled"` }
UserConfig are options that can be changed at runtime or configured through the web interface If they are set through the environment to a non-default value, that will take precedence
type UserPreferredUnits ¶
type UserPreferredUnits struct { SpeedRaw string `form:"speed" json:"speed"` // The user's preferred speed unit DistanceRaw string `form:"distance" json:"distance"` // The user's preferred distance unit ElevationRaw string `form:"elevation" json:"elevation"` // The user's preferred elevation unit WeightRaw string `form:"weight" json:"weight"` // The user's preferred weight unit }
func (UserPreferredUnits) Cadence ¶
func (u UserPreferredUnits) Cadence() string
func (UserPreferredUnits) Distance ¶
func (u UserPreferredUnits) Distance() string
func (UserPreferredUnits) DistanceToDatabase ¶
func (u UserPreferredUnits) DistanceToDatabase(d float64) float64
func (UserPreferredUnits) Elevation ¶
func (u UserPreferredUnits) Elevation() string
func (UserPreferredUnits) HeartRate ¶
func (u UserPreferredUnits) HeartRate() string
func (UserPreferredUnits) Speed ¶
func (u UserPreferredUnits) Speed() string
func (UserPreferredUnits) Tempo ¶
func (u UserPreferredUnits) Tempo() string
func (UserPreferredUnits) Weight ¶
func (u UserPreferredUnits) Weight() string
type Workout ¶
type Workout struct { Model Date *time.Time `gorm:"not null;uniqueIndex:idx_start_user"` // The timestamp the workout was recorded PublicUUID *uuid.UUID `gorm:"type:uuid;uniqueIndex"` // UUID to publicly share a workout - this UUID can be rotated User *User `gorm:"foreignKey:UserID"` // The user who owns the workout Data *MapData `gorm:"foreignKey:WorkoutID;constraint:OnDelete:CASCADE" json:",omitempty"` // The map data associated with the workout GPX *GPXData `gorm:"foreignKey:WorkoutID;constraint:OnDelete:CASCADE" json:",omitempty"` // The file data associated with the workout Name string `gorm:"not null"` // The name of the workout Notes string // The notes associated with the workout, in markdown Type WorkoutType // The type of the workout Equipment []Equipment `json:",omitempty" gorm:"constraint:OnDelete:CASCADE;many2many:workout_equipment"` // Which equipment is used for this workout RouteSegmentMatches []*RouteSegmentMatch `gorm:"constraint:OnDelete:CASCADE" json:",omitempty"` // Which route segments match UserID uint `gorm:"not null;index;uniqueIndex:idx_start_user"` // The ID of the user who owns the workout Dirty bool // Whether the workout has been modified and the details should be re-rendered }
func GetWorkoutDetailsByUUID ¶
func GetWorkoutWithGPXByUUID ¶
func NewWorkout ¶
func (*Workout) AverageSpeed ¶
func (*Workout) AverageSpeedNoPause ¶
func (*Workout) CaloriesBurned ¶
func (*Workout) Details ¶
func (w *Workout) Details() *MapDataDetails
func (*Workout) EquipmentIDs ¶
func (*Workout) FindMatches ¶
func (w *Workout) FindMatches(routeSegments []*RouteSegment) []*RouteSegmentMatch
FindMatches will find all workouts that match the current route segment The result will contain a list of RouteSegmentMatches, which will contain the workout, the point of the workout along the segment, and the total distance and duration of the segment for this workout.
func (*Workout) FullAddress ¶
func (*Workout) HasAccuracy ¶
func (*Workout) HasCadence ¶
func (*Workout) HasCalories ¶
func (*Workout) HasElevation ¶
func (*Workout) HasElevationData ¶
func (*Workout) HasExtraMetric ¶
func (*Workout) HasExtraMetrics ¶
func (*Workout) HasHeading ¶
func (*Workout) HasHeartRate ¶
func (*Workout) MarkdownNotes ¶
func (*Workout) MaxElevation ¶
func (*Workout) MinElevation ¶
func (*Workout) PauseDuration ¶
func (*Workout) RepetitionFrequencyPerMinute ¶
func (*Workout) Repetitions ¶
func (*Workout) StatisticsPer ¶
func (w *Workout) StatisticsPer(count float64, unit string) (WorkoutBreakdown, error)
func (*Workout) TotalDistance ¶
func (*Workout) TotalDuration ¶
func (*Workout) TotalRepetitions ¶
func (*Workout) UpdateAverages ¶
func (w *Workout) UpdateAverages()
func (*Workout) UpdateExtraMetrics ¶
func (w *Workout) UpdateExtraMetrics()
func (*Workout) UpdateRouteSegmentMatches ¶
type WorkoutBreakdown ¶
type WorkoutBreakdown struct { Unit string Items []BreakdownItem }
type WorkoutEquipment ¶
type WorkoutFilters ¶
type WorkoutFilters struct { Type WorkoutType `query:"type"` Active bool `query:"active"` Since string `query:"since"` OrderBy string `query:"order_by"` OrderDir string `query:"order_dir"` // contains filtered or unexported fields }
func GetWorkoutsFilters ¶
func GetWorkoutsFilters(c echo.Context) (*WorkoutFilters, error)
type WorkoutRecord ¶
type WorkoutRecord struct { WorkoutType WorkoutType // The type of the workout AverageSpeed Float64Record // The record with the maximum average speed AverageSpeedNoPause Float64Record // The record with the maximum average speed without pause MaxSpeed Float64Record // The record with the maximum max speed Distance Float64Record // The record with the maximum distance TotalUp Float64Record // The record with the maximum up elevation Duration DurationRecord // The record with the maximum duration Active bool // Whether there is any data in the record }
WorkoutRecord is the collection of records for a single workout type
type WorkoutTotals ¶
type WorkoutType ¶
type WorkoutType string
const ( WorkoutTypeAutoDetect WorkoutType = "auto" WorkoutTypeRunning WorkoutType = "running" WorkoutTypeCycling WorkoutType = "cycling" WorkoutTypeECycling WorkoutType = "e-cycling" WorkoutTypeWalking WorkoutType = "walking" WorkoutTypeSkiing WorkoutType = "skiing" WorkoutTypeSnowboarding WorkoutType = "snowboarding" WorkoutTypeSwimming WorkoutType = "swimming" WorkoutTypeKayaking WorkoutType = "kayaking" WorkoutTypeGolfing WorkoutType = "golfing" WorkoutTypeHiking WorkoutType = "hiking" WorkoutTypePushups WorkoutType = "push-ups" WorkoutTypeWeightLifting WorkoutType = "weight lifting" WorkoutTypeClassLocation = "location" WorkoutTypeClassDistance = "distance" WorkoutTypeClassRepetition = "repetition" WorkoutTypeClassWeight = "weight" WorkoutTypeClassDuration = "duration" )
func AsWorkoutType ¶
func AsWorkoutType(s string) WorkoutType
func DistanceWorkoutTypes ¶
func DistanceWorkoutTypes() []WorkoutType
func DurationWorkoutTypes ¶
func DurationWorkoutTypes() []WorkoutType
func LocationWorkoutTypes ¶
func LocationWorkoutTypes() []WorkoutType
func RepetitionWorkoutTypes ¶
func RepetitionWorkoutTypes() []WorkoutType
func WeightWorkoutTypes ¶
func WeightWorkoutTypes() []WorkoutType
func WorkoutTypes ¶
func WorkoutTypes() []WorkoutType
func (WorkoutType) IsDistance ¶
func (wt WorkoutType) IsDistance() bool
func (WorkoutType) IsDuration ¶
func (wt WorkoutType) IsDuration() bool
func (WorkoutType) IsLocation ¶
func (wt WorkoutType) IsLocation() bool
func (WorkoutType) IsRepetition ¶
func (wt WorkoutType) IsRepetition() bool
func (WorkoutType) IsWeight ¶
func (wt WorkoutType) IsWeight() bool
func (WorkoutType) String ¶
func (wt WorkoutType) String() string