Prompt — public_domain gem como retriever de contenido rasterizable
Fecha: 2026-08-03
Repo destino: github.com/[usuario]/public_domain_gem
Consumidor: ~/nef/archive-lending-clone (lector de préstamo con spread de dos páginas)
Para qué: que poblar el catálogo del lector deje de ser artesanal.
Pegar de aquí abajo.
Contexto
Estoy usando este gem como retriever de contenido de dominio público para un lector web que muestra páginas escaneadas en un spread de dos hojas. El gem ya resuelve búsqueda y metadata. Le falta exactamente lo que el lector necesita para decidir si un item se puede paginar y cómo pedir cada página.
Hoy Archive::Item y Archive::Result exponen iiif_manifest_url, pero un
consumidor no puede saber, sin trabajo extra, si el item realmente sirve
imágenes de página ni cuántas hay. Eso es lo que quiero cerrar.
Qué agregar
Tres cosas, en lib/public_domain/archive/item.rb y su equivalente en
result.rb donde aplique:
1. #rasterizable?
True si el item tiene derivados de imagen servibles por IIIF.
Heurística verificada: la presencia de un archivo cuyo nombre termina en
_jp2.zip en la lista de files. Comprobado contra tres items:
| identifier | _jp2.zip | IIIF sirve páginas |
|---|---|---|
donquijote00cervuoft | sí | sí |
parasoperdidop01miltuoft | sí | sí |
manualpaleografia00riveuoft | no | no — 404 en toda página, 500 en el manifiesto |
Esto se resuelve con la metadata que Item.fetch ya trae. No pidas el
manifiesto solo para esto.
2. #page_count
Número real de páginas paginables.
Trampa importante: NO uses metadata["imagecount"]. No coincide con el
número de canvases del manifiesto IIIF:
| identifier | imagecount | canvases reales |
|---|---|---|
donquijote00cervuoft | 910 | 906 |
parasoperdidop01miltuoft | 392 | 388 |
Confiar en imagecount produce 404 en las últimas páginas. El número bueno es
items.length del manifiesto (IIIF Presentation 3 — es items, no
sequences[].canvases de la v2).
Como el manifiesto es caro y a veces falla, page_count debe pedirlo de forma
diferida y memoizada, y devolver nil si el item no es rasterizable? o si el
manifiesto falla. nil significa “no paginable”, no cero.
3. #page_image_url(index, height: nil, width: nil)
Constructor de URL de una página. Patrón verificado, sin necesidad de leer el manifiesto:
https://iiif.archive.org/iiif/<identifier>$<index>/full/,<height>/0/default.jpg
indexes 0-indexed. Documentalo en el método: es la fuente más probable de bugs off-by-one en los consumidores.- Sin
heightniwidth, usa/full/max/0/default.jpg. - Escapa el identifier.
Robustez que quiero
- Un manifiesto que devuelve 500 no debe reventar nada:
manualpaleografia00riveuoftes un caso real y vivo. Debe degradar apage_count → nil, no a excepción. - Nada de peticiones de red en el constructor.
page_countes lazy; el resto sale de la metadata que ya se tiene.
Tests
Sigue el estilo de test/archive/item_test.rb con fixtures en test/fixtures/.
Casos mínimos:
- item con
_jp2.zip→rasterizable?true - item sin
_jp2.zip→rasterizable?false,page_countnil, sin pedir red - manifiesto 500 →
page_countnil, sin levantar excepción page_countmemoizado: dos llamadas, una sola peticiónpage_image_url(0)genera índice$0, no$1page_image_urlcon y sinheight
Ojo: los identifiers de los fixtures actuales (elingeniosohidalgo,
audioquijote) son ficticios y devuelven metadata vacía contra la API real. Si
agregas fixtures nuevos, cápturalos de items reales.
Fuera de alcance
No toques el modelo de búsqueda, ni Europeana/Wikisource/OAI, ni agregues un cliente IIIF completo. Solo lo que hace falta para paginar un item de Archive.
Extra, si sale barato
Un #to_h que ya incluya rasterizable, page_count e identifier me deja
generar el catálogo del lector directo desde una búsqueda, sin pegamento
intermedio.
Por qué estos campos y no otros
Lo que consume el lector para decidir el modo de render:
rasterizable?→ usa imágenes IIIF (rápido, sin bajar el PDF)- si no → cae al PDF, que en Archive.org no tiene CORS, así que solo puede
ir en un
<iframe>, no rasterizarse con pdf.js page_count→ arma el spread y calcula el límite final
Detalle que motivó todo esto: archive.org/download/ no manda
Access-Control-Allow-Origin, pero iiif.archive.org manda *. Por eso el
camino de imágenes es el único rasterizable del lado cliente para este origen.