Documentation ¶
Index ¶
- Constants
- Variables
- func GetEntityColumn(t uint8) string
- func NativeSummaryTypes() []uint8
- func PersistedSummaryTypes() []uint8
- func SummaryTypes() []uint8
- func ValidateCaptcha(captchaId, captchaValue string) bool
- func ValidateEmail(email string) bool
- func ValidatePassword(password string) bool
- func ValidateTimezone(tz string) bool
- func ValidateUsername(username string) bool
- type Alias
- type AliasResolver
- type AliasReverseResolver
- type CountByUser
- type CredentialsReset
- type CustomTime
- func (j CustomTime) GormDBDataType(db *gorm.DB, field *schema.Field) string
- func (j *CustomTime) Hash() (uint64, error)
- func (j *CustomTime) MarshalJSON() ([]byte, error)
- func (j *CustomTime) Scan(value interface{}) error
- func (j CustomTime) String() string
- func (j CustomTime) T() time.Time
- func (j *CustomTime) UnmarshalJSON(b []byte) error
- func (j CustomTime) Valid() bool
- func (j CustomTime) Value() (driver.Value, error)
- type Diagnostics
- type Duration
- type Durations
- type FilterElement
- type Filters
- func (f *Filters) Count() int
- func (f *Filters) CountByType(entity uint8) int
- func (f *Filters) CountDistinctTypes() int
- func (f *Filters) EntityCount() int
- func (f *Filters) Hash() string
- func (f *Filters) IsEmpty() bool
- func (f *Filters) IsProjectDetails() bool
- func (f *Filters) MatchDuration(d *Duration) bool
- func (f *Filters) MatchHeartbeat(h *Heartbeat) bool
- func (f *Filters) One() (bool, uint8, OrFilter)
- func (f *Filters) OneOrEmpty() FilterElement
- func (f *Filters) ResolveType(entityId uint8) *OrFilter
- func (f *Filters) With(entity uint8, key string) *Filters
- func (f *Filters) WithAliases(resolve AliasReverseResolver) *Filters
- func (f *Filters) WithMultiple(entity uint8, keys []string) *Filters
- func (f *Filters) WithProjectLabels(resolve ProjectLabelReverseResolver) *Filters
- func (f *Filters) WithSelectFilteredOnly() *Filters
- type Heartbeat
- func (h *Heartbeat) Augment(languageMappings map[string]string)
- func (h *Heartbeat) GetKey(t uint8) (key string)
- func (h *Heartbeat) Hashed() *Heartbeat
- func (h *Heartbeat) Sanitize() *Heartbeat
- func (h *Heartbeat) String() string
- func (h *Heartbeat) Timely(maxAge time.Duration) bool
- func (h *Heartbeat) Valid() bool
- type Heartbeats
- type Interval
- type IntervalKey
- type KeyStringValue
- type KeyedInterval
- type LanguageMapping
- type Leaderboard
- func (l *Leaderboard) Add(item *LeaderboardItemRanked)
- func (l *Leaderboard) AddMany(items []*LeaderboardItemRanked)
- func (l *Leaderboard) FilterEmpty()
- func (l Leaderboard) GetByUser(userId string) *Leaderboard
- func (l Leaderboard) HasUser(userId string) bool
- func (l Leaderboard) LastUpdate() time.Time
- func (l Leaderboard) TopByKey(by uint8, key string) Leaderboard
- func (l Leaderboard) TopKeys(by uint8) []string
- func (l Leaderboard) TopKeysByUser(by uint8, userId string) []string
- func (l Leaderboard) TopKeysTotals(by uint8) []LeaderboardKeyTotal
- func (l Leaderboard) TopKeysTotalsByUser(by uint8, userId string) []LeaderboardKeyTotal
- func (l Leaderboard) UserIDs() []string
- type LeaderboardItem
- type LeaderboardItemRanked
- type LeaderboardKeyTotal
- type Login
- type Mail
- type MailAddress
- type MailAddresses
- type OrFilter
- type Product
- type ProductLabelReverseResolver
- type ProjectLabel
- type ProjectLabelReverseResolver
- type ProjectStats
- type Report
- type ResetPasswordRequest
- type SetPasswordRequest
- type Signup
- type Summaries
- type Summary
- func (s *Summary) ApplyFilter(filter FilterElement) *Summary
- func (s *Summary) FillBy(fromType uint8, toType uint8)
- func (s *Summary) FillMissing()
- func (s *Summary) GetByType(summaryType uint8) *SummaryItems
- func (s *Summary) KeepOnly(types map[uint8]bool) *Summary
- func (s *Summary) MappedItems() map[uint8]*SummaryItems
- func (s *Summary) MaxBy(entityType uint8) *SummaryItem
- func (s *Summary) MaxByToString(entityType uint8) string
- func (s *Summary) SetByType(summaryType uint8, items *SummaryItems)
- func (s *Summary) Sorted() *Summary
- func (s *Summary) TotalTime() time.Duration
- func (s *Summary) TotalTimeBy(entityType uint8) (timeSum time.Duration)
- func (s *Summary) TotalTimeByFilter(filter FilterElement) time.Duration
- func (s *Summary) TotalTimeByKey(entityType uint8, key string) (timeSum time.Duration)
- func (s *Summary) Types() []uint8
- func (s *Summary) WithResolvedAliases(resolve AliasResolver) *Summary
- type SummaryItem
- type SummaryItemContainer
- type SummaryItems
- type SummaryParams
- type TimeByUser
- type User
- func (u *User) AnyDataShared() bool
- func (u *User) AvatarURL(urlTemplate string) string
- func (u *User) HasActiveSubscription() bool
- func (u *User) HasActiveSubscriptionStrict() bool
- func (u *User) HeartbeatsTimeout() time.Duration
- func (u *User) Identity() string
- func (u *User) MinDataAge() time.Time
- func (u *User) SubscriptionExpiredSince() (bool, time.Duration)
- func (u *User) TZ() *time.Location
- func (u *User) TZOffset() time.Duration
- func (u *User) WakaTimeURL(fallback string) string
- type UserDataUpdate
Constants ¶
const ( MailPattern = "[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\\.[a-zA-Z0-9-.]+" EmailAddrPattern = ".*\\s<(" + MailPattern + ")>|(" + MailPattern + ")" )
const ( UserKey = "user" ImprintKey = "imprint" AuthCookieKey = "wakapi_auth" PersistentIntervalKey = "wakapi_summary_interval" )
const ( NSummaryTypes uint8 = 99 SummaryUnknown uint8 = 98 SummaryProject uint8 = 0 SummaryLanguage uint8 = 1 SummaryEditor uint8 = 2 SummaryOS uint8 = 3 SummaryMachine uint8 = 4 SummaryLabel uint8 = 5 SummaryBranch uint8 = 6 SummaryEntity uint8 = 7 SummaryCategory uint8 = 8 )
const ( DefaultHeartbeatsTimeout = 2 * time.Minute MinHeartbeatsTimeout = 30 * time.Second MaxHeartbeatsTimeout = 5 * time.Minute )
const DefaultProjectLabel = "default"
const HtmlType = "text/html; charset=UTF-8"
const PlainType = "text/html; charset=UTF-8"
const UnknownSummaryKey = "unknown"
Variables ¶
var ( IntervalToday = &IntervalKey{"today", "Today"} IntervalYesterday = &IntervalKey{"day", "yesterday", "Yesterday"} IntervalPastDay = &IntervalKey{"24_hours", "last_24_hours", "last_day", "Last 24 Hours"} // non-official one IntervalThisWeek = &IntervalKey{"week", "This Week"} IntervalLastWeek = &IntervalKey{"last_week", "Last Week"} IntervalThisMonth = &IntervalKey{"month", "This Month"} IntervalLastMonth = &IntervalKey{"last_month", "Last Month"} IntervalThisYear = &IntervalKey{"year", "This Year"} IntervalPast7Days = &IntervalKey{"7_days", "last_7_days", "Last 7 Days"} IntervalPast7DaysYesterday = &IntervalKey{"Last 7 Days from Yesterday"} IntervalPast14Days = &IntervalKey{"14_days", "last_14_days", "Last 14 Days"} IntervalPast30Days = &IntervalKey{"30_days", "last_30_days", "Last 30 Days"} IntervalPast6Months = &IntervalKey{"6_months", "last_6_months", "Last 6 Months"} IntervalPast12Months = &IntervalKey{"12_months", "last_12_months", "last_year", "Last 12 Months"} IntervalAny = &IntervalKey{"any", "all_time", "All Time"} )
Support Wakapi and WakaTime range / interval identifiers See https://wakatime.com/developers/#summaries
var AllIntervals = []*IntervalKey{ IntervalToday, IntervalYesterday, IntervalPastDay, IntervalThisWeek, IntervalLastWeek, IntervalThisMonth, IntervalLastMonth, IntervalThisYear, IntervalPast7Days, IntervalPast7DaysYesterday, IntervalPast14Days, IntervalPast30Days, IntervalPast6Months, IntervalPast12Months, IntervalAny, }
Functions ¶
func GetEntityColumn ¶
func NativeSummaryTypes ¶
func NativeSummaryTypes() []uint8
func PersistedSummaryTypes ¶
func PersistedSummaryTypes() []uint8
func SummaryTypes ¶
func SummaryTypes() []uint8
func ValidateCaptcha ¶
func ValidateEmail ¶
ValidateEmail checks that, if an email address is given, it has proper syntax and (if not in dev mode) an MX record exists for the domain
func ValidatePassword ¶
func ValidateTimezone ¶
func ValidateUsername ¶
Types ¶
type Alias ¶
type Alias struct { ID uint `gorm:"primary_key"` Type uint8 `gorm:"not null; index:idx_alias_type_key"` User *User `json:"-" gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` UserID string `gorm:"not null; index:idx_alias_user"` Key string `gorm:"not null; index:idx_alias_type_key"` Value string `gorm:"not null"` }
type AliasResolver ¶
AliasResolver returns the alias of an Entity, given its original name. I.e., it returns Alias.Key, given an Alias.Value
type AliasReverseResolver ¶
AliasReverseResolver returns all original names, which have the given alias as mapping target. I.e., it returns a list of Alias.Value, given an Alias.Key
type CountByUser ¶
type CredentialsReset ¶
type CredentialsReset struct { PasswordOld string `schema:"password_old"` PasswordNew string `schema:"password_new"` PasswordRepeat string `schema:"password_repeat"` }
func (*CredentialsReset) IsValid ¶
func (c *CredentialsReset) IsValid() bool
type CustomTime ¶
CustomTime is a wrapper type around time.Time, mainly used for the purpose of transparently unmarshalling Python timestamps in the format <sec>.<nsec> (e.g. 1619335137.3324468)
func (CustomTime) GormDBDataType ¶
sql server doesn't allow multiple columns with timestamp type in a column So we need to change the type to datetimeoffset
func (*CustomTime) Hash ¶
func (j *CustomTime) Hash() (uint64, error)
func (*CustomTime) MarshalJSON ¶
func (j *CustomTime) MarshalJSON() ([]byte, error)
func (*CustomTime) Scan ¶
func (j *CustomTime) Scan(value interface{}) error
func (CustomTime) String ¶
func (j CustomTime) String() string
func (CustomTime) T ¶
func (j CustomTime) T() time.Time
func (*CustomTime) UnmarshalJSON ¶
func (j *CustomTime) UnmarshalJSON(b []byte) error
func (CustomTime) Valid ¶
func (j CustomTime) Valid() bool
type Diagnostics ¶
type Duration ¶
type Duration struct { UserID string `json:"user_id"` Time CustomTime `json:"time" hash:"ignore"` Duration time.Duration `json:"duration" hash:"ignore"` Project string `json:"project"` Language string `json:"language"` Editor string `json:"editor"` OperatingSystem string `json:"operating_system"` Machine string `json:"machine"` Category string `json:"category"` Branch string `json:"branch"` Entity string `json:"Entity"` NumHeartbeats int `json:"-" hash:"ignore"` GroupHash string `json:"-" hash:"ignore"` // contains filtered or unexported fields }
func (*Duration) HashInclude ¶
func (*Duration) WithEntityIgnored ¶
type FilterElement ¶
type Filters ¶
type Filters struct { Project OrFilter OS OrFilter Language OrFilter Editor OrFilter Machine OrFilter Label OrFilter Branch OrFilter Entity OrFilter Category OrFilter SelectFilteredOnly bool // flag indicating to drop all Entity types from a summary except the single one filtered by }
func NewFilterWithMultiple ¶
func NewFiltersWith ¶
func (*Filters) CountByType ¶
func (*Filters) CountDistinctTypes ¶
func (*Filters) EntityCount ¶
func (*Filters) IsProjectDetails ¶
func (*Filters) MatchDuration ¶
func (*Filters) MatchHeartbeat ¶
func (*Filters) OneOrEmpty ¶
func (f *Filters) OneOrEmpty() FilterElement
func (*Filters) ResolveType ¶
func (*Filters) WithAliases ¶
func (f *Filters) WithAliases(resolve AliasReverseResolver) *Filters
WithAliases adds OR-conditions for every alias of a Filter key as additional Filter keys
func (*Filters) WithProjectLabels ¶
func (f *Filters) WithProjectLabels(resolve ProjectLabelReverseResolver) *Filters
func (*Filters) WithSelectFilteredOnly ¶
type Heartbeat ¶
type Heartbeat struct { ID uint64 `gorm:"primary_key" hash:"ignore"` User *User `json:"-" gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE;" hash:"ignore"` UserID string `json:"-" gorm:"not null; index:idx_time_user; index:idx_user_project"` // idx_user_project is for quickly fetching a user's project list (settings page) Entity string `json:"Entity" gorm:"not null"` Type string `json:"type" gorm:"size:255"` Category string `json:"category" gorm:"size:255"` Project string `json:"project" gorm:"index:idx_project; index:idx_user_project"` Branch string `json:"branch" gorm:"index:idx_branch"` Language string `json:"language" gorm:"index:idx_language"` IsWrite bool `json:"is_write"` Editor string `json:"editor" gorm:"index:idx_editor" hash:"ignore"` // ignored because editor might be parsed differently by wakatime OperatingSystem string `json:"operating_system" gorm:"index:idx_operating_system" hash:"ignore"` // ignored because os might be parsed differently by wakatime Machine string `json:"machine" gorm:"index:idx_machine" hash:"ignore"` // ignored because wakatime api doesn't return machines currently UserAgent string `json:"user_agent" hash:"ignore" gorm:"type:varchar(255)"` Time CustomTime `json:"time" gorm:"timeScale:3; index:idx_time; index:idx_time_user" swaggertype:"primitive,number"` Hash string `json:"-" gorm:"type:varchar(17); uniqueIndex"` Origin string `json:"-" hash:"ignore" gorm:"type:varchar(255)"` OriginId string `json:"-" hash:"ignore" gorm:"type:varchar(255)"` CreatedAt CustomTime `json:"created_at" gorm:"timeScale:3" swaggertype:"primitive,number" hash:"ignore"` // https://gorm.io/docs/conventions.html#CreatedAt }
type Heartbeats ¶
type Heartbeats []*Heartbeat
func (*Heartbeats) First ¶
func (h *Heartbeats) First() *Heartbeat
func (*Heartbeats) Last ¶
func (h *Heartbeats) Last() *Heartbeat
func (Heartbeats) Len ¶
func (h Heartbeats) Len() int
func (Heartbeats) Less ¶
func (h Heartbeats) Less(i, j int) bool
func (*Heartbeats) Sorted ¶
func (h *Heartbeats) Sorted() *Heartbeats
func (Heartbeats) Swap ¶
func (h Heartbeats) Swap(i, j int)
type IntervalKey ¶
type IntervalKey []string
func (*IntervalKey) GetHumanReadable ¶
func (k *IntervalKey) GetHumanReadable() string
func (*IntervalKey) HasAlias ¶
func (k *IntervalKey) HasAlias(s string) bool
type KeyStringValue ¶
type KeyedInterval ¶
type KeyedInterval struct { Interval Key *IntervalKey }
type LanguageMapping ¶
type LanguageMapping struct { ID uint `json:"id" gorm:"primary_key"` User *User `json:"-" gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` UserID string `json:"-" gorm:"not null; index:idx_language_mapping_user; uniqueIndex:idx_language_mapping_composite"` Extension string `json:"extension" gorm:"uniqueIndex:idx_language_mapping_composite; type:varchar(16)"` Language string `json:"language" gorm:"type:varchar(64)"` }
func (*LanguageMapping) IsValid ¶
func (m *LanguageMapping) IsValid() bool
type Leaderboard ¶
type Leaderboard []*LeaderboardItemRanked
func (*Leaderboard) Add ¶
func (l *Leaderboard) Add(item *LeaderboardItemRanked)
func (*Leaderboard) AddMany ¶
func (l *Leaderboard) AddMany(items []*LeaderboardItemRanked)
func (Leaderboard) GetByUser ¶
func (l Leaderboard) GetByUser(userId string) *Leaderboard
be cautious: ranks won't match anymore
func (Leaderboard) HasUser ¶
func (l Leaderboard) HasUser(userId string) bool
func (Leaderboard) LastUpdate ¶
func (l Leaderboard) LastUpdate() time.Time
func (Leaderboard) TopByKey ¶
func (l Leaderboard) TopByKey(by uint8, key string) Leaderboard
func (Leaderboard) TopKeys ¶
func (l Leaderboard) TopKeys(by uint8) []string
func (Leaderboard) TopKeysByUser ¶
func (l Leaderboard) TopKeysByUser(by uint8, userId string) []string
func (Leaderboard) TopKeysTotals ¶
func (l Leaderboard) TopKeysTotals(by uint8) []LeaderboardKeyTotal
func (Leaderboard) TopKeysTotalsByUser ¶
func (l Leaderboard) TopKeysTotalsByUser(by uint8, userId string) []LeaderboardKeyTotal
func (Leaderboard) UserIDs ¶
func (l Leaderboard) UserIDs() []string
type LeaderboardItem ¶
type LeaderboardItem struct { ID uint `json:"-" gorm:"primary_key; size:32"` User *User `json:"-" gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` UserID string `json:"user_id" gorm:"not null; index:idx_leaderboard_user"` Interval string `json:"interval" gorm:"not null; size:32; index:idx_leaderboard_combined"` By *uint8 `json:"aggregated_by" gorm:"index:idx_leaderboard_combined"` // pointer because nullable Total time.Duration `json:"total" gorm:"not null" swaggertype:"primitive,integer"` Key *string `json:"key" gorm:"size:255"` // pointer because nullable CreatedAt CustomTime `gorm:"default:CURRENT_TIMESTAMP" swaggertype:"string" format:"date" example:"2006-01-02 15:04:05.000"` }
type LeaderboardItemRanked ¶
type LeaderboardItemRanked struct { LeaderboardItem Rank uint }
https://github.com/go-gorm/gorm/issues/5789 https://github.com/go-gorm/gorm/issues/5284#issuecomment-1107775806
func (*LeaderboardItemRanked) Equals ¶
func (l1 *LeaderboardItemRanked) Equals(l2 *LeaderboardItemRanked) bool
type LeaderboardKeyTotal ¶
type Mail ¶
type Mail struct { From MailAddress To MailAddresses Subject string Body string Type string Date time.Time MessageID string }
type MailAddress ¶
type MailAddress string
func (MailAddress) Domain ¶
func (m MailAddress) Domain() string
func (MailAddress) Raw ¶
func (m MailAddress) Raw() string
func (MailAddress) String ¶
func (m MailAddress) String() string
func (MailAddress) Valid ¶
func (m MailAddress) Valid() bool
type MailAddresses ¶
type MailAddresses []MailAddress
func (MailAddresses) AllValid ¶
func (m MailAddresses) AllValid() bool
func (MailAddresses) RawStrings ¶
func (m MailAddresses) RawStrings() []string
func (MailAddresses) Strings ¶
func (m MailAddresses) Strings() []string
type Product ¶ added in v0.1.7
type ProductLabelReverseResolver ¶ added in v0.1.7
ProductLabelReverseResolver returns all projects for a given label
type ProjectLabel ¶
type ProjectLabel struct { ID uint `json:"id" gorm:"primary_key"` User *User `json:"-" gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` UserID string `json:"-" gorm:"not null; index:idx_project_label_user"` ProjectKey string `json:"project"` Label string `json:"label" gorm:"type:varchar(64)"` }
func (*ProjectLabel) IsValid ¶
func (l *ProjectLabel) IsValid() bool
type ProjectLabelReverseResolver ¶
ProjectLabelReverseResolver returns all projects for a given label
type ProjectStats ¶
type ProjectStats struct { UserId string Project string TopLanguage string Count int64 First CustomTime Last CustomTime }
type ResetPasswordRequest ¶
type ResetPasswordRequest struct {
Email string `schema:"email"`
}
type SetPasswordRequest ¶
type SetPasswordRequest struct { Password string `schema:"password"` PasswordRepeat string `schema:"password_repeat"` Token string `schema:"token"` }
func (*SetPasswordRequest) IsValid ¶
func (c *SetPasswordRequest) IsValid() bool
type Signup ¶
type Signup struct { Username string `schema:"username"` Email string `schema:"email"` Password string `schema:"password"` PasswordRepeat string `schema:"password_repeat"` Location string `schema:"location"` CaptchaId string `schema:"captcha_id"` Captcha string `schema:"captcha"` InviteCode string `schema:"invite_code"` InvitedBy string `schema:"-"` }
type Summary ¶
type Summary struct { ID uint `json:"-" gorm:"primary_key; size:32"` User *User `json:"-" gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` UserID string `json:"user_id" gorm:"not null; index:idx_time_summary_user"` FromTime CustomTime `` /* 152-byte string literal not displayed */ ToTime CustomTime `` /* 150-byte string literal not displayed */ // Previously, all the following properties created a cascade foreign key constraint on the summary_items table // back to this summary table resulting in 5 identical foreign key constraints on the summary_items table. // This is not a problem for PostgreSQL, MySQL and SQLite, but for MSSQL, which complains about circular cascades on // update/delete between these two tables. All of these created foreign key constraints are identical, so only one constraint is enough. // MySQL will create a foreign key constraint for every property referencing other structs, even no constraint is specified in tags. // So explicitly set gorm:"-" in all other properties to avoid creating duplicate foreign key constraints Projects SummaryItems `json:"projects" gorm:"constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` Languages SummaryItems `json:"languages" gorm:"-"` Editors SummaryItems `json:"editors" gorm:"-"` OperatingSystems SummaryItems `json:"operating_systems" gorm:"-"` Machines SummaryItems `json:"machines" gorm:"-"` Labels SummaryItems `json:"labels" gorm:"-"` // labels are not persisted, but calculated at runtime, i.e. when summary is retrieved Branches SummaryItems `json:"branches" gorm:"-"` // branches are not persisted, but calculated at runtime in case a project Filter is applied Entities SummaryItems `json:"entities" gorm:"-"` // entities are not persisted, but calculated at runtime in case a project Filter is applied Categories SummaryItems `json:"categories" gorm:"-"` NumHeartbeats int `json:"-"` }
func NewEmptySummary ¶
func NewEmptySummary() *Summary
func (*Summary) ApplyFilter ¶
func (s *Summary) ApplyFilter(filter FilterElement) *Summary
ApplyFilter drops all summary elements of the given type that don't match the given query. Please note: this only makes sense if you're eventually interested in nothing but the total time of that specific type, because the summary will be inconsistent after this operation (e.g. when filtering by project, languages, editors, etc. won't match up anymore). Therefore, use with caution.
func (*Summary) FillMissing ¶
func (s *Summary) FillMissing()
Augments the summary in a way that at least one item is present for every type.
If a summary has zero items for a given type, but one or more for any of the other types, the total summary duration can be derived from those and inserted as a dummy-item with key "unknown" for the missing type. For instance, the machine type was introduced post hoc. Accordingly, no "machine"-information is present in the data for old heartbeats and summaries. If a user has two years of data without machine information and one day with such, a "machine"-chart plotted from that data will reference a way smaller absolute total amount of time than the other ones. To avoid having to modify persisted data retrospectively, i.e. inserting a dummy SummaryItem for the new type, such is generated dynamically here, considering the "machine" for all old heartbeats "unknown".
func (*Summary) GetByType ¶
func (s *Summary) GetByType(summaryType uint8) *SummaryItems
func (*Summary) MappedItems ¶
func (s *Summary) MappedItems() map[uint8]*SummaryItems
func (*Summary) MaxBy ¶
func (s *Summary) MaxBy(entityType uint8) *SummaryItem
func (*Summary) MaxByToString ¶
func (*Summary) SetByType ¶
func (s *Summary) SetByType(summaryType uint8, items *SummaryItems)
func (*Summary) TotalTimeBy ¶
func (*Summary) TotalTimeByFilter ¶
func (s *Summary) TotalTimeByFilter(filter FilterElement) time.Duration
func (*Summary) TotalTimeByKey ¶
func (*Summary) WithResolvedAliases ¶
func (s *Summary) WithResolvedAliases(resolve AliasResolver) *Summary
type SummaryItem ¶
type SummaryItem struct { ID uint64 `json:"-" gorm:"primary_key"` Summary *Summary `json:"-" gorm:"not null; constraint:OnUpdate:CASCADE,OnDelete:CASCADE"` SummaryID uint `json:"-" gorm:"size:32"` Type uint8 `json:"-" gorm:"index:idx_type"` Key string `json:"key" gorm:"size:255"` Total time.Duration `json:"total" swaggertype:"primitive,integer"` }
func (*SummaryItem) TotalFixed ¶
func (s *SummaryItem) TotalFixed() time.Duration
type SummaryItemContainer ¶
type SummaryItemContainer struct { Type uint8 Items []*SummaryItem }
type SummaryItems ¶
type SummaryItems []*SummaryItem
func (SummaryItems) Len ¶
func (s SummaryItems) Len() int
func (SummaryItems) Less ¶
func (s SummaryItems) Less(i, j int) bool
func (SummaryItems) Swap ¶
func (s SummaryItems) Swap(i, j int)
type SummaryParams ¶
type SummaryParams struct { From time.Time To time.Time User *User Filters *Filters Recompute bool }
func (*SummaryParams) GetProjectFilter ¶
func (s *SummaryParams) GetProjectFilter() string
func (*SummaryParams) HasFilters ¶
func (s *SummaryParams) HasFilters() bool
func (*SummaryParams) IsProjectDetails ¶
func (s *SummaryParams) IsProjectDetails() bool
type TimeByUser ¶
type TimeByUser struct { User string Time CustomTime }
type User ¶
type User struct { ID string `json:"id" gorm:"primary_key"` ApiKey string `json:"api_key" gorm:"unique; default:NULL"` Email string `json:"email" gorm:"index:idx_user_email; size:255"` Location string `json:"location"` Password string `json:"-"` CreatedAt CustomTime `gorm:"default:CURRENT_TIMESTAMP" swaggertype:"string" format:"date" example:"2006-01-02 15:04:05.000"` LastLoggedInAt CustomTime `gorm:"default:CURRENT_TIMESTAMP" swaggertype:"string" format:"date" example:"2006-01-02 15:04:05.000"` IsAdmin bool `json:"-" gorm:"default:false; type:bool"` HasData bool `json:"-" gorm:"default:false; type:bool"` WakatimeApiKey string `json:"-"` // for relay middleware and imports WakatimeApiUrl string `json:"-"` // for relay middleware and imports ResetToken string `json:"-"` ReportsWeekly bool `json:"-" gorm:"default:false; type:bool"` PublicLeaderboard bool `json:"-" gorm:"default:false; type:bool"` SubscribedUntil *CustomTime `json:"-" swaggertype:"string" format:"date" example:"2006-01-02 15:04:05.000"` SubscriptionRenewal *CustomTime `json:"-" swaggertype:"string" format:"date" example:"2006-01-02 15:04:05.000"` StripeCustomerId string `json:"-"` InvitedBy string `json:"-"` ExcludeUnknownProjects bool `json:"-"` HeartbeatsTimeoutSec int `json:"-" gorm:"default:120"` // https://github.com/muety/wakapi/issues/156 }
func (*User) AnyDataShared ¶
func (*User) HasActiveSubscription ¶
HasActiveSubscription returns true if subscriptions are enabled on the server and the user has got one
func (*User) HasActiveSubscriptionStrict ¶
func (*User) HeartbeatsTimeout ¶
func (*User) MinDataAge ¶
func (*User) SubscriptionExpiredSince ¶
SubscriptionExpiredSince returns if a user's subscription has expiration and the duration since when that happened. Returns (false, <negative duration>), if subscription hasn't expired, yet. Returns (false, 0), if subscriptions are not enabled in the first place. Returns (true, <very long duration>), if the user has never had a subscription.
func (*User) TZOffset ¶
TZOffset returns the time difference between the user's current time zone and UTC TODO: is this actually working??
func (*User) WakaTimeURL ¶
WakaTimeURL returns the user's effective WakaTime URL, i.e. a custom one (which could also point to another Wakapi instance) or fallback if not specified otherwise.
type UserDataUpdate ¶
type UserDataUpdate struct { Email string `schema:"email"` Location string `schema:"location"` ReportsWeekly bool `schema:"reports_weekly"` PublicLeaderboard bool `schema:"public_leaderboard"` }
func (*UserDataUpdate) IsValid ¶
func (r *UserDataUpdate) IsValid() bool