Documentation
¶
Index ¶
- Variables
- func ArticleFiltersQueryClause(filters *models.ArticleFilters) query.BoolOption
- func BuildItemQueries(user *models.User, view models.View, subscriptions models.Subscriptions) []query.Option
- func ClassifyFeed(ctx context.Context, feed *models.Feed) error
- func DiscoverFeedURL(sourceURL *url.URL, content []byte) (string, error)
- func EditEmailSubscription(ctx context.Context, subscription *models.Subscription, ...) error
- func EditFeedSubscription(ctx context.Context, subscription *models.Subscription, ...) error
- func EditGroupSubscription(ctx context.Context, subscription *models.Subscription, ...) error
- func EditSearchSubscription(ctx context.Context, subscription *models.Subscription, ...) error
- func ElasticsearchToAPIError(err error) error
- func GenerateArticles(ctx context.Context, items models.Items) (models.Articles, error)
- func GetArticleRemoteContent(ctx context.Context, httpClient *resty.Client, itemPageCache cache.ObjectCache, ...) error
- func NewEmailSubscription(ctx context.Context, userID models.UserID, from *mail.Address) (*models.Subscription, error)
- func NewFeedFromZyteResponse(ctx context.Context, resp *zyte.Response) (*models.Feed, error)
- func NewFeedSortCombinations(sort *models.Sort) []estypes.SortCombinations
- func NewFeedSortOptions(sort *models.Sort) []estypes.SortCombinationsVariant
- func NewFeedSubscription(ctx context.Context, feed *models.Feed, ...) (*models.Subscription, error)
- func NewGroupSubscription(ctx context.Context, request *models.GroupSubscriptionRequest) (*models.Subscription, error)
- func NewItemSortCombinations(sort *models.Sort) []estypes.SortCombinations
- func NewItemSortOptions(sort *models.Sort) []estypes.SortCombinationsVariant
- func NewItemsFromZyteArticles(ctx context.Context, feed *models.Feed, articles *zyte.ArticleList) (models.Items, error)
- func NewSearchSubscription(ctx context.Context, request *models.SearchSubscriptionRequest) (*models.Subscription, error)
- type Change
- type ElasticService
- type FeedService
- func (s *FeedService) AddFeed(ctx context.Context, feed *models.Feed) error
- func (s *FeedService) ApplyFeedUpdates(ctx context.Context, itemPageCache cache.ObjectCache, ...) error
- func (s *FeedService) FetchFeed(ctx context.Context, feedURL string, options ...FetchOption) (*models.Feed, error)
- func (s *FeedService) FetchFeedUpdates(ctx context.Context, details *models.Feed) (*models.Feed, models.URL, error)
- func (s *FeedService) FetchFeedUpdatesAsArticles(ctx context.Context, details *models.Feed) (*models.Feed, models.URL, error)
- func (s *FeedService) FindOrCreateFeed(ctx context.Context, feedURL string) (*models.Feed, bool, error)
- func (s *FeedService) GenerateOPML(ctx context.Context, feedIDs ...models.FeedID) ([]byte, error)
- func (s *FeedService) GetAllFeedsExcept(ctx context.Context, ids ...models.FeedID) (models.Feeds, error)
- func (s *FeedService) GetFeed(ctx context.Context, id models.FeedID) (*models.Feed, error)
- func (s *FeedService) GetFeeds(ctx context.Context, ids ...models.FeedID) (models.Feeds, error)
- func (s FeedService) GetFeedsByURLs(ctx context.Context, urls ...string) (models.Feeds, error)
- func (s *FeedService) GetNewFeedsSince(ctx context.Context, ts time.Time) (models.Feeds, error)
- func (s *FeedService) SuggestFeeds(ctx context.Context, request *models.SuggestFeedsRequest) (*models.SuggestFeedsResults, error)
- func (s *FeedService) SuggestGoogleNewsFeeds(ctx context.Context, text string) (*models.SuggestFeedsResults, error)
- func (s *FeedService) SuggestYoutubeFeeds(ctx context.Context, text string) (*models.SuggestFeedsResults, error)
- func (s *FeedService) UpdateFeed(ctx context.Context, feed *models.Feed) error
- func (s *FeedService) UpdateFeedItems(ctx context.Context, itemPageCache cache.ObjectCache, ...) (time.Time, error)
- type FeedSorting
- type FetchOption
- type FetchOptions
- type Home
- type ImportService
- func (i *ImportService) GetAllImports(ctx context.Context, userID models.UserID) ([]*models.ImportStatus, error)
- func (i *ImportService) GetImportStatus(ctx context.Context, jobID string) (*models.ImportStatus, []*models.ImportResult, error)
- func (i *ImportService) GetPendingImports(ctx context.Context) ([]*models.ImportStatus, error)
- func (i *ImportService) ProcessRequests(ctx context.Context, status *models.ImportStatus) error
- func (i *ImportService) StartImport(ctx context.Context, file *models.OPMLFile) (string, error)
- type Index
- type ItemService
- func (s *ItemService) AddItems(ctx context.Context, items models.Items) (map[string]models.Items, error)
- func (s *ItemService) ArchiveArticle(ctx context.Context, article *models.ArticleArchive) error
- func (s *ItemService) CountArticles(ctx context.Context, filters *models.ListFilters, extraQueries ...query.Option) (int64, error)
- func (s *ItemService) CountGeoArticles(ctx context.Context, filters *models.ListFilters) (int64, error)
- func (s *ItemService) CountSearchResults(ctx context.Context, request *models.SearchRequest) (int64, error)
- func (s *ItemService) EnrichItem(ctx context.Context, itemPageCache cache.ObjectCache, feed *models.Feed, ...) error
- func (s *ItemService) FilterArticles(ctx context.Context, filters *models.ListFilters, extraQueries ...query.Option) (models.Articles, models.Subscriptions, models.Pagination, error)
- func (s *ItemService) FilterGeoArticles(ctx context.Context, filters *models.ListFilters) (models.Articles, models.Subscriptions, models.Pagination, error)
- func (s *ItemService) FindSimilarArticles(ctx context.Context, count int, itemIDs ...models.ItemID) (models.Articles, error)
- func (s *ItemService) GetArticles(ctx context.Context, itemIDs ...models.ItemID) (models.Articles, error)
- func (s *ItemService) GetItems(ctx context.Context, ids ...models.ItemID) (models.Items, error)
- func (s *ItemService) GetNextArticle(ctx context.Context, currentID models.ItemID, ...) (*models.Article, error)
- func (s *ItemService) GetTopCategoriesForItems(ctx context.Context, itemsQuery query.Option) (models.CategoryCounts, error)
- func (s *ItemService) GetTopItemCategoriesForSearchResults(ctx context.Context, request *models.SearchRequest) (models.Categories, error)
- func (s *ItemService) GetTopLanguageCountsForItems(ctx context.Context, itemsQuery query.Option) (map[string]int64, error)
- func (s *ItemService) QueryItems(ctx context.Context, query query.Option, count int, sort *models.Sort, ...) (models.Items, string, error)
- func (s *ItemService) RetrieveItems(ctx context.Context, request *models.SearchRequest) (models.Items, models.Pagination, error)
- func (s *ItemService) SuggestItems(ctx context.Context, request *models.SearchRequest) (models.Items, error)
- func (s *ItemService) UnarchiveArticle(ctx context.Context, userID models.UserID, itemID models.ItemID) error
- type ItemSorting
- type SubscriptionService
- func (s *SubscriptionService) AddSubscriptions(ctx context.Context, newSubscriptions ...*models.Subscription) error
- func (s *SubscriptionService) BulkGetSubscriptions(ctx context.Context, ids ...models.SubscriptionID) (models.Subscriptions, error)
- func (s *SubscriptionService) GetAllSubscriptions(ctx context.Context) (models.Subscriptions, error)
- func (s *SubscriptionService) GetLatestArticles(ctx context.Context, view models.View, subscriptions models.Subscriptions)
- func (s *SubscriptionService) GetSubscription(ctx context.Context, id models.SubscriptionID) (*models.Subscription, error)
- func (s *SubscriptionService) GetSubscriptionCategorySuggestions(ctx context.Context, feedIDs []models.FeedID, ...) []models.Category
- func (s *SubscriptionService) GetSubscriptionSuggestions(ctx context.Context, text string, count int, ...) (models.Subscriptions, error)
- func (s *SubscriptionService) Invalidate(userID models.UserID)
- func (s *SubscriptionService) MarkArticles(ctx context.Context, mark models.Mark, subscriptionID models.SubscriptionID, ...) error
- func (s *SubscriptionService) MarkSubscriptions(ctx context.Context, mark models.Mark, ...) error
- func (s *SubscriptionService) RemoveSubscriptions(ctx context.Context, ids ...models.SubscriptionID) error
- func (s *SubscriptionService) UpdateSubscriptionDynamicInfo(ctx context.Context, subscriptions models.Subscriptions) error
- func (s *SubscriptionService) UpdateSubscriptions(ctx context.Context, subscriptions ...*models.Subscription) error
- type SubscriptionSorting
- type UserService
- func (s UserService) AddUser(ctx context.Context, user *models.User) error
- func (s *UserService) DeleteUser(ctx context.Context, user *models.User) error
- func (s *UserService) GetAllUsers(ctx context.Context) ([]*models.User, error)
- func (s *UserService) GetUser(ctx context.Context, id models.UserID) (*models.User, error)
- func (s *UserService) GetUserByCustomerID(ctx context.Context, id string) (*models.User, error)
- func (s *UserService) GetUserByEmail(ctx context.Context, email string) (*models.User, error)
- func (s *UserService) GetUserByExternalID(ctx context.Context, externalID string) (*models.User, error)
- func (s *UserService) GetUserByPurchaseToken(ctx context.Context, token string) (*models.User, error)
- func (s *UserService) GetUserBySubscriptionEmail(ctx context.Context, emails ...string) (*models.User, error)
- func (s *UserService) GetUserBySubscriptionID(ctx context.Context, id string) (*models.User, error)
- func (s *UserService) UpdateUser(ctx context.Context, user *models.User, updates map[string]any) error
- type UserSubscriptions
Constants ¶
This section is empty.
Variables ¶
var ( ErrNoUserInCtx = errors.New("no user in context") ErrNoSubsInCtx = errors.New("no subscriptions in context") )
var LoadElasticService = sync.OnceValues(func() (*ElasticService, error) { appCfg, err := config.LoadAppConfig() if err != nil { return nil, fmt.Errorf("load app config: %w", err) } return &ElasticService{ environment: appCfg.GetAppEnvironment(), }, nil })
var LoadFeedService = sync.OnceValues(func() (*FeedService, error) { svc, err := LoadElasticService() if err != nil { return nil, fmt.Errorf("load elastic service: %w", err) } return &FeedService{ Cache: otter.Must(&otter.Options[models.FeedID, *models.Feed]{ MaximumSize: 30_000, ExpiryCalculator: &feedCacheExpiryCalculator{}, }), store: svc, loader: otter.LoaderFunc[models.FeedID, *models.Feed]( func(ctx context.Context, id models.FeedID) (*models.Feed, error) { index := ctx.Value("feeds_index").(string) feed, err := elastic.GetDoc[models.FeedID, *models.Feed](ctx, index, id) if err != nil { return nil, fmt.Errorf("%w: %w", otter.ErrNotFound, err) } return feed, nil }, ), httpClient: newHTTPClient(), }, nil })
LoadFeedService loads a service that can manipulate feed objects in the backend store.
var LoadItemService = sync.OnceValues(func() (*ItemService, error) { svc, err := LoadElasticService() if err != nil { return nil, fmt.Errorf("load elastic service: %w", err) } return &ItemService{ Cache: otter.Must(&otter.Options[models.ItemID, *models.Item]{ MaximumSize: 10_000, ExpiryCalculator: &itemCacheexpiryCalculator{}, }), store: svc, httpClient: newHTTPClient(), }, nil })
LoadItemService loads a service that can manipulate models.Item objects in the backend store.
var LoadSubscriptionService = sync.OnceValues(func() (*SubscriptionService, error) { svc, err := LoadElasticService() if err != nil { return nil, fmt.Errorf("load elastic service: %w", err) } feedSvc, err := LoadFeedService() if err != nil { return nil, fmt.Errorf("load feed service: %w", err) } return &SubscriptionService{ Cache: otter.Must( &otter.Options[models.UserID, *UserSubscriptions]{ MaximumSize: 100, ExpiryCalculator: otter.ExpiryAccessing[models.UserID, *UserSubscriptions](time.Hour), }, ), store: svc, userLoader: otter.LoaderFunc[models.UserID, *UserSubscriptions]( func( ctx context.Context, userID models.UserID, ) (*UserSubscriptions, error) { userSubscriptionsCache, err := otter.New(&otter.Options[models.SubscriptionID, *models.Subscription]{ InitialCapacity: 3000, MaximumSize: 3000, }) if err != nil { return nil, fmt.Errorf("create subscriptions cache: %w", err) } start := time.Now() // Execute query. var ( subscriptions models.Subscriptions ) subscriptions, err = elastic.SearchAll[*models.Subscription]( ctx, svc.GetIndexRO(SubscriptionsIndex), query.Term("user_id", userID), 3000, ) if err != nil { return nil, ElasticsearchToAPIError(err) } if len(subscriptions) == 0 { return nil, otter.ErrNotFound } feeds, err := feedSvc.GetFeeds(ctx, subscriptions.GetFeedIDs()...) if err != nil { return nil, fmt.Errorf("get feeds for subscriptions: %w", err) } for groupSubscription := range slices.Values(subscriptions.FilterByType(models.SubscriptionTypeGroup)) { groupSubscription.GroupData.Subscriptions = make( []*models.Subscription, 0, len(groupSubscription.GroupData.Metadata), ) for m := range slices.Values(groupSubscription.GroupData.Metadata) { grouped := subscriptions.GetByID(m.SubscriptionID) groupSubscription.GroupData.Subscriptions = append( groupSubscription.GroupData.Subscriptions, grouped, ) } } for subscription := range slices.Values(subscriptions) { subscription.Feed = feeds.FindByID(subscription.GetFeedID()) userSubscriptionsCache.Set(subscription.GetID(), subscription) } slogctx.Debug(ctx, "Created subscriptions cache for user.", slog.Duration("took", time.Since(start))) return &UserSubscriptions{ Cache: userSubscriptionsCache, userID: userID, loader: otter.LoaderFunc[models.SubscriptionID, *models.Subscription]( func(ctx context.Context, id models.SubscriptionID) (*models.Subscription, error) { subscription, err := elastic.GetDoc[models.SubscriptionID, *models.Subscription]( ctx, svc.GetIndexRO(SubscriptionsIndex), id, ) if err != nil && !errors.Is(err, elastic.ErrNotFound) { return nil, fmt.Errorf("get subscriptions: %w", ElasticsearchToAPIError(err)) } if errors.Is(err, elastic.ErrNotFound) { return nil, otter.ErrNotFound } feed, err := feedSvc.GetFeed(ctx, subscription.GetFeedID()) if err != nil { return nil, fmt.Errorf("get feed for subscriptions: %w", err) } subscription.Feed = feed if subscription.Type == models.SubscriptionTypeGroup { grouped, err := elastic.GetDocs[models.SubscriptionID, *models.Subscription]( ctx, svc.GetIndexRO(SubscriptionsIndex), subscription.GroupData.GetGroupedSubscriptionIDs()..., ) if err != nil { return nil, fmt.Errorf("get grouped subscriptions: %w", err) } subscription.GroupData.Subscriptions = grouped } return subscription, nil }), bulkLoader: otter.BulkLoaderFunc[models.SubscriptionID, *models.Subscription]( func( ctx context.Context, ids []models.SubscriptionID, ) (map[models.SubscriptionID]*models.Subscription, error) { var ( subscriptions models.Subscriptions err error ) subscriptions, err = elastic.GetDocs[models.SubscriptionID, *models.Subscription]( ctx, svc.GetIndexRO(SubscriptionsIndex), ids..., ) if err != nil { return nil, fmt.Errorf("get subscriptions: %w", ElasticsearchToAPIError(err)) } feeds, err := feedSvc.GetFeeds(ctx, subscriptions.GetFeedIDs()...) if err != nil { return nil, fmt.Errorf("get feed for subscriptions: %w", err) } results := make(map[models.SubscriptionID]*models.Subscription, len(subscriptions)) for subscription := range slices.Values(subscriptions) { subscription.Feed = feeds.FindByID(subscription.GetFeedID()) if subscription.Type == models.SubscriptionTypeGroup { grouped, err := elastic.GetDocs[models.SubscriptionID, *models.Subscription]( ctx, svc.GetIndexRO(SubscriptionsIndex), subscription.GroupData.GetGroupedSubscriptionIDs()..., ) if err != nil { return nil, fmt.Errorf("get grouped subscriptions: %w", err) } subscription.GroupData.Subscriptions = grouped } results[subscription.GetID()] = subscription } return results, nil }), }, nil }), }, nil })
LoadSubscriptionService loads a service that can manipulate subscription objects in the backend store.
var LoadUserService = sync.OnceValues(func() (*UserService, error) { svc, err := LoadElasticService() if err != nil { return nil, fmt.Errorf("load elastic service: %w", err) } return &UserService{ Cache: otter.Must(&otter.Options[string, models.User]{ MaximumSize: 100, ExpiryCalculator: otter.ExpiryAccessing[string, models.User]( 60 * time.Second, ), }), store: svc, loader: otter.LoaderFunc[string, models.User]( func(ctx context.Context, id string) (models.User, error) { index := ctx.Value("users_index").(string) switch resp, err := elastic.Search[*models.User](ctx, index, elastic.WithQuery[*search.Search]( query.Term("external_user_id", id, query.WithQueryName[*query.TermQuery]("get-user-by-external-id")), ), elastic.WithDocSorting[*search.Search](), elastic.WithTrackHits[*search.Search](false), elastic.WithSize[*search.Search](1), ); { case err != nil: return models.User{}, fmt.Errorf("%w: %w", otter.ErrNotFound, err) case len(resp.Results) == 0: return models.User{}, fmt.Errorf("%w: %w", otter.ErrNotFound, elastic.ErrNotFound) default: return *resp.Results[0], nil } }, ), }, nil })
LoadUserService loads a service that can manipulate user objects in the backend store.
Functions ¶
func ArticleFiltersQueryClause ¶ added in v0.210.3
func ArticleFiltersQueryClause(filters *models.ArticleFilters) query.BoolOption
func BuildItemQueries ¶
func BuildItemQueries( user *models.User, view models.View, subscriptions models.Subscriptions, ) []query.Option
BuildItemQueries generates a slices of queries for the given subscriptions, based on the given filters.
func ClassifyFeed ¶ added in v0.189.0
ClassifyFeed will add appropriate categories to a feed by classifying the item content.
func DiscoverFeedURL ¶ added in v0.190.1
DiscoverFeedURL attempts to find a feed URL within a HTML page.
There are a couple of "canonical" places the feed URL is located. Firstly, as per the RSS spec, look for a link element with rel="alternate" and type="application/rss+xml". Secondly, check for a link element with a URL that ends with feed, rss or atom, which would indicate a feed URL.
func EditEmailSubscription ¶ added in v0.222.0
func EditEmailSubscription( ctx context.Context, subscription *models.Subscription, edits *models.EditEmailSubscriptionRequest, ) error
func EditFeedSubscription ¶ added in v0.222.0
func EditFeedSubscription( ctx context.Context, subscription *models.Subscription, edits *models.FeedSubscriptionRequest, ) error
func EditGroupSubscription ¶ added in v0.222.0
func EditGroupSubscription( ctx context.Context, subscription *models.Subscription, edits *models.GroupSubscriptionRequest, ) error
func EditSearchSubscription ¶ added in v0.222.0
func EditSearchSubscription( ctx context.Context, subscription *models.Subscription, edits *models.SearchSubscriptionRequest, ) error
func ElasticsearchToAPIError ¶ added in v0.132.2
ElasticsearchToAPIError will extract and wrap a types.ElasticsearchError from the given error, in an APIError containing its pertinent information. If the given error does not contain types.ElasticsearchError, the given error is wrapped in a generic APIError is created.
func GenerateArticles ¶ added in v0.128.0
GenerateArticles takes a slice of items and creates articles from them, grabbing the necessary data from the user object.
func GetArticleRemoteContent ¶ added in v0.147.0
func GetArticleRemoteContent( ctx context.Context, httpClient *resty.Client, itemPageCache cache.ObjectCache, article *models.Article, ) error
GetArticleRemoteContent populates the article content with the item source.
func NewEmailSubscription ¶ added in v0.222.0
func NewFeedFromZyteResponse ¶ added in v0.222.0
func NewFeedSortCombinations ¶ added in v0.160.0
func NewFeedSortCombinations(sort *models.Sort) []estypes.SortCombinations
func NewFeedSortOptions ¶ added in v0.160.0
func NewFeedSortOptions(sort *models.Sort) []estypes.SortCombinationsVariant
func NewFeedSubscription ¶ added in v0.222.0
func NewFeedSubscription( ctx context.Context, feed *models.Feed, customisation *models.SubscriptionCustomisation, ) (*models.Subscription, error)
NewFeedSubscription creates a new subscription for a feed with any user customisations given.
func NewGroupSubscription ¶ added in v0.222.0
func NewGroupSubscription(ctx context.Context, request *models.GroupSubscriptionRequest) (*models.Subscription, error)
NewGroupSubscription creates a GroupSubscription. A GroupSubscription is a kind of meta-subscription that aggregates all articles from multiple individual subscriptions into a single custom subscription.
func NewItemSortCombinations ¶ added in v0.132.2
func NewItemSortCombinations(sort *models.Sort) []estypes.SortCombinations
func NewItemSortOptions ¶ added in v0.132.2
func NewItemSortOptions(sort *models.Sort) []estypes.SortCombinationsVariant
func NewItemsFromZyteArticles ¶ added in v0.222.0
func NewSearchSubscription ¶ added in v0.222.0
func NewSearchSubscription( ctx context.Context, request *models.SearchSubscriptionRequest, ) (*models.Subscription, error)
NewSearchSubscription creates a new SearchSubscription. A SearchSubscription collates articles that match a search into a single custom subscription.
Types ¶
type ElasticService ¶ added in v0.235.0
type ElasticService struct {
// contains filtered or unexported fields
}
func (*ElasticService) GetIndexRO ¶ added in v0.235.0
func (s *ElasticService) GetIndexRO(name Index) string
func (*ElasticService) GetIndexRW ¶ added in v0.235.0
func (s *ElasticService) GetIndexRW(name Index) string
type FeedService ¶ added in v0.235.0
type FeedService struct {
*otter.Cache[models.FeedID, *models.Feed]
// contains filtered or unexported fields
}
FeedService holds a cache and backend connection for handling models.Feed objects.
func (*FeedService) AddFeed ¶ added in v0.235.0
AddFeed adds a new feed to Elasticsearch and the cache.
func (*FeedService) ApplyFeedUpdates ¶ added in v0.235.0
func (s *FeedService) ApplyFeedUpdates(ctx context.Context, itemPageCache cache.ObjectCache, oldData, newData *models.Feed) error
ApplyFeedUpdates takes an existing feed and new feed data, compares the two, updates any fields as appropriate and writes the updated feed back to the database. It will add/update both any new/updated items and any updates to the feed metadata.
func (*FeedService) FetchFeed ¶ added in v0.239.1
func (s *FeedService) FetchFeed( ctx context.Context, feedURL string, options ...FetchOption, ) (*models.Feed, error)
FetchFeed retrieves the feed found at the given URL.
func (*FeedService) FetchFeedUpdates ¶ added in v0.239.1
func (s *FeedService) FetchFeedUpdates( ctx context.Context, details *models.Feed, ) (*models.Feed, models.URL, error)
FetchFeedUpdates fetches an updated version of the feed, including items. It returns the updated feed, and the source URL used to fetch the updates (for disambiguation of feeds with multiple source URLs). A non-nil error is returned where there is a critical error fetching the feed details.
func (*FeedService) FetchFeedUpdatesAsArticles ¶ added in v0.239.1
func (s *FeedService) FetchFeedUpdatesAsArticles( ctx context.Context, details *models.Feed, ) (*models.Feed, models.URL, error)
FetchFeedUpdatesAsArticles fetches an updated version of the feed, using Zyte to generate a feed from the source website articles list. It returns the updated feed, and the source URL used to fetch the updates (for disambiguation of feeds with multiple source URLs). A non-nil error is returned where there is a critical error fetching the feed details.
func (*FeedService) FindOrCreateFeed ¶ added in v0.235.0
func (s *FeedService) FindOrCreateFeed( ctx context.Context, feedURL string, ) (*models.Feed, bool, error)
FindOrCreateFeed will either generate a new feed or return the existing feed for the given URL. If the feed is new, the boolean return value will be true.
func (*FeedService) GenerateOPML ¶ added in v0.235.0
GenerateOPML generates an OPML file of the feeds listed by the given IDs.
func (*FeedService) GetAllFeedsExcept ¶ added in v0.235.0
func (s *FeedService) GetAllFeedsExcept(ctx context.Context, ids ...models.FeedID) (models.Feeds, error)
GetAllFeedsExcept retrieves a models.Feeds slice containing all feeds except those with the given models.FeedID.
func (*FeedService) GetFeeds ¶ added in v0.235.0
GetFeeds retrieves the Feeds matching the given FeedIDs. It will fetch any cached versions before fetching from Elasticsearch (and then caching those).
func (FeedService) GetFeedsByURLs ¶ added in v0.237.0
GetFeedByURLs retrieves a models.Feeds slice containing all feeds that have a source matching one of the given URLs.
func (*FeedService) GetNewFeedsSince ¶ added in v0.235.0
GetNewFeedsSince retrieves a models.Feeds slice containing all feeds created since the given timestamp.
func (*FeedService) SuggestFeeds ¶ added in v0.235.0
func (s *FeedService) SuggestFeeds( ctx context.Context, request *models.SuggestFeedsRequest, ) (*models.SuggestFeedsResults, error)
SuggestFeeds returns a feeds and their latest articles that match the given text. It will search first for existing feeds in Elasticsearch. If the given text is a URL, it will fallback to searching the website for a feed.
func (*FeedService) SuggestGoogleNewsFeeds ¶ added in v0.235.0
func (s *FeedService) SuggestGoogleNewsFeeds( ctx context.Context, text string, ) (*models.SuggestFeedsResults, error)
SuggestGoogleNewsFeeds will return a google news RSS feed for the given search query.
func (*FeedService) SuggestYoutubeFeeds ¶ added in v0.235.0
func (s *FeedService) SuggestYoutubeFeeds(ctx context.Context, text string) (*models.SuggestFeedsResults, error)
SuggestYoutubeFeeds will return a list of youtube feeds that match the given text.
func (*FeedService) UpdateFeed ¶ added in v0.235.0
UpdateFeed applies the given updates to a Feed. Any cached version of the feed is invalidated.
func (*FeedService) UpdateFeedItems ¶ added in v0.235.0
func (s *FeedService) UpdateFeedItems( ctx context.Context, itemPageCache cache.ObjectCache, oldData, newData *models.Feed, ) (time.Time, error)
UpdateFeedItems determines if there are new items in the feed and then adds them to the database, performing item enrichment as needed. It returns a timestamp indicating a new lastFetched value for the feed, based off the latest new item's timestamp.
type FeedSorting ¶ added in v0.160.0
type FeedSorting struct {
Updated string `json:"updated"`
Published string `json:"published"`
FeedID string `json:"feed_id"`
}
FeedSorting contains the sort options for sorting item search results.
func (*FeedSorting) SortCombinationsCaster ¶ added in v0.160.0
func (s *FeedSorting) SortCombinationsCaster() *estypes.SortCombinations
SortCombinationsCaster is required to allow FeedSorting to be used as Elasticsearch sort values.
type FetchOption ¶ added in v0.148.1
type FetchOption func(*FetchOptions)
FetchOption is a functional option that controls some aspect of how a feed will be fetched.
func FetchWithFeedID ¶ added in v0.147.0
func FetchWithFeedID(id models.FeedID) FetchOption
FetchWithFeedID assigns the given FeedID to the feed object.
func FetchWithProxy ¶ added in v0.147.0
func FetchWithProxy(value bool) FetchOption
FetchWithProxy option will ensure the fetch feed request is proxied.
type FetchOptions ¶ added in v0.147.0
FetchOptions defines options that manipulate how a feed will be fetched from a remote URL.
type Home ¶ added in v0.235.0
type Home struct{}
func (*Home) AggregateSubscriptions ¶ added in v0.235.0
func (s *Home) AggregateSubscriptions( ctx context.Context, user *models.User, subscriptions models.Subscriptions, ) (models.CategoryCounts, models.CategoryCounts, models.Articles, error)
type ImportService ¶ added in v0.237.0
type ImportService struct {
// contains filtered or unexported fields
}
func NewImportService ¶ added in v0.237.0
func NewImportService() (*ImportService, error)
func (*ImportService) GetAllImports ¶ added in v0.238.0
func (i *ImportService) GetAllImports(ctx context.Context, userID models.UserID) ([]*models.ImportStatus, error)
func (*ImportService) GetImportStatus ¶ added in v0.237.0
func (i *ImportService) GetImportStatus( ctx context.Context, jobID string, ) (*models.ImportStatus, []*models.ImportResult, error)
func (*ImportService) GetPendingImports ¶ added in v0.237.0
func (i *ImportService) GetPendingImports(ctx context.Context) ([]*models.ImportStatus, error)
GetPendingImports retrieves any imports in "pending" status (i.e., ready to be started).
func (*ImportService) ProcessRequests ¶ added in v0.237.0
func (i *ImportService) ProcessRequests( ctx context.Context, status *models.ImportStatus, ) error
bulkImportFeeds handles processing any number of NewFeedSubscriptionRequest requests.
func (*ImportService) StartImport ¶ added in v0.237.0
StartImport generates a models.ImportStatus with a slice of models.ImportRequest for all feeds found in the given OPML file. An import job run by the scheduler will find the status and process it.
type ItemService ¶ added in v0.235.0
type ItemService struct {
*otter.Cache[models.ItemID, *models.Item]
// contains filtered or unexported fields
}
ItemService holds a cache and backend connection for handling models.Item objects.
func (*ItemService) AddItems ¶ added in v0.235.0
func (s *ItemService) AddItems(ctx context.Context, items models.Items) (map[string]models.Items, error)
AddItems will add the given models.Item to the database. It returns a map divided into "updated" and "new" items, to indicate items that existed and were updated vs. items that were added as new.
func (*ItemService) ArchiveArticle ¶ added in v0.235.0
func (s *ItemService) ArchiveArticle(ctx context.Context, article *models.ArticleArchive) error
archiveArticle will index the given article content to the article archive for permanent storage.
func (*ItemService) CountArticles ¶ added in v0.241.3
func (s *ItemService) CountArticles( ctx context.Context, filters *models.ListFilters, extraQueries ...query.Option, ) (int64, error)
CountArticles returns a count of items that match the given models.ListFilters. An additional array of query.Option can be passed to further filter items matched.
func (*ItemService) CountGeoArticles ¶ added in v0.241.3
func (s *ItemService) CountGeoArticles( ctx context.Context, filters *models.ListFilters, ) (int64, error)
CountGeoArticles executes CountArticles with an additional filter clause to only match articles with geo data.
func (*ItemService) CountSearchResults ¶ added in v0.235.0
func (s *ItemService) CountSearchResults(ctx context.Context, request *models.SearchRequest) (int64, error)
CountSearchResults will return an approximate count of the number of items that would match the given *models.SearchRequest, published within the last 5 minutes.
func (*ItemService) EnrichItem ¶ added in v0.239.1
func (s *ItemService) EnrichItem( ctx context.Context, itemPageCache cache.ObjectCache, feed *models.Feed, item *models.Item, ) error
EnrichItem checks the data of the given models.Item. If it is missing certain values, it tries to "enrich" the item to fill missing data from the item source.
func (*ItemService) FilterArticles ¶ added in v0.235.0
func (s *ItemService) FilterArticles( ctx context.Context, filters *models.ListFilters, extraQueries ...query.Option, ) (models.Articles, models.Subscriptions, models.Pagination, error)
FilterArticles returns a models.Articles slice (and a models.Subscriptions slice) of articles that match the given models.ListFilters. An additional array of query.Option can be passed to further filter items matched.
func (*ItemService) FilterGeoArticles ¶ added in v0.241.3
func (s *ItemService) FilterGeoArticles( ctx context.Context, filters *models.ListFilters, ) (models.Articles, models.Subscriptions, models.Pagination, error)
FilterGeoArticles executes FilterArticles with an additional filter clause to only match articles with geo data.
func (*ItemService) FindSimilarArticles ¶ added in v0.235.0
func (s *ItemService) FindSimilarArticles( ctx context.Context, count int, itemIDs ...models.ItemID, ) (models.Articles, error)
FindSimilarArticles performs a "more like this" search to find other Articles that are similar to the Items with the given IDs.
func (*ItemService) GetArticles ¶ added in v0.235.0
func (s *ItemService) GetArticles( ctx context.Context, itemIDs ...models.ItemID, ) (models.Articles, error)
GetArticles generates Article objects from the Items with the given IDs.
func (*ItemService) GetItems ¶ added in v0.235.0
GetItems returns a models.Items slice containing the items matching the given models.ItemID.
func (*ItemService) GetNextArticle ¶ added in v0.235.0
func (s *ItemService) GetNextArticle( ctx context.Context, currentID models.ItemID, subscriptionID models.SubscriptionID, view models.View, direction string, ts time.Time, ) (*models.Article, error)
GetNextArticle returns the "next" article from the given article, based on the given article timestamp. The direction defines what the next article will be (previous or next). If a subscription is given, it will filter to that subscription only. Otherwise, the results are also filtered to the given view.
func (*ItemService) GetTopCategoriesForItems ¶ added in v0.235.0
func (s *ItemService) GetTopCategoriesForItems( ctx context.Context, itemsQuery query.Option, ) (models.CategoryCounts, error)
func (*ItemService) GetTopItemCategoriesForSearchResults ¶ added in v0.235.0
func (s *ItemService) GetTopItemCategoriesForSearchResults( ctx context.Context, request *models.SearchRequest, ) (models.Categories, error)
GetTopItemCategoriesForSearchResults returns a models.Categories slice containing the top categories from items that match the given *models.SearchRequest.
func (*ItemService) GetTopLanguageCountsForItems ¶ added in v0.239.0
func (*ItemService) QueryItems ¶ added in v0.235.0
func (s *ItemService) QueryItems( ctx context.Context, query query.Option, count int, sort *models.Sort, pagination *string, ) (models.Items, string, error)
SearchItems will search the items index for items matching the given query. Count, sort and pagination values are optional.
func (*ItemService) RetrieveItems ¶ added in v0.235.0
func (s *ItemService) RetrieveItems( ctx context.Context, request *models.SearchRequest, ) (models.Items, models.Pagination, error)
RetrieveItems will retrieve a models.Items slice of items matching the given *models.SearchRequest. The request supports pagination and will return the next set of results as appropriate.
func (*ItemService) SuggestItems ¶ added in v0.235.0
func (s *ItemService) SuggestItems( ctx context.Context, request *models.SearchRequest, ) (models.Items, error)
func (*ItemService) UnarchiveArticle ¶ added in v0.235.0
func (s *ItemService) UnarchiveArticle( ctx context.Context, userID models.UserID, itemID models.ItemID, ) error
unarchiveArticle will delete an article from the archive.
type ItemSorting ¶ added in v0.132.2
type ItemSorting struct {
Published string `json:"published"`
Updated string `json:"updated"`
ItemID string `json:"item_id"`
}
ItemSorting contains the sort options for sorting item search results.
func (*ItemSorting) SortCombinationsCaster ¶ added in v0.132.2
func (s *ItemSorting) SortCombinationsCaster() *estypes.SortCombinations
SortCombinationsCaster is required to allow ItemSorting to be used as Elasticsearch sort values.
type SubscriptionService ¶ added in v0.235.0
type SubscriptionService struct {
*otter.Cache[models.UserID, *UserSubscriptions]
// contains filtered or unexported fields
}
SubscriptionService holds a cache and backend connection for handling models.Subscription objects.
func (*SubscriptionService) AddSubscriptions ¶ added in v0.237.0
func (s *SubscriptionService) AddSubscriptions( ctx context.Context, newSubscriptions ...*models.Subscription, ) error
AddSubscriptions adds the given subscriptions to a user.
func (*SubscriptionService) BulkGetSubscriptions ¶ added in v0.235.0
func (s *SubscriptionService) BulkGetSubscriptions( ctx context.Context, ids ...models.SubscriptionID, ) (models.Subscriptions, error)
BulkGetSubscriptions returns a models.Subscriptions slice of subscriptions that match the given models.SubscriptionID.
func (*SubscriptionService) GetAllSubscriptions ¶ added in v0.235.0
func (s *SubscriptionService) GetAllSubscriptions( ctx context.Context, ) (models.Subscriptions, error)
GetAllSubscriptions returns a models.Subscriptions slice of all subscriptions for a user.
func (*SubscriptionService) GetLatestArticles ¶ added in v0.235.0
func (s *SubscriptionService) GetLatestArticles( ctx context.Context, view models.View, subscriptions models.Subscriptions, )
GetLatestArticles will fetch and add the latest articles to the given subscriptions.
func (*SubscriptionService) GetSubscription ¶ added in v0.235.0
func (s *SubscriptionService) GetSubscription( ctx context.Context, id models.SubscriptionID, ) (*models.Subscription, error)
GetSubscription returns a *models.Subscription that matches the given models.SubscriptionID for the given user.
func (*SubscriptionService) GetSubscriptionCategorySuggestions ¶ added in v0.235.0
func (*SubscriptionService) GetSubscriptionSuggestions ¶ added in v0.235.0
func (s *SubscriptionService) GetSubscriptionSuggestions( ctx context.Context, text string, count int, ignoredSubscriptions []models.SubscriptionID, ) (models.Subscriptions, error)
GetSubscriptionSuggestions returns subscriptions that match the given text. A set of ids can be optionally passed to ignore those subscriptions.
func (*SubscriptionService) Invalidate ¶ added in v0.237.0
func (s *SubscriptionService) Invalidate(userID models.UserID)
Invalidate will invalidate the cache for the given user. Can be used to force fetching subscriptions from the backend.
func (*SubscriptionService) MarkArticles ¶ added in v0.235.0
func (s *SubscriptionService) MarkArticles( ctx context.Context, mark models.Mark, subscriptionID models.SubscriptionID, itemIDs ...models.ItemID, ) error
func (*SubscriptionService) MarkSubscriptions ¶ added in v0.235.0
func (s *SubscriptionService) MarkSubscriptions( ctx context.Context, mark models.Mark, subscriptionIDs ...models.SubscriptionID, ) error
MarkSubscriptions will mark as appropriate all the given subscriptions. Marking a subscription includes updating the subscription data in the user object and clearing any individual item states for a subscription.
func (*SubscriptionService) RemoveSubscriptions ¶ added in v0.235.0
func (s *SubscriptionService) RemoveSubscriptions( ctx context.Context, ids ...models.SubscriptionID, ) error
RemoveSubscriptions removes subscriptions with the given models.SubscriptionID from a user.
func (*SubscriptionService) UpdateSubscriptionDynamicInfo ¶ added in v0.235.0
func (s *SubscriptionService) UpdateSubscriptionDynamicInfo( ctx context.Context, subscriptions models.Subscriptions, ) error
UpdateSubscriptionDynamicInfo adds dynamically generated information (e.g., unread count, stats, etc.) of the subscriptions in the models.Subscriptions slice. At the least, all subscriptions will have an unread count and last updated info generated. Other stats will also be generated if the user has set the display option ShowSubscriptionStats in their account settings.
func (*SubscriptionService) UpdateSubscriptions ¶ added in v0.235.0
func (s *SubscriptionService) UpdateSubscriptions( ctx context.Context, subscriptions ...*models.Subscription, ) error
UpdateSubscriptions will bulk update each given *models.Subscription.
type SubscriptionSorting ¶ added in v0.128.0
type SubscriptionSorting struct {
MarkedReadAt string `json:"marked_read_at"`
SubscriptionID string `json:"subscription_id"`
}
SubscriptionSorting contains the sort options for sorting subscription results.
func (*SubscriptionSorting) SortCombinationsCaster ¶ added in v0.128.0
func (s *SubscriptionSorting) SortCombinationsCaster() *estypes.SortCombinations
SortCombinationsCaster is required to allow FeedSorting to be used as Elasticsearch sort values.
type UserService ¶ added in v0.235.0
type UserService struct {
*otter.Cache[string, models.User]
// contains filtered or unexported fields
}
UserService holds a cache and backend connection for handling models.User objects.
func (UserService) AddUser ¶ added in v0.235.0
AddUser stores and caches the given *models.User in the backend.
func (*UserService) DeleteUser ¶ added in v0.235.0
DeleteUser deletes the user and the user's subscription objects from Elasticsearch.
func (*UserService) GetAllUsers ¶ added in v0.235.0
GetUser retrieves the user doc with the given id.
func (*UserService) GetUserByCustomerID ¶ added in v0.235.0
GetUserByCustomerID retrieves the user associated with the given customer ID. It handles finding and adding customer details to an existing user for a new customer.
func (*UserService) GetUserByEmail ¶ added in v0.235.0
GetUserByEmail will retrieve a user by their email.
func (*UserService) GetUserByExternalID ¶ added in v0.235.0
func (s *UserService) GetUserByExternalID(ctx context.Context, externalID string) (*models.User, error)
GetUserByExternalID will search for and return a user that matches the given external ID, if exists.
func (*UserService) GetUserByPurchaseToken ¶ added in v0.235.0
func (s *UserService) GetUserByPurchaseToken(ctx context.Context, token string) (*models.User, error)
getUserByPurchaseToken retrieves the user associated with the given purchase token.
func (*UserService) GetUserBySubscriptionEmail ¶ added in v0.235.0
func (s *UserService) GetUserBySubscriptionEmail(ctx context.Context, emails ...string) (*models.User, error)
GetUserBySubscriptionEmail will retrieve a user from their Foragd newsletter subscription email.
func (*UserService) GetUserBySubscriptionID ¶ added in v0.235.0
GetUserBySubscriptionID will retrieve a user from their payment subscription ID.
func (*UserService) UpdateUser ¶ added in v0.235.0
func (s *UserService) UpdateUser(ctx context.Context, user *models.User, updates map[string]any) error
UpdateUser will apply the given updates to the user.
type UserSubscriptions ¶ added in v0.235.0
type UserSubscriptions struct {
*otter.Cache[models.SubscriptionID, *models.Subscription]
// contains filtered or unexported fields
}