model

package
v1.0.0 Latest Latest
Warning

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

Go to latest
Published: Feb 3, 2026 License: Apache-2.0, BSD-3-Clause, MIT Imports: 10 Imported by: 0

Documentation

Overview

Package models defines core data structures and errors Per AI.md PART 31: Standard error definitions and data models

Index

Constants

View Source
const (
	// 400 Bad Request
	ErrCodeBadRequest = "BAD_REQUEST"       // Malformed request syntax
	ErrCodeValidation = "VALIDATION_FAILED" // Input validation failed

	// 401 Unauthorized
	ErrCodeUnauthorized = "UNAUTHORIZED"  // Authentication required
	ErrCodeTokenExpired = "TOKEN_EXPIRED" // Token has expired
	ErrCodeTokenInvalid = "TOKEN_INVALID" // Invalid token
	ErrCode2FARequired  = "2FA_REQUIRED"  // Two-factor authentication required
	ErrCode2FAInvalid   = "2FA_INVALID"   // Invalid 2FA code

	// 403 Forbidden
	ErrCodeForbidden     = "FORBIDDEN"      // Permission denied
	ErrCodeAccountLocked = "ACCOUNT_LOCKED" // Account temporarily locked

	// 404 Not Found
	ErrCodeNotFound = "NOT_FOUND" // Resource not found

	// 405 Method Not Allowed
	ErrCodeMethodNotAllowed = "METHOD_NOT_ALLOWED" // HTTP method not supported

	// 409 Conflict
	ErrCodeConflict = "CONFLICT" // Resource already exists or version conflict

	// 422 Unprocessable Entity (uses same code as 400 validation - semantic validation)
	ErrCodeUnprocessable = "UNPROCESSABLE" // Semantic validation error

	// 429 Too Many Requests
	ErrCodeRateLimit = "RATE_LIMITED" // Rate limit exceeded

	// 500 Internal Server Error
	ErrCodeInternal = "SERVER_ERROR" // Server error

	// 503 Service Unavailable
	ErrCodeMaintenance = "MAINTENANCE" // Maintenance mode or overloaded
)

Standard Error Codes per AI.md PART 16: Unified Response Format These map to HTTP status codes for consistent API responses

Variables

View Source
var (
	// Query errors
	ErrEmptyQuery      = errors.New("query text cannot be empty")
	ErrInvalidCategory = errors.New("invalid category")

	// Engine errors
	ErrEngineNotFound    = errors.New("engine not found")
	ErrEngineDisabled    = errors.New("engine is disabled")
	ErrEngineUnavailable = errors.New("engine is unavailable")
	ErrEngineTimeout     = errors.New("engine request timed out")
	ErrEngineRateLimit   = errors.New("engine rate limit exceeded")

	// Search errors
	ErrNoResults     = errors.New("no results found")
	ErrNoEngines     = errors.New("no engines available")
	ErrSearchTimeout = errors.New("search request timed out")

	// Configuration errors
	ErrInvalidConfig = errors.New("invalid configuration")
	ErrMissingConfig = errors.New("missing required configuration")
)

Domain-specific errors

ErrorCodeToHTTP maps error codes to HTTP status codes

HTTPToErrorCode maps HTTP status codes to default error codes Per AI.md PART 16: Unified Response Format

ValidSortOrders is a list of valid sort orders

Functions

func ErrorCodeFromHTTP

func ErrorCodeFromHTTP(status int) string

ErrorCodeFromHTTP returns the default error code for an HTTP status

func HTTPStatusCode

func HTTPStatusCode(code string) int

HTTPStatusCode returns the HTTP status code for an error code

func IsValidSortOrder

func IsValidSortOrder(s SortOrder) bool

IsValidSortOrder checks if a sort order is valid

func StripHTML

func StripHTML(s string) string

StripHTML removes HTML tags from text and decodes HTML entities. For example, `<span class="searchmatch">Google</span>` becomes "Google" and `&amp;` becomes "&".

Types

type Category

type Category string

Category represents a search category

