package fa import ( "context" "iter" "github.com/PuerkitoBio/goquery" "git.anthrove.art/public/go-fa-api/internal/urls" ) // Gallery iterates the submissions in a user's main gallery, newest first. // // Each yielded *Submission carries only the fields visible on the listing // page: ID, Title, Author (for favorites), ThumbURL, and Rating. Call // [Client.GetSubmission] with the ID to load the full record. func (c *Client) Gallery(ctx context.Context, name string, opts ListOptions, reqOpts ...Option) iter.Seq2[*Submission, error] { return c.listGallerySection(ctx, name, urls.Gallery, opts, reqOpts) } // Scraps iterates the user's scraps folder. Same yield shape as Gallery. func (c *Client) Scraps(ctx context.Context, name string, opts ListOptions, reqOpts ...Option) iter.Seq2[*Submission, error] { return c.listGallerySection(ctx, name, urls.Scraps, opts, reqOpts) } // Favorites iterates the user's favorited submissions. The yielded // *Submission's Author field reflects the original artist (not the user // whose favorites we are walking). func (c *Client) Favorites(ctx context.Context, name string, opts ListOptions, reqOpts ...Option) iter.Seq2[*Submission, error] { return c.listGallerySection(ctx, name, urls.Favorites, opts, reqOpts) } // listGallerySection is the shared engine for Gallery / Scraps / Favorites. // urlFn picks the section-specific URL builder; the rest of the pagination // machinery is identical across all three sections. func (c *Client) listGallerySection( ctx context.Context, name string, urlFn func(string, int) string, opts ListOptions, reqOpts []Option, ) iter.Seq2[*Submission, error] { return func(yield func(*Submission, error) bool) { page := opts.firstPage() pagesFetched := 0 for { if opts.reachedLimit(pagesFetched) { return } var ( items []*Submission hasNext bool ) err := c.fetch(ctx, urlFn(name, page), func(doc *goquery.Document) error { items, hasNext = parseGalleryPage(doc, c.cfg.jsonListings) return nil }, reqOpts...) if err != nil { yield(nil, err) return } pagesFetched++ if len(items) == 0 { return } for _, s := range items { if !yield(s, nil) { return } } if !hasNext { return } page++ } } }