Class: Abqari::Folio
- Inherits:
-
Object
- Object
- Abqari::Folio
- Defined in:
- lib/abqari/folio.rb
Overview
Folio integration. Folio (foliobooks.app) is a publishing/storefront app
that exposes a public read-only JSON API for embedding book metadata on
author websites. This class fetches that data at build time and stashes
it in site.data keyed by slug, so layouts can render books / bundles /
series without hitting Folio at runtime — and the visitor never makes a
request to Folio either.
API endpoints used:
GET /api/v1/authors/:slug/publications.json
GET /api/v1/authors/:slug/bundles.json
GET /api/v1/authors/:slug/series.json
Cache-first design (matches the Jekyll plugin in apps/memoirs):
1. Fresh build, network OK → 200 → write cache → use it
2. Subsequent build, no change → 304 → use cache
3. Folio briefly unreachable → use cache, log warning
4. First build, no network → empty data; layouts fall back to front matter
Cache files live in vendor/folio/ (gitignored) so each CI runner
rebuilds its own cache and there's no version-control churn.
Constant Summary collapse
- OPEN_TIMEOUT =
5- READ_TIMEOUT =
10- MAX_RESPONSE_BYTES =
8 MB is enormously generous for Folio's JSON shape — a prolific author with hundreds of titles plus full metadata still fits well under 1 MB. The cap exists so a compromised or misconfigured upstream can't exhaust the CI runner's memory.
8 * 1024 * 1024
- USER_AGENT =
"abqari-folio-fetcher/#{Abqari::VERSION}"
Instance Method Summary collapse
- #author_slug ⇒ Object
- #base_url ⇒ Object
- #cache_dir ⇒ Object
- #config ⇒ Object
- #enabled? ⇒ Boolean
-
#fetch ⇒ Object
Fetches publications + bundles, derives series, populates site.data.
-
#initialize(site) ⇒ Folio
constructor
A new instance of Folio.
Constructor Details
#initialize(site) ⇒ Folio
Returns a new instance of Folio.
41 42 43 44 |
# File 'lib/abqari/folio.rb', line 41 def initialize(site) @site = site @cfg = site.config['folio'] || {} end |
Instance Method Details
#author_slug ⇒ Object
54 55 56 |
# File 'lib/abqari/folio.rb', line 54 def @cfg['author_slug'] end |
#base_url ⇒ Object
50 51 52 |
# File 'lib/abqari/folio.rb', line 50 def base_url @cfg['base_url'] end |
#cache_dir ⇒ Object
62 63 64 65 66 |
# File 'lib/abqari/folio.rb', line 62 def cache_dir # Folio cache is site-specific (different sites pull different # publications), so it lives under the site root. File.join(@site.site_root, 'vendor', 'folio') end |
#config ⇒ Object
58 59 60 |
# File 'lib/abqari/folio.rb', line 58 def config @cfg end |
#enabled? ⇒ Boolean
46 47 48 |
# File 'lib/abqari/folio.rb', line 46 def enabled? base_url && end |
#fetch ⇒ Object
Fetches publications + bundles, derives series, populates site.data. Called from Site#build before page rendering so layouts can read site.data etc. when they render.
Slug filtering. An author may have multiple imprints under one Folio account (e.g. fiction + non-fiction) but want a given site to show only some. Configure either of:
folio:
include_slugs: [memoirs-of-an-assassin, the-russia-assignment]
exclude_slugs: [some-other-book]
include_slugs (when set) wins — only those publications survive,
and only the bundles/series that reference them are kept. Otherwise
exclude_slugs removes the listed publications. Both default to
empty (all publications kept) so existing sites are unaffected.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/abqari/folio.rb', line 84 def fetch return unless enabled? FileUtils.mkdir_p(cache_dir) pubs = filter_publications(fetch_endpoint('publications')) bundles = filter_bundles(fetch_endpoint('bundles'), pubs) series = filter_series(fetch_endpoint('series'), pubs) @site.data['folio_publications'] = index_by_slug(pubs) @site.data['folio_bundles'] = index_by_slug(bundles) @site.data['folio_series'] = index_by_slug(series) pubs_count = @site.data['folio_publications'].size bundles_count = @site.data['folio_bundles'].size series_count = @site.data['folio_series'].size Log.info "Folio: loaded #{pubs_count} publication(s), #{bundles_count} bundle(s), #{series_count} series" end |