const (
	CategoryGeneral Category = "general"
	CategoryImages  Category = "images"
	CategoryVideos  Category = "videos"
	CategoryNews    Category = "news"
	CategoryMaps    Category = "maps"
	CategoryFiles   Category = "files"
	CategoryIT      Category = "it"
	CategoryScience Category = "science"
	CategorySocial  Category = "social"
)

func AllCategories

func AllCategories() []Category

AllCategories returns all available categories

func (Category) IsValid

func (c Category) IsValid() bool

IsValid checks if the category is valid

func (Category) String

func (c Category) String() string

String returns the string representation of a category

type EngineConfig

type EngineConfig struct {
	Name        string   `yaml:"name" json:"name"`
	DisplayName string   `yaml:"display_name" json:"display_name"`
	Enabled     bool     `yaml:"enabled" json:"enabled"`
	Priority    int      `yaml:"priority" json:"priority"`
	Categories  []string `yaml:"categories" json:"categories"`
	Language    string   `yaml:"language" json:"language"`
	Timeout     int      `yaml:"timeout" json:"timeout"` // seconds
	MaxResults  int      `yaml:"max_results" json:"max_results"`

	// Tor support
	SupportsTor bool `yaml:"supports_tor" json:"supports_tor"`
	UseTor      bool `yaml:"use_tor" json:"use_tor"`

	// Rate limiting
	RateLimit struct {
		Requests int `yaml:"requests" json:"requests"`
		Window   int `yaml:"window" json:"window"` // seconds
	} `yaml:"rate_limit" json:"rate_limit"`

	// Engine-specific settings
	Settings map[string]interface{} `yaml:"settings,omitempty" json:"settings,omitempty"`
}

EngineConfig represents configuration for a search engine

func NewEngineConfig

func NewEngineConfig(name string) *EngineConfig

NewEngineConfig creates a new EngineConfig with defaults

func (*EngineConfig) GetMaxResults

func (ec *EngineConfig) GetMaxResults() int

GetMaxResults returns the maximum number of results

func (*EngineConfig) GetPriority

func (ec *EngineConfig) GetPriority() int

GetPriority returns the engine priority

func (*EngineConfig) GetTimeout

func (ec *EngineConfig) GetTimeout() int

GetTimeout returns the timeout in seconds

func (*EngineConfig) IsEnabled

func (ec *EngineConfig) IsEnabled() bool

IsEnabled checks if the engine is enabled

func (*EngineConfig) SupportsCategory

func (ec *EngineConfig) SupportsCategory(category Category) bool

SupportsCategory checks if the engine supports a category

type Query

type Query struct {
	// User input
	Text string `json:"text"`

	// Filters
	Category   Category `json:"category"`
	Language   string   `json:"language"`
	Region     string   `json:"region,omitempty"` // Region code (us, uk, de, etc.)
	SafeSearch int      `json:"safe_search"`      // 0: off, 1: moderate, 2: strict

	// Pagination
	Page    int `json:"page"`
	PerPage int `json:"per_page"`

	// Sorting
	SortBy SortOrder `json:"sort_by,omitempty"`

	// Time range
	TimeRange string `json:"time_range,omitempty"` // any, day, week, month, year

	// Advanced filters (parsed from operators or set directly)
	Site         string   `json:"site,omitempty"`
	ExcludeSite  string   `json:"exclude_site,omitempty"`
	FileType     string   `json:"file_type,omitempty"`
	FileTypes    []string `json:"file_types,omitempty"`
	InURL        string   `json:"in_url,omitempty"`
	InTitle      string   `json:"in_title,omitempty"`
	InText       string   `json:"in_text,omitempty"`
	ExactTerms   string   `json:"exact_terms,omitempty"`
	ExactPhrases []string `json:"exact_phrases,omitempty"`
	ExcludeTerms []string `json:"exclude_terms,omitempty"`

	// Date filters
	DateBefore string `json:"date_before,omitempty"` // YYYY-MM-DD
	DateAfter  string `json:"date_after,omitempty"`  // YYYY-MM-DD

	// Media-specific filters
	ImageSize    string `json:"image_size,omitempty"`    // small, medium, large, xlarge
	ImageType    string `json:"image_type,omitempty"`    // photo, clipart, lineart, animated
	ImageColor   string `json:"image_color,omitempty"`   // color, gray, trans, red, etc.
	ImageAspect  string `json:"image_aspect,omitempty"`  // square, wide, tall
	VideoLength  string `json:"video_length,omitempty"`  // short, medium, long
	VideoQuality string `json:"video_quality,omitempty"` // hd, 4k

	// News-specific
	NewsSource string `json:"news_source,omitempty"` // source:nytimes

	// Engine selection
	Engines        []string `json:"engines,omitempty"`
	ExcludeEngines []string `json:"exclude_engines,omitempty"`

	// Parsed operators (internal use)
	ParsedOperators interface{} `json:"-"`
	CleanedText     string      `json:"-"` // Text with operators removed
}

