Documentation
¶
Index ¶
- Constants
- func IsSystemFeed(url string) bool
- type Article
- type ArticleFilter
- type DB
- func (d *DB) BulkMarkRead(ids []int64) error
- func (d *DB) BulkMarkUnread(ids []int64) error
- func (d *DB) BulkSetBookmarked(ids []int64, bookmark bool) (int, error)
- func (d *DB) BulkSetStarred(ids []int64, starred bool) error
- func (d *DB) CacheArticle(id int64, body string) error
- func (d *DB) Close() error
- func (d *DB) CreateFolder(name string) error
- func (d *DB) DeleteArticle(id int64) error
- func (d *DB) DeleteCategory(name string) error
- func (d *DB) DeleteFeed(id int64) error
- func (d *DB) DeleteFolder(name string) error
- func (d *DB) DeleteSmartFolder(id int64) error
- func (d *DB) GetAIEndpoint() (string, error)
- func (d *DB) GetAIKey() (string, error)
- func (d *DB) GetAIModel() (string, error)
- func (d *DB) GetAIProvider() (string, error)
- func (d *DB) GetAfterSyncCommands() ([]string, error)
- func (d *DB) GetFeedByURL(url string) (*Feed, error)
- func (d *DB) GetLanguage() (string, error)
- func (d *DB) GetLibraryFeedID() (int64, error)
- func (d *DB) GetReadRetentionDays() (int, error)
- func (d *DB) GetRefreshInterval() (int, error)
- func (d *DB) GetSetting(key string) (string, error)
- func (d *DB) GetShowImages() (bool, error)
- func (d *DB) GetShowPreview() (bool, error)
- func (d *DB) GetSortField() (string, error)
- func (d *DB) GetSortReverse() (bool, error)
- func (d *DB) GetTheme() (string, error)
- func (d *DB) InsertSmartFolder(name, query string) (SmartFolder, error)
- func (d *DB) LibraryUnreadCount() (int, error)
- func (d *DB) ListAllArticles(limit int) ([]Article, error)
- func (d *DB) ListArticles(feedID int64, limit int) ([]Article, error)
- func (d *DB) ListArticlesFiltered(feedID int64, filter ArticleFilter, limit int) ([]Article, error)
- func (d *DB) ListFeeds() ([]Feed, error)
- func (d *DB) ListFolders() ([]string, error)
- func (d *DB) ListSmartFolders() ([]SmartFolder, error)
- func (d *DB) MarkFeedRead(feedID int64) (int, error)
- func (d *DB) MarkRead(articleID int64) error
- func (d *DB) MarkUnread(articleID int64) error
- func (d *DB) RenameCategory(oldName, newName string) error
- func (d *DB) RenameFeed(id int64, name string) error
- func (d *DB) RenameFolder(oldName, newName string) error
- func (d *DB) SaveLibraryURL(libraryFeedID int64, url, placeholderTitle string) (int64, bool, error)
- func (d *DB) SearchArticles(limit int) ([]SearchItem, error)
- func (d *DB) SetAIEndpoint(v string) error
- func (d *DB) SetAIKey(v string) error
- func (d *DB) SetAIModel(v string) error
- func (d *DB) SetAIProvider(v string) error
- func (d *DB) SetAfterSyncCommands(cmds []string) error
- func (d *DB) SetFeedCategory(id int64, category string) error
- func (d *DB) SetLanguage(lang string) error
- func (d *DB) SetReadRetentionDays(days int) error
- func (d *DB) SetRefreshInterval(minutes int) error
- func (d *DB) SetSetting(key, value string) error
- func (d *DB) SetShowImages(v bool) error
- func (d *DB) SetShowPreview(v bool) error
- func (d *DB) SetSortField(v string) error
- func (d *DB) SetSortReverse(v bool) error
- func (d *DB) SetTheme(name string) error
- func (d *DB) ToggleBookmark(articleID int64) (bool, error)
- func (d *DB) ToggleStar(articleID int64) (bool, error)
- func (d *DB) TrimArticles(feedID int64, max int, fetchCutoff, readCutoff time.Time) error
- func (d *DB) UpdateLibraryFetched(id int64, title, body string) error
- func (d *DB) UpdateSmartFolder(id int64, name, query string) error
- func (d *DB) UpsertArticle(a Article) (bool, error)
- func (d *DB) UpsertFeed(name, url, category string) (Feed, error)
- type Feed
- type SearchItem
- type SmartFolder
Constants ¶
const ( LibraryFeedURL = "internal://library" LibraryFeedName = "Library" )
LibraryFeedURL is the sentinel URL of the system feed that owns articles saved by the user via the Library modal (hotkey B). Excluded from user-facing lists, sync, and OPML.
Variables ¶
This section is empty.
Functions ¶
func IsSystemFeed ¶ added in v0.7.0
IsSystemFeed reports whether a feed is internal (e.g. Library) and should be hidden from sync, OPML export, and the Settings > Feeds list.
Types ¶
type Article ¶
type Article struct {
ID int64
FeedID int64
FeedName string // transient: populated only by cross-feed loaders
Title string
URL string
Description string
Content string
PublishedAt time.Time
ReadAt *time.Time
StarredAt *time.Time
BookmarkedAt *time.Time
CachedAt *time.Time
CachedBody string
CreatedAt time.Time
}
type ArticleFilter ¶
type ArticleFilter int
ArticleFilter narrows a feed's article list. Kept as a DB-level enum so callers don't pass opaque booleans or magic strings.
const ( FilterAll ArticleFilter = iota FilterUnread FilterStarred )
type DB ¶
type DB struct {
// contains filtered or unexported fields
}
func (*DB) BulkMarkRead ¶
BulkMarkRead marks many articles read in one UPDATE. No-op on empty input. Idempotent for already-read rows.
func (*DB) BulkMarkUnread ¶
BulkMarkUnread clears read_at on many articles in one UPDATE.
func (*DB) BulkSetBookmarked ¶
BulkSetBookmarked sets bookmarked_at to now() or NULL on many articles.
func (*DB) BulkSetStarred ¶
BulkSetStarred sets starred_at to now() or NULL on many articles.
func (*DB) CreateFolder ¶ added in v0.11.0
CreateFolder creates an empty regular folder. The folder becomes visible immediately and can later receive feeds via SetFeedCategory.
func (*DB) DeleteArticle ¶ added in v0.7.0
DeleteArticle removes a single article by id. Used by the Library pane to discard saved URLs the user no longer wants — TrimArticles skips the system feed, so without this the table grows forever.
func (*DB) DeleteCategory ¶
DeleteCategory empties the category of every feed that currently has it, moving them into the "Other" bucket. Thin alias around RenameCategory(name, "") that makes the caller's intent explicit.
func (*DB) DeleteFeed ¶
func (*DB) DeleteFolder ¶ added in v0.11.0
DeleteFolder removes the explicit folder and moves assigned feeds to Other.
func (*DB) DeleteSmartFolder ¶
DeleteSmartFolder removes a folder by id. No-op if the id does not exist so callers don't have to pre-check.
func (*DB) GetAIEndpoint ¶
func (*DB) GetAIModel ¶
func (*DB) GetAIProvider ¶
func (*DB) GetAfterSyncCommands ¶
func (*DB) GetLanguage ¶
func (*DB) GetLibraryFeedID ¶ added in v0.7.0
GetLibraryFeedID returns the ID of the system Library feed. Migration 007 seeds this row, so a missing row would only happen if a user deleted it manually — re-insert in that case.
func (*DB) GetReadRetentionDays ¶ added in v0.8.0
GetReadRetentionDays returns how many days read articles are kept by TrimArticles before age-based deletion. 0 means keep indefinitely (by age; max_articles_per_feed still caps the per-feed count). When the key is unset, returns defaultReadRetentionDays without writing it — we don't want a silent auto-write to obscure "never configured" from "configured to 90".
func (*DB) GetRefreshInterval ¶
func (*DB) GetShowImages ¶
func (*DB) GetShowPreview ¶
GetShowPreview returns whether the inline article preview popup is enabled. Defaults to true when the setting has never been written — the feature is on-by-default so first-time users see it without hunting through settings.
func (*DB) GetSortField ¶
func (*DB) GetSortReverse ¶
func (*DB) InsertSmartFolder ¶
func (d *DB) InsertSmartFolder(name, query string) (SmartFolder, error)
InsertSmartFolder appends a new folder at the end of the list. Position is computed from the current max so new folders land after existing ones.
func (*DB) LibraryUnreadCount ¶ added in v0.7.0
LibraryUnreadCount returns the number of unread saved URLs in the Library feed. Cheap enough to call on every feed-list refresh.
func (*DB) ListAllArticles ¶
ListAllArticles returns articles across all feeds (no feed_id filter), joined with the feed name. Used by smart folders — callers then apply in-memory query filtering on the result set.
func (*DB) ListArticlesFiltered ¶
ListArticlesFiltered returns articles for a feed, narrowed by filter.
func (*DB) ListFolders ¶ added in v0.11.0
ListFolders returns explicit regular folders plus any non-empty feed categories that may have been created by older versions or config sync.
func (*DB) ListSmartFolders ¶
func (d *DB) ListSmartFolders() ([]SmartFolder, error)
ListSmartFolders returns all smart folders ordered by position then id so the UI draws them in a stable, user-controlled sequence.
func (*DB) MarkFeedRead ¶
MarkFeedRead marks every unread article in a feed as read in a single UPDATE and returns the affected row count.
func (*DB) MarkUnread ¶
MarkUnread clears the read state of a single article. Idempotent.
func (*DB) RenameCategory ¶
RenameCategory renames one category to another across all feeds. The new name may be empty, which moves matching feeds into the "Other" bucket. No-op when no feeds match.
func (*DB) RenameFolder ¶ added in v0.11.0
RenameFolder renames the explicit folder row and all feeds assigned to the same category. Empty newName removes the explicit folder and moves assigned feeds to Other.
func (*DB) SaveLibraryURL ¶ added in v0.7.0
SaveLibraryURL inserts a saved URL into the Library feed (or updates the placeholder title on duplicate, preserving read/star/bookmark state). Returns the article ID and whether it was newly inserted. Used by the Add-URL modal: caller passes a fast placeholder title (e.g. host) and updates it later via UpdateLibraryFetched once the background readability fetch returns the real <title>.
func (*DB) SearchArticles ¶
func (d *DB) SearchArticles(limit int) ([]SearchItem, error)
func (*DB) SetAIEndpoint ¶
func (*DB) SetAIModel ¶
func (*DB) SetAIProvider ¶
func (*DB) SetAfterSyncCommands ¶
func (*DB) SetFeedCategory ¶
SetFeedCategory moves a feed into (or out of) a category. Empty string means "uncategorized". Used by :categorymove command.
func (*DB) SetLanguage ¶
func (*DB) SetReadRetentionDays ¶ added in v0.8.0
SetReadRetentionDays persists the retention window (days). Passing 0 disables age-based deletion.
func (*DB) SetRefreshInterval ¶
func (*DB) SetSetting ¶
func (*DB) SetShowImages ¶
func (*DB) SetShowPreview ¶
func (*DB) SetSortField ¶
func (*DB) SetSortReverse ¶
func (*DB) ToggleBookmark ¶
ToggleBookmark flips the bookmarked (read-later) state of an article.
func (*DB) ToggleStar ¶
ToggleStar flips the starred state of an article: nil ↔ now(). Returns whether the article is now starred.
func (*DB) TrimArticles ¶
TrimArticles prunes old read articles in a feed once its total count exceeds max. An article is eligible for deletion only when ALL of:
- read_at IS NOT NULL (unread is always kept)
- starred_at IS NULL (star is an explicit user "save")
- bookmarked_at IS NULL (read-later is an explicit user "save")
- read_at < readCutoff (recently-read articles get a grace window so a stray `x` keystroke doesn't immediately destroy the row)
- last_fetched_at IS NULL OR last_fetched_at < fetchCutoff (anything still in the current RSS response is protected — otherwise marking read right before a refresh would delete it and the next fetch would re-insert it as unread)
Passing a zero time.Time as readCutoff is the "retention=0 / keep everything" signal: the call returns without deleting. This matches user intent ("I want unlimited history") — the per-feed `max` cap would otherwise silently trim older read rows even when the user explicitly opted out of age-based trimming.
func (*DB) UpdateLibraryFetched ¶ added in v0.7.0
UpdateLibraryFetched stores the result of an async readability fetch: the extracted page title (if non-empty) replaces the placeholder, and the Markdown body is cached so the reader can show it immediately on open. Title is only overwritten when extraction succeeded — empty titles leave the placeholder intact.
func (*DB) UpdateSmartFolder ¶
UpdateSmartFolder overwrites the name and query of an existing folder. Position is preserved so the user's ordering survives edits.
func (*DB) UpsertArticle ¶
UpsertArticle inserts or updates an article and returns whether the row was newly inserted. The pre-check is racy under concurrent writers to the same (feed_id, url): the upsert itself is atomic, so rows stay consistent, but the inserted flag may be off — fetcher loops are per-feed serial so this is dormant in practice.