Documentation
¶
Index ¶
- type AnalysisConfig
- type AnthropicModelsResponse
- type AnthropicRequest
- type AnthropicResponse
- type Article
- type ArticleAnalysis
- type ArticleCounts
- type ArticleFilter
- type ArticleInspection
- type ArticleUpdate
- type Category
- type CodexCredential
- type Digest
- type DigestAnalysis
- type DigestArticle
- type DigestProviderResult
- type DiscordNotificationConfig
- type Feed
- type FeedConfig
- type FeedDiagnosis
- type FeedGroup
- type FeedItem
- type FeedResult
- type FeedsFile
- type FetchResult
- type GenericLLMRequest
- type GitHubPagesNotificationConfig
- type GlossaryTerm
- type HostTriggers
- type LlamaCppModelsResponse
- type Message
- type ModelInfo
- type ModelsResponse
- type NotificationsConfig
- type OllamaModelDetails
- type OllamaModelsResponse
- type OllamaRequest
- type OllamaResponse
- type OpenAIModelsResponse
- type OpenAIRequest
- type OpenAIResponse
- type ProviderConfig
- type ReferencedReport
- type RelatedArticle
- type SelectorCandidate
- type Selectors
- type ServerConfig
- type Tag
- type WorkerPoolConfig
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type AnalysisConfig ¶
type AnalysisConfig struct {
Provider string `json:"provider,omitempty"` // Name of the configured provider to use for analysis
Persona string `json:"persona,omitempty"` // Additional prompt prefix to customize the AI instructions
WritingStyle string `json:"writing_style,omitempty"` // Writing style guide injected into digest summary prompt
WorkerPool *WorkerPoolConfig `json:"worker_pool,omitempty"` // Configuration for the analysis worker pool
AutoAnalyze bool `json:"auto_analyze,omitempty"` // Automatically enqueue articles for analysis after each feed refresh
VibeScore bool `json:"vibe_score,omitempty"` // Use the legacy single-number LLM importance prompt instead of the rubric scoring system
Glossary bool `json:"glossary,omitempty"` // Generate glossary-mode content (plain-language explanation + jargon glossary) as an extra analysis task
}
AnalysisConfig represents the configuration for the analysis features
type AnthropicModelsResponse ¶
type AnthropicModelsResponse struct {
Data []struct {
Type string `json:"type"`
Id string `json:"id"`
DisplayName string `json:"display_name"`
CreatedAt string `json:"created_at"`
MaxInputTokens int `json:"max_input_tokens"`
MaxTokens int `json:"max_tokens"`
} `json:"data"`
HasMore bool `json:"has_more"`
FirstId string `json:"first_id"`
LastId string `json:"last_id"`
}
AnthropicModelsResponse represents the response from Anthropic's models endpoint
type AnthropicRequest ¶
type AnthropicRequest struct {
Model string `json:"model"`
Messages []Message `json:"messages"`
Temperature float64 `json:"temperature,omitempty"`
MaxTokens int `json:"max_tokens,omitempty"`
}
AnthropicRequest represents a request to the Anthropic API
type AnthropicResponse ¶
type AnthropicResponse struct {
Id string `json:"id"`
Type string `json:"type"`
Model string `json:"model"`
Content []struct {
Type string `json:"type"`
Text string `json:"text"`
} `json:"content"`
}
AnthropicResponse represents a response from the Anthropic API
type Article ¶
type Article struct {
Id string `gorm:"primaryKey" json:"id"`
FeedId string `gorm:"index" json:"feed_id"`
Title string `json:"title"`
Content string `gorm:"type:text" json:"content"`
Link string `json:"link"`
PublishedAt time.Time `gorm:"index" json:"published_at"`
FetchedAt time.Time `json:"fetched_at"`
Read *bool `gorm:"default:false" json:"read"`
Tags []Tag `gorm:"many2many:article_tags;" json:"tags"`
CategoryName *string `gorm:"index" json:"category_name,omitempty"`
Category *Category `gorm:"foreignKey:CategoryName;references:Name" json:"category,omitempty"`
HeroImage string `json:"hero_image,omitempty"`
Bookmarked *bool `gorm:"default:false" json:"bookmarked"`
RelatedArticles []RelatedArticle `gorm:"-" json:"related_articles,omitempty"` // Handled separately
// LatestImportanceScore is populated only by ListArticles (via JOIN on the latest analysis).
// Not persisted on the Article row.
LatestImportanceScore *int32 `gorm:"-" json:"latest_importance_score,omitempty"`
}
Article represents an article from a feed
func (*Article) BeforeCreate ¶
BeforeCreate ensures Id is set before creating a record
type ArticleAnalysis ¶
type ArticleAnalysis struct {
Id string `gorm:"primaryKey" json:"id"`
ArticleId string `gorm:"index" json:"article_id"`
ProviderType string `json:"provider_type"`
ModelName string `json:"model_name"`
ImportanceScore int `json:"importance_score"`
ScoreDimensionsJson string `gorm:"column:score_dimensions;type:text" json:"-"`
ScoreDimensions *scoring.Dimensions `gorm:"-" json:"score_dimensions,omitempty"`
KeyPointsJson string `gorm:"column:key_points;type:text" json:"-"`
InsightsJson string `gorm:"column:insights;type:text" json:"-"`
ReferencedReportsJson string `gorm:"column:referenced_reports;type:text" json:"-"`
KeyPoints []string `gorm:"-" json:"key_points"`
Insights []string `gorm:"-" json:"insights"`
ReferencedReports []ReferencedReport `gorm:"-" json:"referenced_reports"`
Tldr string `gorm:"type:text" json:"tldr"`
Justification string `gorm:"type:text" json:"justification"`
BriefOverview string `gorm:"type:text" json:"brief_overview"`
StandardSynthesis string `gorm:"type:text" json:"standard_synthesis"`
ComprehensiveSynthesis string `gorm:"type:text" json:"comprehensive_synthesis"`
GlossaryExplanation string `gorm:"type:text" json:"glossary_explanation"`
GlossaryTermsJson string `gorm:"column:glossary_terms;type:text" json:"-"`
GlossaryTerms []GlossaryTerm `gorm:"-" json:"glossary_terms"`
ThinkingProcess string `gorm:"type:text" json:"thinking_process,omitempty"`
RawResponse string `gorm:"type:text" json:"raw_response"`
CreatedAt time.Time `gorm:"index" json:"created_at"`
Article *Article `gorm:"foreignKey:ArticleId;references:Id" json:"-"`
}
ArticleAnalysis represents an analysis result from an LLM provider for an article
func (*ArticleAnalysis) AfterFind ¶
func (a *ArticleAnalysis) AfterFind(tx *gorm.DB) error
AfterFind converts JSON strings back to slices after querying
func (*ArticleAnalysis) BeforeCreate ¶
func (a *ArticleAnalysis) BeforeCreate(tx *gorm.DB) error
BeforeCreate ensures Id is set before creating a record
func (ArticleAnalysis) TableName ¶
func (ArticleAnalysis) TableName() string
TableName specifies the table name for ArticleAnalysis
type ArticleCounts ¶
type ArticleFilter ¶
type ArticleFilter struct {
UnreadOnly bool `json:"unread_only"`
CategoryName string `json:"category_name"`
TagId string `json:"tag_id"`
BookmarkedOnly bool `json:"bookmarked_only"`
RelatedToId string `json:"related_to_id"`
StartDate *time.Time `json:"start_date,omitempty"`
EndDate *time.Time `json:"end_date,omitempty"`
FeedId string `json:"feed_id"`
ExcludeDigested bool `json:"exclude_digested,omitempty"`
Offset int `json:"offset,omitempty"`
Limit int `json:"limit,omitempty"`
Query string `json:"query,omitempty"`
}
ArticleFilter represents filtering options for listing articles
type ArticleInspection ¶ added in v0.2.0
type ArticleInspection struct {
ModeUsed string `json:"mode_used"`
RawHTMLLen int `json:"raw_html_len"`
HTML string `json:"html"` // page HTML (capped) for selector inspection
Extracted string `json:"extracted"` // extracted markdown when selectors supplied
ExtractedLen int `json:"extracted_len"` // rune count of Extracted
SelectorMatched bool `json:"selector_matched"` // the article selector matched an element
Error string `json:"error"`
DurationMs int64 `json:"duration_ms"`
}
ArticleInspection is the result of scraping a single article URL in a given mode, used by the feed-config builder to inspect page HTML and test selectors.
type ArticleUpdate ¶
type ArticleUpdate struct {
Read *bool `json:"read,omitempty"`
TagIds *[]string `json:"tag_ids,omitempty"`
CategoryName *string `json:"category_name,omitempty"`
HeroImage *string `json:"hero_image,omitempty"`
Bookmarked *bool `json:"bookmarked,omitempty"`
RelatedArticles *[]RelatedArticle `json:"related_articles,omitempty"`
}
ArticleUpdate represents fields that can be updated for an article
type Category ¶
type Category struct {
Name string `gorm:"uniqueIndex,primaryKey" json:"name"`
Color string `json:"color"` // For UI display
Icon string `json:"icon"` // For UI display
Articles []Article `gorm:"foreignKey:CategoryName;references:Name" json:"-"` // One-to-many relationship with articles
}
Category represents an article category
type CodexCredential ¶
type CodexCredential struct {
Id string `json:"id"` // short random ID
Label string `json:"label"` // email or fallback
Priority int `json:"priority"` // lower = preferred
AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"`
LastRefresh time.Time `json:"last_refresh"`
AuthMode string `json:"auth_mode"` // "chatgpt" | "claude"
Source string `json:"source"` // "manual:device_code" | "manual:pkce"
ExpiresAt *time.Time `json:"expires_at,omitempty"` // OAuth absolute expiry (non-JWT tokens, e.g. claude-code)
LastStatus string `json:"last_status,omitempty"` // "ok" | "auth_failed" | "rate_limited"
LastStatusAt *time.Time `json:"last_status_at,omitempty"`
LastErrorReason string `json:"last_error_reason,omitempty"`
LastErrorResetAt *time.Time `json:"last_error_reset_at,omitempty"` // when rate_limited expires
}
CodexCredential holds OAuth state for a single ChatGPT/Codex account.
type Digest ¶
type Digest struct {
Id string `gorm:"primaryKey" json:"id"`
CreatedAt time.Time `gorm:"index" json:"created_at"`
Title string `gorm:"type:text" json:"title,omitempty"`
ArticleCount *int `gorm:"default:0" json:"article_count"`
TimeWindow time.Duration `json:"time_window"`
RawGroupingResponse string `gorm:"type:text" json:"raw_grouping_response,omitempty"`
DigestSummary string `gorm:"type:text" json:"digest_summary,omitempty"`
ProviderResults []DigestProviderResult `gorm:"-" json:"provider_results"` // Handled through separate table
DigestAnalyses []DigestAnalysis `gorm:"-" json:"digest_analyses,omitempty"` // Handled through separate table
Articles []Article `gorm:"many2many:digest_articles;" json:"-"`
AnalysisErrors map[string]string `gorm:"-" json:"-"` // transient: articleId → classified error, not persisted
}
Digest represents a generated digest of articles
type DigestAnalysis ¶
type DigestAnalysis struct {
DigestId string `gorm:"primaryKey;index" json:"digest_id"`
AnalysisId string `gorm:"primaryKey" json:"analysis_id"`
ArticleId string `gorm:"index" json:"article_id"`
DuplicateGroup string `json:"duplicate_group,omitempty"`
IsMostComprehensive bool `gorm:"default:false" json:"is_most_comprehensive"`
Analysis *ArticleAnalysis `gorm:"foreignKey:AnalysisId;references:Id" json:"analysis,omitempty"`
}
DigestAnalysis links an ArticleAnalysis to a Digest with duplicate-group metadata.
func (DigestAnalysis) TableName ¶
func (DigestAnalysis) TableName() string
type DigestArticle ¶
type DigestArticle struct {
DigestId string `json:"digest_id"`
ArticleId string `json:"article_id"`
}
DigestArticle represents an article included in a digest
type DigestProviderResult ¶
type DigestProviderResult struct {
Id string `gorm:"primaryKey" json:"id"`
DigestId string `gorm:"index" json:"digest_id"`
ProviderType string `json:"provider_type"`
ModelName string `json:"model_name"`
BriefOverview string `gorm:"type:text" json:"brief_overview"`
StandardSynthesis string `gorm:"type:text" json:"standard_synthesis"`
ComprehensiveSynthesis string `gorm:"type:text" json:"comprehensive_synthesis"`
ProcessingTime float64 `json:"processing_time"`
Error string `json:"error"`
CreatedAt time.Time `gorm:"index" json:"created_at"`
Digest *Digest `gorm:"foreignKey:DigestId" json:"-"`
}
DigestProviderResult represents a provider's result for a digest
func (*DigestProviderResult) BeforeCreate ¶
func (d *DigestProviderResult) BeforeCreate(tx *gorm.DB) error
BeforeCreate ensures Id is set before creating a record
func (DigestProviderResult) TableName ¶
func (DigestProviderResult) TableName() string
TableName specifies the table name for DigestProviderResult
type DiscordNotificationConfig ¶
type DiscordNotificationConfig struct {
Enabled bool `json:"enabled"`
WebhookURL string `json:"webhook_url"`
}
DiscordNotificationConfig holds Discord-specific notification settings
type Feed ¶
type Feed struct {
Id string `gorm:"primaryKey" json:"id"`
URL string `gorm:"index" json:"url"`
Type string `json:"type"`
Title string `json:"title"`
LastFetch time.Time `json:"last_fetch"`
// Scraper map[string]any `gorm:"-" json:"scraper,omitempty"` // In-memory representation
Scraper datatypes.JSONMap `json:"scraper,omitempty"` // In-memory representation
Enabled *bool `gorm:"default:true" json:"enabled"`
GroupId *string `gorm:"default:'default'" json:"group_id"`
Articles []Article `gorm:"foreignKey:FeedId" json:"-"` // One-to-many relationship with articles
}
Feed represents a feed with its metadata
func (*Feed) BeforeCreate ¶
BeforeCreate ensures Id is set and properly converts Params before creating a record
type FeedConfig ¶
type FeedConfig struct {
URL string `json:"url" yaml:"url"`
Title string `json:"title,omitempty" yaml:"title,omitempty"`
Note string `json:"note,omitempty" yaml:"note,omitempty"`
Type string `json:"type" yaml:"type"`
Enabled bool `json:"enabled" yaml:"enabled"`
Scraper map[string]any `json:"scraper,omitempty" yaml:"scraper,omitempty"`
Scraping string `json:"scraping,omitempty" yaml:"scraping,omitempty"` // "dynamic", "full_browser", "none" (use feed content, no fetch), or "" (static)
Selectors *Selectors `json:"selectors,omitempty" yaml:"selectors,omitempty"`
Headers map[string]string `json:"headers,omitempty" yaml:"headers,omitempty"` // custom HTTP headers applied to all requests for this feed
}
FeedConfig represents the configuration for a feed
type FeedDiagnosis ¶ added in v0.2.0
type FeedDiagnosis struct {
URL string `json:"url"`
FinalURL string `json:"final_url"` // after redirects
HTTPStatus int `json:"http_status"` // 0 when the request never completed
ContentType string `json:"content_type"` // raw Content-Type header
ContentLength int `json:"content_length"` // bytes actually read
FeedTypeGuess string `json:"feed_type_guess"` // rss | atom | json-feed | html | empty | unknown
DeclaredCharset string `json:"declared_charset"` // from XML prolog or Content-Type, when present
ItemCount int `json:"item_count"` // parsed items when the feed is valid
ParseError string `json:"parse_error"` // gofeed parse error, empty when valid
InvalidUTF8At *int `json:"invalid_utf8_at"` // byte offset of first invalid UTF-8 byte, nil when valid
Verdict string `json:"verdict"` // one-line human summary
BodySnippet string `json:"body_snippet"` // first printable bytes of the body
HexDump string `json:"hex_dump"` // bytes around InvalidUTF8At, when relevant
RawBodyPath string `json:"raw_body_path"` // on-disk path to the saved raw body
FetchDurationMs int64 `json:"fetch_duration_ms"` // wall time of the fetch
}
FeedDiagnosis is the structured result of inspecting a single feed's raw HTTP response. It captures what actually came back over the wire so the two common failure modes — an unrecognizable body ("Failed to detect feed type") and raw non-UTF-8 bytes ("invalid utf-8 syntax") — can be diagnosed without re-running the server at trace log level.
type FeedGroup ¶
type FeedGroup struct {
Id string `gorm:"primaryKey" json:"id"`
Name string `gorm:"uniqueIndex" json:"name"`
Icon string `json:"icon"`
SortOrder *int `gorm:"default:0" json:"sort_order"`
Feeds []Feed `gorm:"foreignKey:GroupId" json:"-"` // One-to-many relationship with feeds
}
FeedGroup represents a group of feeds
type FeedItem ¶
type FeedItem struct {
Id string
Title string
Content string
Link string
PublishedAt time.Time
Tags []string
Category string
HeroImage string // New field for hero image URL
}
FeedItem represents a generic feed item returned by a scraper
type FeedResult ¶
type FeedResult struct {
Feed Feed
Items []FeedItem
Error error
FetchResult FetchResult
}
FeedResult represents the result of fetching a feed
type FeedsFile ¶
type FeedsFile struct {
DefaultSelectors *Selectors `yaml:"default_selectors,omitempty"`
Feeds []FeedConfig `yaml:"feeds"`
}
FeedsFile is the top-level structure of feeds.yml
type FetchResult ¶
type FetchResult struct {
TotalFetched int
Stored int
Skipped int
Errors []string
StoredArticleIDs []string // IDs of articles successfully stored in this fetch
}
FetchResult holds statistics from a single feed fetch operation
type GenericLLMRequest ¶
type GenericLLMRequest struct {
Model string `json:"model,omitempty"` // Model name
Messages []Message `json:"messages,omitempty"` // For chat-based APIs (OpenAI, Anthropic)
Prompt string `json:"prompt,omitempty"` // For completion-based APIs (Ollama)
Temperature float64 `json:"temperature,omitempty"` // Optional
MaxTokens int `json:"max_tokens,omitempty"` // Optional
}
GenericLLMRequest represents a generic request to an LLM provider
type GitHubPagesNotificationConfig ¶
type GitHubPagesNotificationConfig struct {
Enabled bool `json:"enabled"`
RepoURL string `json:"repo_url"` // e.g. https://github.com/user/user.github.io.git
Branch string `json:"branch"` // default "main"
ConfigurePages bool `json:"configure_pages"` // configure GitHub Pages source to this branch
Token string `json:"token"` // GitHub PAT; prefer env DOWNLINK_GH_PAGES_TOKEN
OutputDir string `json:"output_dir"` // subdirectory inside repo (empty = repo root)
Theme string `json:"theme"` // HTML theme for published pages; empty = "dark"
BaseURL string `json:"base_url"` // public URL, e.g. https://user.github.io
CommitAuthor string `json:"commit_author"` // default "downlink-bot"
CommitEmail string `json:"commit_email"` // default "downlink-bot@users.noreply.github.com"
CloneDir string `json:"clone_dir"` // local working clone; default: os.TempDir()/downlink-ghpages
DiscordWebhookURL string `json:"discord_webhook_url"` // optional: notify this webhook when a page is published
}
GitHubPagesNotificationConfig holds GitHub Pages publishing settings
type GlossaryTerm ¶ added in v0.3.0
GlossaryTerm is a single jargon term and its plain-language definition, produced by the glossary-mode analysis task to help newcomers familiarize themselves with the terminology used in an article.
type HostTriggers ¶
type HostTriggers = smodels.HostTriggers
type LlamaCppModelsResponse ¶
type LlamaCppModelsResponse struct {
Object string `json:"object"`
// OpenAI-compatible data array (preferred)
Data []struct {
Id string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
OwnedBy string `json:"owned_by"`
} `json:"data"`
// llama.cpp native models array (fallback)
Models []struct {
Name string `json:"name"`
Model string `json:"model"`
} `json:"models"`
}
LlamaCppModelsResponse handles the hybrid response format from llama.cpp /models endpoint, which includes both a custom "models" array and an OpenAI-compatible "data" array.
type Message ¶
type Message struct {
Role string `json:"role"` // "system", "user", "assistant"
Content string `json:"content"` // Message content
}
Message represents a message in a chat-based LLM request
type ModelInfo ¶
type ModelInfo struct {
Id string `json:"id"`
Name string `json:"name"`
DisplayName string `json:"display_name,omitempty"`
Description string `json:"description,omitempty"`
ProviderType string `json:"provider_type"`
}
ModelInfo represents generic model information
type ModelsResponse ¶
type ModelsResponse struct {
Models []ModelInfo `json:"models"`
Error string `json:"error,omitempty"`
}
ModelsResponse represents the response structure for GetAvailableModels
type NotificationsConfig ¶
type NotificationsConfig struct {
Discord DiscordNotificationConfig `json:"discord"`
GitHubPages GitHubPagesNotificationConfig `json:"github_pages"`
}
NotificationsConfig holds notification platform configurations
type OllamaModelDetails ¶
type OllamaModelDetails struct {
ParentModel string `json:"parent_model"`
Format string `json:"format"`
Family string `json:"family"`
Families []string `json:"families"`
ParameterSize string `json:"parameter_size"`
QuantizationLevel string `json:"quantization_level"`
}
OllamaModelDetails represents the details of an Ollama model
type OllamaModelsResponse ¶
type OllamaModelsResponse struct {
Models []struct {
Name string `json:"name"`
Model string `json:"model"`
ModifiedAt string `json:"modified_at"`
Size int64 `json:"size"`
Digest string `json:"digest"`
Details OllamaModelDetails `json:"details"`
} `json:"models"`
}
OllamaModelsResponse represents the response from Ollama's models endpoint
type OllamaRequest ¶
type OllamaRequest struct {
Model string `json:"model"`
Prompt string `json:"prompt"`
Stream bool `json:"stream"`
}
OllamaRequest represents the request to the Ollama API
type OllamaResponse ¶
type OllamaResponse struct {
Model string `json:"model"`
Response string `json:"response"`
CreatedAt string `json:"created_at"`
}
OllamaResponse represents the response from the Ollama API
type OpenAIModelsResponse ¶
type OpenAIModelsResponse struct {
Object string `json:"object"`
Data []struct {
Id string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
OwnedBy string `json:"owned_by"`
} `json:"data"`
}
OpenAIModelsResponse represents the response from OpenAI's models endpoint
type OpenAIRequest ¶
type OpenAIRequest struct {
Model string `json:"model"`
Messages []Message `json:"messages"`
Temperature float64 `json:"temperature,omitempty"`
MaxTokens int `json:"max_tokens,omitempty"`
}
OpenAIRequest represents a request to the OpenAI API
type OpenAIResponse ¶
type OpenAIResponse struct {
Id string `json:"id"`
Object string `json:"object"`
Created int64 `json:"created"`
Model string `json:"model"`
Choices []struct {
Index int `json:"index"`
Message Message `json:"message"`
FinishReason string `json:"finish_reason"`
} `json:"choices"`
}
OpenAIResponse represents a response from the OpenAI API
type ProviderConfig ¶
type ProviderConfig struct {
Name string `json:"name"` // User-defined name for this provider configuration (required)
ProviderType string `json:"provider_type"`
ModelName string `json:"model_name"`
Enabled bool `json:"enabled"`
BaseURL string `json:"base_url,omitempty"` // Used for Ollama and other local providers
Temperature *float64 `json:"temperature,omitempty"` // Using pointer type for zero values (GORM best practice)
MaxRetries *int `json:"max_retries,omitempty"` // Using pointer type for zero values (GORM best practice)
TimeoutMinutes *int `json:"timeout_minutes,omitempty"` // Using pointer type for zero values (GORM best practice)
APIKey string `json:"api_key,omitempty"` // Per-provider API key; overrides the global key when set
Credentials []CodexCredential `json:"credentials,omitempty"` // openai-codex OAuth credential pool
}
ProviderConfig represents configuration for a specific LLM provider used for digest generation
type ReferencedReport ¶
type ReferencedReport struct {
Title string `json:"title"`
URL string `json:"url"`
Publisher string `json:"publisher"`
Context string `json:"context"`
Category string `json:"category"`
Primary bool `json:"primary"`
}
ReferencedReport is an explicit third-party report, research item, advisory, whitepaper, or technical analysis linked from an article.
type RelatedArticle ¶
type RelatedArticle struct {
ArticleId string `gorm:"primaryKey;column:article_id" json:"article_id"`
RelatedArticleId string `gorm:"primaryKey;column:related_article_id" json:"related_article_id"`
RelationType string `gorm:"column:relation_type" json:"relation_type"` // e.g., "similar", "continuation", "response"
SimilarityScore float64 `gorm:"column:similarity_score" json:"similarity_score"`
}
RelatedArticle represents a relationship between two articles
func (RelatedArticle) TableName ¶
func (RelatedArticle) TableName() string
TableName specifies the table name for RelatedArticle
type SelectorCandidate ¶ added in v0.2.0
type SelectorCandidate struct {
Selector string `json:"selector"`
Chars int `json:"chars"`
LinkDensity float64 `json:"link_density"`
Snippet string `json:"snippet"`
}
SelectorCandidate is a ranked guess at the CSS selector wrapping an article body, produced by inspecting a scraped page. Mirrors scrapers.SelectorCandidate.
type Selectors ¶
type Selectors struct {
Article string `json:"article,omitempty" yaml:"article,omitempty"` // Selector to find the article content
Cutoff string `json:"cutoff,omitempty" yaml:"cutoff,omitempty"` // Selector to mark where to cutoff the article
Blacklist string `json:"blacklist,omitempty" yaml:"blacklist,omitempty"` // Elements to exclude from the article
}
Selectors defines CSS selectors for content extraction
func GetEffectiveSelectors ¶
GetEffectiveSelectors returns the effective selectors to use for a feed It prioritizes feed-specific selectors, then falls back to config defaults, then to system defaults
type ServerConfig ¶
type ServerConfig struct {
Feeds []FeedConfig `json:"feeds"`
DbPath string `json:"db_path"`
Providers []ProviderConfig `json:"providers"`
Analysis AnalysisConfig `json:"analysis"`
Notifications NotificationsConfig `json:"notifications"`
DefaultSelectors *Selectors `json:"-" yaml:"-"` // Loaded from feeds.yml, not config.json
SolimenAddr string `json:"solimen_addr"`
}
ServerConfig represents application configuration
type Tag ¶
type Tag struct {
Id string `gorm:"primaryKey" json:"id"`
Name string `gorm:"uniqueIndex" json:"name"`
Color string `json:"color"`
UseCount *int `gorm:"default:0" json:"use_count"` // To track popularity
Articles []Article `gorm:"many2many:article_tags;" json:"-"` // Many-to-many relationship with articles
}
Tag represents an article tag
type WorkerPoolConfig ¶
type WorkerPoolConfig struct {
MaxWorkers *int `json:"max_workers,omitempty"` // Maximum number of concurrent workers (default: 3)
}
WorkerPoolConfig contains the configuration for the worker pool