Documentation ¶
Index ¶
- Constants
- Variables
- func BarChart(ctx context.Context, stats []Stat, max int, daily bool) template.HTML
- func ChunkStat(stats []Stat) (int, []int)
- func EmailTemplate(tplname string, args interface{}) func() ([]byte, error)
- func GetMax(ctx context.Context, start, end time.Time, filter string, daily bool) (int, error)
- func GetTotalCount(ctx context.Context, start, end time.Time, filter string) (int, int, error)
- func GetTotalCountUTC(ctx context.Context, start, end time.Time, filter string) (int, int, error)
- func HorizontalChart(ctx context.Context, stats Stats, total, pageSize int, link, paginate bool) template.HTML
- func Import(ctx context.Context, fp io.Reader, replace, email bool)
- func NewContext(ctx context.Context) context.Context
- func ResetCache()
- func TextChart(ctx context.Context, stats []Stat, max int, daily bool) template.HTML
- func WithSite(ctx context.Context, s *Site) context.Context
- func WithUser(ctx context.Context, u *User) context.Context
- type APIToken
- func (t *APIToken) ByID(ctx context.Context, id int64) error
- func (t *APIToken) ByToken(ctx context.Context, token string) error
- func (t *APIToken) Defaults(ctx context.Context)
- func (t *APIToken) Delete(ctx context.Context) error
- func (t *APIToken) Insert(ctx context.Context) error
- func (t *APIToken) Validate(ctx context.Context) error
- type APITokenPermissions
- type APITokens
- type AdminBotlog
- type AdminBotlogIP
- type AdminBotlogIPs
- type AdminSiteStat
- type AdminStat
- type AdminStats
- type Export
- type ExportRow
- type Exports
- type Hit
- type HitStat
- type HitStats
- func (h *HitStats) List(ctx context.Context, start, end time.Time, filter string, exclude []string, ...) (int, int, bool, error)
- func (h *HitStats) ListPathsLike(ctx context.Context, path string, matchTitle bool) error
- func (h *HitStats) PathCountUnique(ctx context.Context, path string) error
- func (h *HitStats) SiteTotalUnique(ctx context.Context) error
- type Hits
- type Site
- func (s Site) Admin() bool
- func (s *Site) ByCode(ctx context.Context, code string) error
- func (s *Site) ByHost(ctx context.Context, host string) error
- func (s *Site) ByID(ctx context.Context, id int64) error
- func (s *Site) Defaults(ctx context.Context)
- func (s *Site) Delete(ctx context.Context) error
- func (s Site) DeleteAll(ctx context.Context) error
- func (s Site) DeleteOlderThan(ctx context.Context, days int) error
- func (s Site) Display() string
- func (s Site) Domain() string
- func (s Site) FreePlan() bool
- func (s Site) IDOrParent() int64
- func (s *Site) Insert(ctx context.Context) error
- func (s *Site) ListSubs(ctx context.Context) ([]string, error)
- func (s Site) PayExternal() string
- func (s Site) PlanCustomDomain(ctx context.Context) bool
- func (s Site) ShowPayBanner(ctx context.Context) bool
- func (s Site) URL() string
- func (s *Site) Update(ctx context.Context) error
- func (s *Site) UpdateCnameSetupAt(ctx context.Context) error
- func (s *Site) UpdateCode(ctx context.Context, code string) error
- func (s *Site) UpdateReceivedData(ctx context.Context) error
- func (s *Site) UpdateStripe(ctx context.Context, stripeID, plan, amount string) error
- func (s *Site) Validate(ctx context.Context) error
- type SiteSettings
- type Sites
- func (s *Sites) ContainsCNAME(ctx context.Context, cname string) (bool, error)
- func (s *Sites) ListSubs(ctx context.Context) error
- func (s *Sites) OldSoftDeleted(ctx context.Context) error
- func (s *Sites) UnscopedList(ctx context.Context) error
- func (s *Sites) UnscopedListCnames(ctx context.Context) error
- type Stat
- type StatT
- type Stats
- func (h *Stats) ByRef(ctx context.Context, start, end time.Time, ref string) error
- func (h *Stats) ListBrowser(ctx context.Context, browser string, start, end time.Time) error
- func (h *Stats) ListBrowsers(ctx context.Context, start, end time.Time, limit, offset int) error
- func (h *Stats) ListLocations(ctx context.Context, start, end time.Time, limit, offset int) error
- func (h *Stats) ListRefsByPath(ctx context.Context, path string, start, end time.Time, offset int) error
- func (h *Stats) ListSize(ctx context.Context, name string, start, end time.Time) error
- func (h *Stats) ListSizes(ctx context.Context, start, end time.Time) error
- func (h *Stats) ListSystem(ctx context.Context, system string, start, end time.Time) error
- func (h *Stats) ListSystems(ctx context.Context, start, end time.Time, limit, offset int) error
- func (h *Stats) ListTopRefs(ctx context.Context, start, end time.Time, offset int) error
- type Update
- type Updates
- type User
- func (u *User) ByEmail(ctx context.Context, email string) error
- func (u *User) ByEmailToken(ctx context.Context, key string) error
- func (u *User) ByResetToken(ctx context.Context, key string) error
- func (u *User) BySite(ctx context.Context, id int64) error
- func (u *User) ByToken(ctx context.Context, token string) error
- func (u *User) ByTokenAndSite(ctx context.Context, token string) error
- func (u User) CorrectPassword(pwd string) (bool, error)
- func (u *User) Defaults(ctx context.Context)
- func (u *User) DisableTOTP(ctx context.Context) error
- func (u *User) EnableTOTP(ctx context.Context) error
- func (u *User) GetToken() string
- func (u *User) Insert(ctx context.Context) error
- func (u *User) Login(ctx context.Context) error
- func (u *User) Logout(ctx context.Context) error
- func (u *User) RequestReset(ctx context.Context) error
- func (u *User) SeenUpdates(ctx context.Context) error
- func (u *User) Update(ctx context.Context, emailChanged bool) error
- func (u *User) UpdatePassword(ctx context.Context, pwd string) error
- func (u *User) Validate(ctx context.Context, validatePassword bool) error
- func (u *User) VerifyEmail(ctx context.Context) error
- func (u User) Widgets() []string
- type Users
Constants ¶
const ( StateActive = "a" StateRequest = "r" StateDeleted = "d" )
State column values.
const ( PlanPersonal = "personal" PlanPersonalPlus = "personalplus" // This is really the "starter" plan. PlanBusiness = "business" PlanBusinessPlus = "businessplus" PlanChild = "child" )
Plan column values.
const ExportVersion = "1"
const PathTotals = "TOTAL "
PathTotals is a special path to indicate this is the "total" overview.
Trailing whitespace is trimmed on paths, so this should never conflict.
Variables ¶
var ( // Valid UUID for testing: 00112233-4455-6677-8899-aabbccddeeff TestSession = zint.Uint128{0x11223344556677, 0x8899aabbccddeeff} TestSeqSession = zint.Uint128{TestSession[0], TestSession[1] + 1} )
var ( RefSchemeHTTP = ptr("h") RefSchemeOther = ptr("o") RefSchemeGenerated = ptr("g") RefSchemeCampaign = ptr("c") )
ref_scheme column
var Memstore ms
var Now = func() time.Time { return time.Now().UTC() }
Now gets the current time in UTC; can be overwritten in tests.
var Plans = []string{PlanPersonal, PlanPersonalPlus, PlanBusiness, PlanBusinessPlus}
var SQLiteHook = func(c *sqlite3.SQLiteConn) error { return c.RegisterFunc("percent_diff", func(start, final int) float64 { if start == 0 { return math.Inf(0) } return float64(float64((final-start)/start) * 100) }, true) }
var States = []string{StateActive, StateRequest, StateDeleted}
Functions ¶
func EmailTemplate ¶
func GetTotalCount ¶
func GetTotalCountUTC ¶
func HorizontalChart ¶
func NewContext ¶
NewContext creates a new context with the all the request values set.
Useful for tests, or for "removing" the timeout on the request context so it can be passed to background functions.
func ResetCache ¶
func ResetCache()
Types ¶
type APIToken ¶
type APIToken struct { ID int64 `db:"api_token_id" json:"-"` SiteID int64 `db:"site_id" json:"-"` UserID int64 `db:"user_id" json:"-"` Name string `db:"name" json:"name"` Token string `db:"token" json:"-"` Permissions APITokenPermissions `db:"permissions" json:"permissions"` CreatedAt time.Time `db:"created_at" json:"-"` }
type APITokenPermissions ¶
type APITokenPermissions struct { Count bool `db:"count" json:"count"` Export bool `db:"export" json:"export"` SiteRead bool `db:"site_read" json:"site_read"` SiteCreate bool `db:"site_create" json:"site_create"` SiteUpdate bool `db:"site_update" json:"site_update"` }
func (*APITokenPermissions) Scan ¶
func (tp *APITokenPermissions) Scan(v interface{}) error
Scan converts the data returned from the DB into the struct.
func (APITokenPermissions) String ¶
func (tp APITokenPermissions) String() string
type AdminBotlog ¶
type AdminBotlogIP ¶
type AdminBotlogIPs ¶
type AdminBotlogIPs []AdminBotlogIP
type AdminSiteStat ¶
type AdminSiteStat struct { Site Site `db:"-"` User User `db:"-"` LastData time.Time `db:"last_data"` CountTotal int `db:"count_total"` CountLastMonth int `db:"count_last_month"` CountPrevMonth int `db:"count_prev_month"` }
type AdminStat ¶
type AdminStat struct { ID int64 `db:"id"` Parent *int64 `db:"parent"` Code string `db:"code"` Stripe *string `db:"stripe"` BillingAmount *string `db:"billing_amount"` LinkDomain string `db:"link_domain"` Email string `db:"email"` CreatedAt time.Time `db:"created_at"` Plan string `db:"plan"` LastMonth int `db:"last_month"` Total int `db:"total"` }
type AdminStats ¶
type AdminStats []AdminStat
type Export ¶
type Export struct { ID int64 `db:"export_id" json:"id,readonly"` SiteID int64 `db:"site_id" json:"site_id,readonly"` // The hit ID this export was started from. StartFromHitID int64 `db:"start_from_hit_id" json:"start_from_hit_id"` // Last hit ID that was exported; can be used as start_from_hit_id. LastHitID *int64 `db:"last_hit_id" json:"last_hit_id,readonly"` Path string `db:"path" json:"path,readonly"` // {omitdoc} CreatedAt time.Time `db:"created_at" json:"created_at,readonly"` FinishedAt *time.Time `db:"finished_at" json:"finished_at,readonly"` NumRows *int `db:"num_rows" json:"num_rows,readonly"` // File size in MB. Size *string `db:"size" json:"size,readonly"` // SHA256 hash. Hash *string `db:"hash" json:"hash,readonly"` // Any errors that may have occured. Error *string `db:"error" json:"error,readonly"` }
type ExportRow ¶
type Hit ¶
type Hit struct { ID int64 `db:"id" json:"-"` Site int64 `db:"site" json:"-"` Session zint.Uint128 `db:"session2" json:"-"` // Old incremental session IDs; kinda expensive to migrate, and only used // for export. Will migrate later when I refactor the hits table. OldSession *int64 `db:"session" json:"-"` Path string `db:"path" json:"p,omitempty"` Title string `db:"title" json:"t,omitempty"` Ref string `db:"ref" json:"r,omitempty"` Event zdb.Bool `db:"event" json:"e,omitempty"` Size zdb.Floats `db:"size" json:"s,omitempty"` Query string `db:"-" json:"q,omitempty"` Bot int `db:"bot" json:"b,omitempty"` RefScheme *string `db:"ref_scheme" json:"-"` Browser string `db:"browser" json:"-"` Location string `db:"location" json:"-"` FirstVisit zdb.Bool `db:"first_visit" json:"-"` CreatedAt time.Time `db:"created_at" json:"-"` RefURL *url.URL `db:"-" json:"-"` // Parsed Ref Random string `db:"-" json:"rnd"` // Browser cache buster, as they don't always listen to Cache-Control // Some values we need to pass from the HTTP handler to memstore RemoteAddr string `db:"-" json:"-"` UserSessionID string `db:"-" json:"-"` }
type HitStat ¶
type HitStats ¶
type HitStats []HitStat
func (*HitStats) List ¶
func (h *HitStats) List( ctx context.Context, start, end time.Time, filter string, exclude []string, daily bool, ) (int, int, bool, error)
List the top paths for this site in the given time period.
func (*HitStats) ListPathsLike ¶
ListPathsLike lists all paths matching the like pattern.
func (*HitStats) PathCountUnique ¶
PathCountUnique gets the total_unique for one path.
type Hits ¶
type Hits []Hit
type Site ¶
type Site struct { ID int64 `db:"id" json:"id,readonly"` Parent *int64 `db:"parent" json:"parent,readonly"` // Custom domain, e.g. "stats.example.com" Cname *string `db:"cname" json:"cname"` // When the CNAME was verified. CnameSetupAt *time.Time `db:"cname_setup_at" json:"cname_setup_at,readonly"` // Domain code (arp242, which makes arp242.goatcounter.com) Code string `db:"code" json:"code"` // Site domain for linking (www.arp242.net). LinkDomain string `db:"link_domain" json:"link_domain"` Plan string `db:"plan" json:"plan"` Stripe *string `db:"stripe" json:"-"` BillingAmount *string `db:"billing_amount" json:"-"` Settings SiteSettings `db:"settings" json:"setttings"` // Whether this site has received any data; will be true after the first // pageview. ReceivedData bool `db:"received_data" json:"received_data"` State string `db:"state" json:"state"` CreatedAt time.Time `db:"created_at" json:"created_at"` UpdatedAt *time.Time `db:"updated_at" json:"updated_at"` }
func MustGetSite ¶
MustGetSite behaves as GetSite(), panicking if this fails.
func (Site) DeleteAll ¶
DeleteAll deletes all pageviews for this site, keeping the site itself and user intact.
func (Site) Domain ¶
Domain gets the global default domain, or this site's configured custom domain.
func (Site) IDOrParent ¶
IDOrParent gets this site's ID or the parent ID if that's set.
func (Site) PayExternal ¶
func (Site) PlanCustomDomain ¶
PlanCustomDomain reports if this site's plan allows custom domains.
func (Site) ShowPayBanner ¶
ShowPayBanner determines if we should show a "please pay" banner for the customer.
func (*Site) UpdateCnameSetupAt ¶
UpdateCnameSetupAt confirms the custom domain was setup correct.
func (*Site) UpdateCode ¶
UpdateCode changes the site's domain code (e.g. "test" in "test.goatcounter.com").
func (*Site) UpdateStripe ¶
UpdateStripe sets the Stripe customer ID.
type SiteSettings ¶
type SiteSettings struct { Public bool `json:"public"` AllowCounter bool `json:"allow_counter"` TwentyFourHours bool `json:"twenty_four_hours"` SundayStartsWeek bool `json:"sunday_starts_week"` DateFormat string `json:"date_format"` NumberFormat rune `json:"number_format"` DataRetention int `json:"data_retention"` IgnoreIPs zdb.Strings `json:"ignore_ips"` Timezone *tz.Zone `json:"timezone"` Campaigns zdb.Strings `json:"campaigns"` AllowAdmin bool `json:"allow_admin"` Limits struct { Page int `json:"page"` Ref int `json:"ref"` Hchart int `json:"hchart"` } `json:"limits"` }
func (*SiteSettings) Scan ¶
func (ss *SiteSettings) Scan(v interface{}) error
Scan converts the data returned from the DB into the struct.
func (SiteSettings) String ¶
func (ss SiteSettings) String() string
type Sites ¶
type Sites []Site
Sites is a list of sites.
func (*Sites) ContainsCNAME ¶
ContainsCNAME reports if there is a site with this CNAME set.
func (*Sites) OldSoftDeleted ¶
OldSoftDeleted finds all sites which have been soft-deleted more than a week ago.
func (*Sites) UnscopedList ¶
UnscopedList lists all sites, not scoped to the current user.
type Stats ¶
func (*Stats) ListBrowser ¶
ListBrowser lists all the versions for one browser.
func (*Stats) ListBrowsers ¶
ListBrowsers lists all browser statistics for the given time period.
func (*Stats) ListLocations ¶
ListLocations lists all location statistics for the given time period.
func (*Stats) ListRefsByPath ¶
func (h *Stats) ListRefsByPath(ctx context.Context, path string, start, end time.Time, offset int) error
ListRefsByPath lists all references for a path.
func (*Stats) ListSystem ¶
ListSystem lists all the versions for one system.
func (*Stats) ListSystems ¶
ListSystems lists OS statistics for the given time period.
func (*Stats) ListTopRefs ¶
ListTopRefs lists all ref statistics for the given time period, excluding referrals from the configured LinkDomain.
The returned count is the count without LinkDomain, and is different from the total number of hits.
type Updates ¶
type Updates []Update
type User ¶
type User struct { ID int64 `db:"id" json:"id,readonly"` Site int64 `db:"site" json:"site,readonly"` Email string `db:"email" json:"email"` EmailVerified zdb.Bool `db:"email_verified" json:"email_verified,readonly"` Password []byte `db:"password" json:"-"` TOTPEnabled zdb.Bool `db:"totp_enabled" json:"totp_enabled,readonly"` TOTPSecret []byte `db:"totp_secret" json:"-"` Role string `db:"role" json:"role,readonly"` LoginAt *time.Time `db:"login_at" json:"login_at,readonly"` ResetAt *time.Time `db:"reset_at" json:"reset_at,readonly"` LoginRequest *string `db:"login_request" json:"-"` LoginToken *string `db:"login_token" json:"-"` CSRFToken *string `db:"csrf_token" json:"-"` EmailToken *string `db:"email_token" json:"-"` SeenUpdatesAt time.Time `db:"seen_updates_at" json:"-"` CreatedAt time.Time `db:"created_at" json:"created_at,readonly"` UpdatedAt *time.Time `db:"updated_at" json:"updated_at,readonly"` }
User entry.
func (*User) ByEmailToken ¶
ByEmailToken gets a user by email verification token.
func (*User) ByResetToken ¶
ByResetToken gets a user by login request key.
func (*User) ByTokenAndSite ¶
ByTokenAndSite gets a user by login token.
func (User) CorrectPassword ¶
CorrectPassword verifies that this password is correct.
func (*User) RequestReset ¶
RequestReset generates a new password reset key.
func (*User) SeenUpdates ¶
SeenUpdates marks this user as having seen all updates up until now.
func (*User) UpdatePassword ¶
UpdatePassword updates this user's password.
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
Package bgrun allows simple synchronisation of goroutines.
|
Package bgrun allows simple synchronisation of goroutines. |
Package cfg contains global application configuration settings.
|
Package cfg contains global application configuration settings. |
cmd
|
|
Package cron schedules jobs.
|
Package cron schedules jobs. |
db
|
|
Package gctest contains testing helpers.
|
Package gctest contains testing helpers. |