gutz

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Aug 21, 2025 License: GPL-3.0 Imports: 32 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, hourCounts map[int]int, 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
}

ActivityData holds all activity data for timezone detection.

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 CommitMessageSample

type CommitMessageSample struct {
	Message string
	Author  string
}

CommitMessageSample represents a sample commit message for analysis.

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 WithHTTPClient

func WithHTTPClient(_ any) Option

WithHTTPClient sets the HTTP client (kept for compatibility, not implemented).

func WithLogger

func WithLogger(_ any) Option

WithLogger sets the logger (kept for compatibility, handled differently).

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"`
	Location                   *Location              `json:"location,omitempty"`
	HourlyOrganizationActivity map[int]map[string]int `json:"hourly_organization_activity,omitempty"`
	HourlyActivityUTC          map[int]int            `json:"hourly_activity_utc"`
	HalfHourlyActivityUTC      map[float64]int        `json:"-"`
	Method                     string                 `json:"method"`
	LocationName               string                 `json:"location_name,omitempty"`
	GeminiSuggestedLocation    string                 `json:"gemini_suggested_location,omitempty"`
	Name                       string                 `json:"name,omitempty"`
	Timezone                   string                 `json:"timezone"`
	GeminiReasoning            string                 `json:"gemini_reasoning,omitempty"`
	Username                   string                 `json:"username"`
	CreatedAt                  *time.Time             `json:"created_at,omitempty"`
	ActivityTimezone           string                 `json:"activity_timezone,omitempty"`
	GeminiPrompt               string                 `json:"gemini_prompt,omitempty"`
	ActivityDateRange          DateRange              `json:"activity_date_range,omitempty"`
	SleepHoursUTC              []int                  `json:"sleep_hours_utc,omitempty"`
	SleepRangesLocal           []SleepRange           `json:"sleep_ranges_local,omitempty"`
	TopOrganizations           []OrgActivity          `json:"top_organizations"`
	SleepBucketsUTC            []float64              `json:"sleep_buckets_utc,omitempty"`
	TimezoneCandidates         []timezone.Candidate   `json:"timezone_candidates,omitempty"`
	DataSources                []string               `json:"data_sources,omitempty"`
	LunchHoursUTC              LunchBreak             `json:"lunch_hours_utc,omitempty"`
	LunchHoursLocal            LunchBreak             `json:"lunch_hours_local,omitempty"`
	PeakProductivityUTC        PeakTime               `json:"peak_productivity_utc"`
	PeakProductivityLocal      PeakTime               `json:"peak_productivity_local"`
	ActiveHoursLocal           ActiveHours            `json:"active_hours_local,omitempty"`
	LocationConfidence         float64                `json:"location_confidence,omitempty"`
	TimezoneConfidence         float64                `json:"timezone_confidence,omitempty"`
	Confidence                 float64                `json:"confidence"`
	GeminiActivityMismatch     bool                   `json:"gemini_activity_mismatch,omitempty"`
	Verification               *VerificationResult    `json:"verification,omitempty"`
	GeminiSuspiciousMismatch   bool                   `json:"gemini_suspicious_mismatch,omitempty"`
	GeminiMismatchReason       string                 `json:"gemini_mismatch_reason,omitempty"`
	GeminiActivityOffsetHours  float64                `json:"gemini_activity_offset_hours,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.

type UserContext

type UserContext struct {
	User             *github.User
	GitHubTimezone   string // Timezone from GitHub profile (e.g., "UTC-12")
	FromCache        map[string]bool
	Username         string
	ProfileHTML      string
	PullRequests     []github.PullRequest
	StarredRepos     []github.Repository
	Repositories     []github.Repository
	Issues           []github.Issue
	Comments         []github.Comment
	Gists            []github.Gist // Full gist objects with descriptions
	Commits          []time.Time
	CommitActivities []github.CommitActivity // Enhanced commit data with repository info
	Organizations    []github.Organization
	Events           []github.PublicEvent
	SSHKeys          []github.SSHKey // SSH public keys with creation timestamps
}

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

type VerificationResult

type VerificationResult struct {
	ClaimedLocation       string  `json:"claimed_location,omitempty"`
	ClaimedTimezone       string  `json:"claimed_timezone,omitempty"`
	LocationDistanceMiles float64 `json:"location_distance_miles,omitempty"`
	TimezoneOffsetDiff    int     `json:"timezone_offset_diff,omitempty"`
	LocationMismatch      string  `json:"location_mismatch,omitempty"` // "major" (>1000mi), "minor" (>250mi), or ""
	TimezoneMismatch      string  `json:"timezone_mismatch,omitempty"` // "major" (>3tz), "minor" (>1tz), or ""
}

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

Jump to

Keyboard shortcuts

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