Query represents a search query

func NewQuery

func NewQuery(text string) *Query

NewQuery creates a new Query with defaults (sanitizes input)

func (*Query) GetEffectiveText

func (q *Query) GetEffectiveText() string

GetEffectiveText returns the text to use for searching (cleaned or original)

func (*Query) HasAdvancedFilters

func (q *Query) HasAdvancedFilters() bool

HasAdvancedFilters checks if advanced filters are set

func (*Query) HasMediaFilters

func (q *Query) HasMediaFilters() bool

HasMediaFilters checks if media-specific filters are set

func (*Query) IsEmpty

func (q *Query) IsEmpty() bool

IsEmpty checks if the query text is empty

func (*Query) Sanitize

func (q *Query) Sanitize()

Sanitize strips leading and trailing whitespace from all text fields

func (*Query) Validate

func (q *Query) Validate() error

Validate checks if the query is valid (sanitizes first)

type RSSChannel

type RSSChannel struct {
	Title         string    `xml:"title"`
	Link          string    `xml:"link"`
	Description   string    `xml:"description"`
	Language      string    `xml:"language,omitempty"`
	LastBuildDate string    `xml:"lastBuildDate"`
	Items         []RSSItem `xml:"item"`
}

RSSChannel represents an RSS channel

type RSSFeed

type RSSFeed struct {
	XMLName xml.Name   `xml:"rss"`
	Version string     `xml:"version,attr"`
	Channel RSSChannel `xml:"channel"`
}

RSSFeed represents an RSS 2.0 feed

type RSSItem

type RSSItem struct {
	Title       string `xml:"title"`
	Link        string `xml:"link"`
	Description string `xml:"description"`
	Author      string `xml:"author,omitempty"`
	PubDate     string `xml:"pubDate,omitempty"`
	Source      string `xml:"source,omitempty"`
	GUID        string `xml:"guid"`
}

RSSItem represents an RSS item

type Result

type Result struct {
	// Core fields
	Title    string   `json:"title" xml:"title"`
	URL      string   `json:"url" xml:"link"`
	Content  string   `json:"content" xml:"description"`
	Engine   string   `json:"engine" xml:"source"`
	Category Category `json:"category" xml:"category"`

	// Additional fields
	Thumbnail   string    `json:"thumbnail,omitempty" xml:"thumbnail,omitempty"`
	Author      string    `json:"author,omitempty" xml:"author,omitempty"`
	PublishedAt time.Time `json:"published_at,omitempty" xml:"pubDate,omitempty"`
	Domain      string    `json:"domain,omitempty" xml:"domain,omitempty"`

	// Media-specific fields
	ImageWidth  int    `json:"image_width,omitempty" xml:"-"`
	ImageHeight int    `json:"image_height,omitempty" xml:"-"`
	ImageFormat string `json:"image_format,omitempty" xml:"-"`
	Duration    int    `json:"duration,omitempty" xml:"-"`   // Video duration in seconds
	ViewCount   int64  `json:"view_count,omitempty" xml:"-"` // Video view count
	FileSize    int64  `json:"file_size,omitempty" xml:"-"`  // File size in bytes
	FileType    string `json:"file_type,omitempty" xml:"-"`  // File extension

	// Scoring fields
	Score          float64 `json:"score" xml:"-"`
	Position       int     `json:"position" xml:"-"`
	Relevance      float64 `json:"relevance,omitempty" xml:"-"`       // Engine-provided relevance
	Popularity     float64 `json:"popularity,omitempty" xml:"-"`      // Engagement/popularity score
	DuplicateCount int     `json:"duplicate_count,omitempty" xml:"-"` // How many engines returned this

	// Language detection
	Language string `json:"language,omitempty" xml:"language,omitempty"`

	// Metadata
	Metadata map[string]interface{} `json:"metadata,omitempty" xml:"-"`
}

