gutz

package
v1.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 25, 2025 License: GPL-3.0 Imports: 35 Imported by: 0

Documentation

Overview

Package gutz provides GitHub user timezone detection functionality.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CSPMiddleware

func CSPMiddleware(config *CSPConfig) func(http.HandlerFunc) http.HandlerFunc

CSPMiddleware creates a middleware that applies CSP headers.

func GenerateHistogram

func GenerateHistogram(result *Result, timezone string) string

GenerateHistogram creates a visual representation of user activity.

func IsValidGitHubUsername

func IsValidGitHubUsername(username string) bool

IsValidGitHubUsername validates GitHub username format for security. This is exported for use by the server to prevent path traversal attacks.

func NonceFromContext

func NonceFromContext(ctx context.Context) string

NonceFromContext extracts the CSP nonce from the request context.

Types

type ActiveHours

type ActiveHours struct {
	Start float64 `json:"start"`
	End   float64 `json:"end"`
}

ActiveHours represents working hours.

type ActivityData

type ActivityData struct {
	PullRequests     []github.PullRequest
	Issues           []github.Issue
	Comments         []github.Comment
	StarredRepos     []github.Repository
	CommitActivities []github.CommitActivity
	StarTimestamps   []time.Time
}

ActivityData holds all activity data for timezone detection.

type ActivityPeriod added in v1.1.0

type ActivityPeriod struct {
	Type          string  `json:"type,omitempty"`
	StartLocal    float64 `json:"start_local"`
	EndLocal      float64 `json:"end_local"`
	StartUTC      float64 `json:"start_utc"`
	EndUTC        float64 `json:"end_utc"`
	Activity      int     `json:"activity"`
	DurationHours float64 `json:"duration_hours"`
}

ActivityPeriod represents a continuous period of activity during the day.

func ClassifyActivityPeriods added in v1.1.0

func ClassifyActivityPeriods(halfHourlyActivityUTC map[float64]int, offsetHours int) []ActivityPeriod

ClassifyActivityPeriods converts UTC periods to local time and classifies them.

type CSPConfig

type CSPConfig struct {
	Mode               string
	Nonce              string
	ReportURI          string
	TrustedScriptSrcs  []string
	TrustedStyleSrcs   []string
	TrustedImageSrcs   []string
	TrustedFontSrcs    []string
	TrustedConnectSrcs []string
	TrustedFrameSrcs   []string
	DevMode            bool
}

CSPConfig holds Content Security Policy configuration.

func NewCSPConfig

func NewCSPConfig(devMode bool) *CSPConfig

NewCSPConfig creates a new CSP configuration with secure defaults.

func (*CSPConfig) BuildPolicy

func (c *CSPConfig) BuildPolicy() string

BuildPolicy constructs the CSP header value.

func (*CSPConfig) GenerateNonce

func (c *CSPConfig) GenerateNonce() error

GenerateNonce creates a cryptographically secure nonce for this request.

func (*CSPConfig) HeaderName

func (c *CSPConfig) HeaderName() string

HeaderName returns the appropriate CSP header name based on mode.

type CountryTLD

type CountryTLD struct {
	TLD     string
	Country string
}

CountryTLD represents a country top-level domain with its associated country.

type DateRange

type DateRange struct {
	OldestActivity      time.Time `json:"oldest_activity,omitempty"`
	NewestActivity      time.Time `json:"newest_activity,omitempty"`
	TotalDays           int       `json:"total_days,omitempty"`
	SpansDSTTransitions bool      `json:"spans_dst_transitions,omitempty"`
}

DateRange represents activity date range.

type Detector

type Detector struct {
	// contains filtered or unexported fields
}

Detector performs timezone detection for GitHub users.

func New

func New(ctx context.Context, opts ...Option) *Detector

New creates a new Detector with default logger.

func NewWithLogger

func NewWithLogger(ctx context.Context, logger *slog.Logger, opts ...Option) *Detector

NewWithLogger creates a new Detector with a custom logger.

func (*Detector) Close

