Files
go-fa-api/journal.go
2026-05-26 20:21:55 +02:00

81 lines
1.7 KiB
Go

package fa
import (
"context"
"fmt"
"iter"
"time"
"github.com/PuerkitoBio/goquery"
"git.anthrove.art/public/go-fa-api/internal/urls"
)
// Journal is a single journal entry, as seen on /journal/{id}/.
type Journal struct {
ID JournalID
Title string
Author UserRef
PostedAt time.Time
BodyHTML string
BodyText string
}
// GetJournal fetches a journal entry by its numeric ID.
func (c *Client) GetJournal(ctx context.Context, id JournalID, opts ...Option) (*Journal, error) {
if id <= 0 {
return nil, fmt.Errorf("fa: GetJournal: id must be > 0")
}
var out *Journal
err := c.fetch(ctx, urls.Journal(int64(id)), func(doc *goquery.Document) error {
j, err := parseJournal(id, doc)
if err != nil {
return err
}
out = j
return nil
}, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// UserJournals iterates a user's journals across pages. The iterator yields
// each [Journal] preview (full body included on FA's listing page).
//
// Use [ListOptions.MaxPages] to bound the crawl.
func (c *Client) UserJournals(ctx context.Context, name string, opts ListOptions, reqOpts ...Option) iter.Seq2[*Journal, error] {
return func(yield func(*Journal, error) bool) {
page := opts.firstPage()
pagesFetched := 0
for {
if opts.reachedLimit(pagesFetched) {
return
}
var (
items []*Journal
hasNext bool
)
err := c.fetch(ctx, urls.UserJournals(name, page), func(doc *goquery.Document) error {
items, hasNext = parseUserJournalsPage(doc)
return nil
}, reqOpts...)
if err != nil {
yield(nil, err)
return
}
pagesFetched++
for _, j := range items {
if !yield(j, nil) {
return
}
}
if !hasNext {
return
}
page++
}
}
}