Documentation
¶
Overview ¶
Package models defines core data structures and errors Per AI.md PART 31: Standard error definitions and data models
Index ¶
- Constants
- Variables
- func ErrorCodeFromHTTP(status int) string
- func HTTPStatusCode(code string) int
- func IsValidSortOrder(s SortOrder) bool
- func StripHTML(s string) string
- type Category
- type EngineConfig
- type Query
- type RSSChannel
- type RSSFeed
- type RSSItem
- type Result
- type SearchResults
- func (sr *SearchResults) AddResult(result Result)
- func (sr *SearchResults) AddResults(results []Result)
- func (sr *SearchResults) CalculateTotalPages()
- func (sr *SearchResults) GetPage(page int) []Result
- func (sr *SearchResults) ToAtom(w io.Writer, baseURL string) error
- func (sr *SearchResults) ToCSV(w io.Writer) error
- func (sr *SearchResults) ToJSON(w io.Writer, pretty bool) error
- func (sr *SearchResults) ToRSS(w io.Writer, baseURL string) error
- type SortOrder
Constants ¶
const ( // 400 Bad Request ErrCodeBadRequest = "BAD_REQUEST" // Malformed request syntax ErrCodeValidation = "VALIDATION_FAILED" // Input validation failed // 401 Unauthorized 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 ¶
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") 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
var ErrorCodeToHTTP = map[string]int{ ErrCodeBadRequest: 400, ErrCodeValidation: 400, ErrCodeUnauthorized: 401, ErrCodeTokenExpired: 401, ErrCodeTokenInvalid: 401, ErrCode2FARequired: 401, ErrCode2FAInvalid: 401, ErrCodeForbidden: 403, ErrCodeAccountLocked: 403, ErrCodeNotFound: 404, ErrCodeMethodNotAllowed: 405, ErrCodeConflict: 409, ErrCodeUnprocessable: 422, ErrCodeRateLimit: 429, ErrCodeInternal: 500, ErrCodeMaintenance: 503, }
ErrorCodeToHTTP maps error codes to HTTP status codes
var HTTPToErrorCode = map[int]string{ 400: ErrCodeBadRequest, 401: ErrCodeUnauthorized, 403: ErrCodeForbidden, 404: ErrCodeNotFound, 405: ErrCodeMethodNotAllowed, 409: ErrCodeConflict, 422: ErrCodeUnprocessable, 429: ErrCodeRateLimit, 500: ErrCodeInternal, 503: ErrCodeMaintenance, }
HTTPToErrorCode maps HTTP status codes to default error codes Per AI.md PART 16: Unified Response Format
var ValidSortOrders = []SortOrder{SortRelevance, SortDate, SortDateAsc, SortPopularity, SortRandom}
ValidSortOrders is a list of valid sort orders
Functions ¶
func ErrorCodeFromHTTP ¶
ErrorCodeFromHTTP returns the default error code for an HTTP status
func HTTPStatusCode ¶
HTTPStatusCode returns the HTTP status code for an error code
func IsValidSortOrder ¶
IsValidSortOrder checks if a sort order is valid
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" )
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 (*Query) GetEffectiveText ¶
GetEffectiveText returns the text to use for searching (cleaned or original)
func (*Query) HasAdvancedFilters ¶
HasAdvancedFilters checks if advanced filters are set
func (*Query) HasMediaFilters ¶
HasMediaFilters checks if media-specific filters are set
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) ExtractDomain ¶
ExtractDomain extracts the domain from the URL
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