func (d *Detector) Close() error

Close properly shuts down the detector, including saving the cache to disk.

func (*Detector) Detect

func (d *Detector) Detect(ctx context.Context, username string) (*Result, error)

Detect performs timezone detection for the given GitHub username.

type Location

type Location struct {
	Latitude  float64 `json:"latitude"`
	Longitude float64 `json:"longitude"`
}

Location represents geographic coordinates.

type LunchBreak

type LunchBreak struct {
	Start      float64 `json:"start"`
	End        float64 `json:"end"`
	Confidence float64 `json:"confidence"`
}

LunchBreak represents detected lunch break times.

type MastodonProfileData

type MastodonProfileData struct {
	ProfileFields map[string]string
	Username      string
	DisplayName   string
	Bio           string
	JoinedDate    string
	Websites      []string
	Hashtags      []string
}

MastodonProfileData represents all extracted data from a Mastodon profile.

type Option

type Option func(*OptionHolder)

Option configures a Detector.

func WithActivityAnalysis

func WithActivityAnalysis(enabled bool) Option

WithActivityAnalysis enables or disables activity analysis.

func WithCacheDir

func WithCacheDir(dir string) Option

WithCacheDir sets the cache directory for HTTP requests.

func WithGCPProject

func WithGCPProject(projectID string) Option

WithGCPProject sets the GCP project ID for Gemini API access.

func WithGeminiAPIKey

func WithGeminiAPIKey(key string) Option

WithGeminiAPIKey sets the Gemini API key for AI-based timezone detection.

func WithGeminiModel

func WithGeminiModel(model string) Option

WithGeminiModel sets the Gemini model to use for AI-based detection.

func WithGitHubToken

func WithGitHubToken(token string) Option

WithGitHubToken sets the GitHub API token for the Detector.

func WithMapsAPIKey

func WithMapsAPIKey(key string) Option

WithMapsAPIKey sets the Google Maps API key for geocoding services.

func WithMemoryOnlyCache

func WithMemoryOnlyCache() Option

WithMemoryOnlyCache configures the detector to use memory-only HTTP caching.

func WithNoCache

func WithNoCache() Option

WithNoCache disables all caching (both memory and disk).

type OptionHolder

type OptionHolder struct {
	// contains filtered or unexported fields
}

OptionHolder holds configuration options.

type OrgActivity

type OrgActivity struct {
	Name  string `json:"name"`
	Count int    `json:"count"`
}

OrgActivity represents organization activity counts.

type PeakTime

type PeakTime struct {
	Start float64 `json:"start"`
	End   float64 `json:"end"`
	Count int     `json:"count"`
}

PeakTime represents peak productivity periods.

type Result