Result represents a single search result from an engine

func (*Result) Age

func (r *Result) Age() time.Duration

Age returns how old the result is

func (*Result) ExtractDomain

func (r *Result) ExtractDomain() string

ExtractDomain extracts the domain from the URL

func (*Result) IsRecent

func (r *Result) IsRecent(hours int) bool

IsRecent checks if the result is from the last n hours

func (*Result) Sanitize

func (r *Result) Sanitize()

Sanitize strips leading and trailing whitespace from all text fields, removes HTML tags, and decodes HTML entities from content fields. Per AI.md: All search results must have whitespace trimmed

type SearchResults

type SearchResults struct {
	Query        string    `json:"query" xml:"query"`
	Category     Category  `json:"category" xml:"category"`
	Results      []Result  `json:"results" xml:"item"`
	TotalResults int       `json:"total_results" xml:"totalResults"`
	Page         int       `json:"page" xml:"page"`
	PerPage      int       `json:"per_page" xml:"perPage"`
	TotalPages   int       `json:"total_pages" xml:"totalPages"`
	SearchTime   float64   `json:"search_time" xml:"searchTime"`
	Engines      []string  `json:"engines" xml:"engines"`
	Suggestions  []string  `json:"suggestions,omitempty" xml:"suggestions,omitempty"`
	SortedBy     SortOrder `json:"sorted_by,omitempty" xml:"sortedBy,omitempty"`

	// Facets for filtering - populated by aggregator when results contain domain/language metadata
	Domains   map[string]int `json:"domains,omitempty" xml:"-"`
	Languages map[string]int `json:"languages,omitempty" xml:"-"`
}

SearchResults represents aggregated search results

func NewSearchResults

func NewSearchResults(query string, category Category) *SearchResults

NewSearchResults creates a new SearchResults instance

func (*SearchResults) AddResult

func (sr *SearchResults) AddResult(result Result)

AddResult adds a result to the collection (sanitizes whitespace automatically)

func (*SearchResults) AddResults

func (sr *SearchResults) AddResults(results []Result)

AddResults adds multiple results to the collection (sanitizes whitespace automatically)

func (*SearchResults) CalculateTotalPages

func (sr *SearchResults) CalculateTotalPages()

CalculateTotalPages calculates the total number of pages

func (*SearchResults) GetPage

func (sr *SearchResults) GetPage(page int) []Result

GetPage returns results for a specific page

func (*SearchResults) ToAtom

func (sr *SearchResults) ToAtom(w io.Writer, baseURL string) error

ToAtom exports results as Atom feed

func (*SearchResults) ToCSV

func (sr *SearchResults) ToCSV(w io.Writer) error

ToCSV exports results as CSV Uses idiomatic csv.Writer pattern: write all data, then check for accumulated errors

func (*SearchResults) ToJSON

func (sr *SearchResults) ToJSON(w io.Writer, pretty bool) error

ToJSON exports results as JSON

func (*SearchResults) ToRSS

func (sr *SearchResults) ToRSS(w io.Writer, baseURL string) error

ToRSS exports results as RSS 2.0 feed

type SortOrder

type SortOrder string

SortOrder defines how results are sorted

const (
	SortRelevance  SortOrder = "relevance"  // Default: by score
	SortDate       SortOrder = "date"       // By date (newest first)
	SortDateAsc    SortOrder = "date_asc"   // By date (oldest first)
	SortPopularity SortOrder = "popularity" // By popularity/engagement
	SortRandom     SortOrder = "random"     // Random order
)

Jump to

Keyboard shortcuts

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