type Result struct {
	DetectionTime              time.Time              `json:"detection_time"`
	Verification               *VerificationResult    `json:"verification,omitempty"`
	CreatedAt                  *time.Time             `json:"created_at,omitempty"`
	HourlyOrganizationActivity map[int]map[string]int `json:"hourly_organization_activity,omitempty"`
	HalfHourlyActivityUTC      map[float64]int        `json:"half_hourly_activity_utc,omitempty"`
	Location                   *Location              `json:"location,omitempty"`
	Name                       string                 `json:"name,omitempty"`
	GeminiReasoning            string                 `json:"gemini_reasoning,omitempty"`
	GeminiSuggestedLocation    string                 `json:"gemini_suggested_location,omitempty"`
	Username                   string                 `json:"username"`
	Timezone                   string                 `json:"timezone"`
	LocationName               string                 `json:"location_name,omitempty"`
	ActivityTimezone           string                 `json:"activity_timezone,omitempty"`
	GeminiPrompt               string                 `json:"gemini_prompt,omitempty"`
	Method                     string                 `json:"method"`
	GeminiMismatchReason       string                 `json:"gemini_mismatch_reason,omitempty"`
	ActivityDateRange          DateRange              `json:"activity_date_range,omitempty"`
	SleepHoursUTC              []int                  `json:"sleep_hours_utc,omitempty"`
	ActivityPeriods            []ActivityPeriod       `json:"activity_periods,omitempty"`
	TopOrganizations           []OrgActivity          `json:"top_organizations"`
	TimezoneCandidates         []timezone.Candidate   `json:"timezone_candidates,omitempty"`
	DataSources                []string               `json:"data_sources,omitempty"`
	SleepRangesLocal           []SleepRange           `json:"sleep_ranges_local,omitempty"`
	SleepBucketsUTC            []float64              `json:"sleep_buckets_utc,omitempty"`
	Timeline                   []timestampEntry       `json:"-"`
	PeakProductivityLocal      PeakTime               `json:"peak_productivity_local"`
	PeakProductivityUTC        PeakTime               `json:"peak_productivity_utc"`
	LunchHoursUTC              LunchBreak             `json:"lunch_hours_utc,omitempty"`
	LunchHoursLocal            LunchBreak             `json:"lunch_hours_local,omitempty"`
	ActiveHoursLocal           ActiveHours            `json:"active_hours_local,omitempty"`
	ActiveHoursUTC             ActiveHours            `json:"active_hours_utc,omitempty"`
	LocationConfidence         float64                `json:"location_confidence,omitempty"`
	TimezoneConfidence         float64                `json:"timezone_confidence,omitempty"`
	Confidence                 float64                `json:"confidence"`
	GeminiActivityOffsetHours  float64                `json:"gemini_activity_offset_hours,omitempty"`
	GeminiActivityMismatch     bool                   `json:"gemini_activity_mismatch,omitempty"`
	GeminiSuspiciousMismatch   bool                   `json:"gemini_suspicious_mismatch,omitempty"`
}

Result represents timezone detection results.

type SleepRange

type SleepRange struct {
	Start    float64 `json:"start"`
	End      float64 `json:"end"`
	Duration float64 `json:"duration"`
}

SleepRange represents a sleep period.

func CalculateSleepRanges

func CalculateSleepRanges(sleepHoursUTC []int, tz string) []SleepRange

CalculateSleepRanges converts UTC sleep hours to local time and groups them into ranges.

func CalculateSleepRangesFromBuckets added in v1.1.0

func CalculateSleepRangesFromBuckets(sleepBucketsUTC []float64, tz string) []SleepRange

CalculateSleepRangesFromBuckets converts UTC sleep buckets (half-hourly) into local sleep ranges.

type UserContext

type UserContext struct {
	User                    *github.User
	FromCache               map[string]bool
	GitHubTimezone          string
	ProfileLocationTimezone string
	Username                string
	ProfileHTML             string
	Repositories            []github.Repository
	StarredRepos            []github.Repository
	PullRequests            []github.PullRequest
	Issues                  []github.Issue
	Comments                []github.Comment
	Gists                   []github.Gist
	Commits                 []time.Time
	CommitActivities        []github.CommitActivity
	Organizations           []github.Organization
	Events                  []github.PublicEvent
	SSHKeys                 []github.SSHKey
}

UserContext holds all fetched data for a user to avoid redundant API calls.

type VerificationResult

type VerificationResult struct {
	ProfileLocation         string  `json:"profile_location,omitempty"`
	ProfileTimezone         string  `json:"profile_timezone,omitempty"`
	ProfileLocationTimezone string  `json:"profile_location_timezone,omitempty"`
	LocationMismatch        string  `json:"location_mismatch,omitempty"`
	TimezoneMismatch        string  `json:"timezone_mismatch,omitempty"`
	ProfileLocationDiff     int     `json:"profile_location_diff,omitempty"`
	ActivityOffsetDiff      int     `json:"activity_offset_diff,omitempty"`
	LocationDistanceKm      float64 `json:"location_distance_km,omitempty"`
	TimezoneOffsetDiff      int     `json:"timezone_offset_diff,omitempty"`
	ActivityMismatch        bool    `json:"activity_mismatch,omitempty"`
}

VerificationResult contains the results of verifying profile vs detected location/timezone.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL