27 KiB
PLANO — Brasiliana Fotográfica → S3
Comece por aqui. Documento de transferência: uma sessão nova consegue retomar o trabalho só com este arquivo. Detalhe técnico completo em
README.md.
Objetivo: os 13.036 itens da Brasiliana Fotográfica — metadados e imagens
em qualidade de preservação — depositados em s3://brasiliana, organizados
como acervo arquivístico (procedência + checksums).
Autorização: a Biblioteca Nacional foi consultada. Confirmou que o material é público e que não tem equipe técnica para fornecer um dump; a coleta por scraping é o caminho combinado. Ritmo cortês e identificação continuam valendo.
Reorganização de pastas em 2026-09-10. Scripts + estado (catálogo,
.sqlite,.log,.tmp/, credenciais) mudaram de raiz parapipeline/; visualizações foram paraweb/;exemplo-item/virouexamples/exemplo-item/;censo.pyvirouarchive/censo.py. Todo comando de terminal abaixo já foi atualizado para o novo caminho. Detalhe completo emREADME.md→ "Estrutura do repositório".Mudança de plano em 2026-09-10 (importante, ver 2.6): o achado 2.4 abaixo não se sustentou. Cloudflare passou a bloquear bitstream via curl também pra itens sem cache de borda — não só HTML. Tudo (Fases 2 e 3) roda pelo navegador agora, trilha única, não mais A/B separadas por tipo de nome. A Fase 4 (legado) segue via curl normalmente — domínio diferente (
objdigital.bn.br), sem esse bloqueio.
1. Estado em 2026-09-30
Coleta concluída em 2026-09-13. Conferido em 2026-09-30 contra o ledger
(pipeline/subidor.sqlite, tabela enviados) e a listagem do bucket.
| Estado | |
|---|---|
| Fase 1 (metadados) | ✅ catalogo.jsonl com 13.060 itens (o falso-positivo /1 não está nele), também no bucket, idêntico ao local |
| Imagem de preservação | ✅ 12.991 itens, 13.194 arquivos, 127,4 GB (121 itens com 2 a 8 imagens: 203 extras) |
| Sem preservação | ⚠️ 69 itens: a origem responde HTTP 500 ao bitstream (errors.md). Todos, menos o 7523, têm a miniatura |
| Miniatura do DSpace | ✅ 13.060 arquivos em 13.059 itens |
| Fase 4 (legado objdigital) | ✅ 2.137 arquivos (1.899 JPG, 213 PDF, 25 outros), 9,6 GB |
| Derivados | ✅ thumb256 13.059 e medio 13.059 |
| Blog | ✅ 636 posts em wordpress/ + wordpress-posts.jsonl |
| Bucket | ✅ 81.269 objetos, 139,2 GB, mais 487 objetos (172 MB) em descricao/ |
MANIFEST.md |
✅ versão final no bucket (2026-09-30) |
| Descrição NOBRADE | ✅ ver §9, também no bucket em descricao/ |
| Mural | ✅ no ar em https://xn--2dk.xyz/brasiliana/; o visor NOBRADE está no branch feat/nobrade (§9, fase 7) |
Nenhum navegador ou subidor precisa estar rodando: a fila local está zerada.
2. Cinco achados que não devem ser redescobertos
Cada um destes custou horas. Nenhum é óbvio, e vários são contraintuitivos.
2.1 O sitemap está sete anos desatualizado
htmlmap/sitemap são de abril/2019 e listam ~5.300 dos 13.036 itens. Enumerar
por eles perde 59% do acervo sem erro aparente — o crawl termina limpo, pela
metade. Fonte correta: browse?type=title&rpp=100&offset=N, percorrido por
comunidade (o que de quebra etiqueta a instituição de origem).
2.2 O arquivo de preservação está no DSpace, não no objdigital
O DC.identifier aponta para objdigital.bn.br e parece ser o master. É o
contrário: o bitstream do DSpace tem 5533×4065 (7,4 MB) contra ~2600×2100
(147 KB) do objdigital. O maior medido: 8679×6484, 34,7 MB — EXIF mostra
Hasselblad H3D II-39MS a 7216×5412.
Inverter isso arquiva o acervo a um quarto da resolução, e nada avisa.
O PDF de 71,9 MB do item 14582 no objdigital não é a mesma imagem melhor: é outro objeto, um álbum de várias páginas.
2.3 O Cloudflare bloqueia automação de navegador — não IP, não geografia
Medido na mesma máquina, mesmo IP, mesmo instante:
| Cliente | Páginas HTML |
|---|---|
| Chrome/Brave do usuário | ✅ 200 |
fetch() de dentro da página |
✅ 200 (>100 seguidas) |
| Playwright headed | ❌ 200 na 1ª, 403 depois |
| Playwright headless | ❌ 403 |
| curl / httpx | ❌ 403 |
| Servidor (Hetzner Helsinki) | ❌ 403 |
Proxies não ajudam — o bloqueio dispara na segunda requisição da mesma sessão, não por origem. Testado e descartado. Não repita.
2.4 Bitstreams passam por curl; páginas HTML não
bitstream/... responde 200 a curl -L simples, até com UA de curl. Só o HTML
é desafiado. É isso que permite baixar os 116 GB fora do navegador, num servidor.
2.5 Nome de arquivo com percent-encoding leva 403
Testado com cinco user-agents (Chrome, Safari, Firefox, Googlebot, curl):
todos 403 numa URL com %28/%20, enquanto curl/8.7.1 puro dá 200
numa URL de nome simples. O gatilho é o caminho, não o cliente — variar
user-agent não resolve. O navegador busca os dois casos sem problema.
Daí as duas trilhas — modelo original, superado, ver 2.6. Itens da BN
usam imagem.jpg (trilha A); os do IMS usam nomes descritivos com espaços
e acentos (trilha B).
2.6 O achado 2.4 não se sustentou — Cloudflare bloqueia bitstream também
Testado ao vivo em 2026-09-10: item nunca antes acessado, buscado pelo
navegador (200 OK) e imediatamente depois via curl na Finlândia — 403,
página real do Cloudflare ("Attention Required"). O único item que passava
por curl (6066) só passava porque já tinha sido baixado com sucesso antes
e ficou em cache de borda (cf-cache-status: HIT) — sobra de um caso, não
regra geral. Pré-aquecer a URL pelo navegador antes de tentar via curl
não transfere o cache pra tornar o curl aceito (testado, falha igual).
Consequência: não existe mais trilha A via servidor. Tudo — nome simples
ou com encoding — precisa passar pelo navegador vivo (fetch() de dentro da
página). baixador.py na Finlândia fica só pra Fase 4 (objdigital, domínio
diferente, sem esse bloqueio — ver 2.11).
2.7 Itens com múltiplos bitstreams reais — não é caso raro
115 itens (de ~13.058) têm 2 a 6 imagens reais no bundle ORIGINAL (contagem final no ledger: 121 itens, 2 a 8 imagens), não
uma. citation_pdf_url não é gerado pra esses (o gerador de citação do
DSpace não sabe qual é "a" imagem quando há mais de uma) — por isso ficam
sem preservation_url na extração simples. Sintoma: full_table tem
dc.description mencionando álbum/página (ex.: "Álbum 0259"), igual ao
caso do PDF de 71,9 MB do achado 2.2 — mesmo fenômeno, mas dentro do
próprio DSpace, não só no objdigital.
Como enumerar as imagens reais de um item, em ordem de confiabilidade:
- Contar
.file-wrapperna página normal do item (não?show=full) — bate com o número real de bitstreams. - Tentar sequências
/bitstream/{PREFIX}/{h}/{seq}/qualquer-nome.jpgpraseqde 1 até N — funciona quando as sequências são contíguas a partir de 1 (maioria dos casos). - Quando (2) falha (sequências não contíguas): pegar o nome real do
arquivo a partir do
<img src>de cada.file-wrapper(é a miniatura, nome com.jpgduplicado no final — ex.nome.jpg.jpg), tirar o último.jpg, e buscar/bitstream/handle/{PREFIX}/{h}/{nome-real}(rota por nome exato, não por sequência).
preservation_url = a maior imagem encontrada (compatibilidade com o
pipeline); all_preservation_urls/all_preservation_sizes guardam todas,
ordenadas da maior pra menor.
Exceção conhecida sem conserto: handle 20.500.12156.1/7523 — HTTP 500 do próprio servidor da BN ao buscar os bitstreams (não é problema de
nome/padrão). Provável arquivo corrompido do lado deles.
2.8b Achado 2.8 falha ~62% das vezes em alguns lotes — bitstream de LICENÇA, não thumbnail
seq_master+1 às vezes é o bitstream de LICENÇA do DSpace (texto puro,
"LICENÇA DE VEICULAÇÃO E DISTRIBUIÇÃO..."), não a miniatura — visto em
Marinha e IMS, 2.655 de 4.278 thumbnails (62%!) baixados errado num
lote, 146 já tinham subido pro bucket antes de descobrir (limpo).
O filtro de tamanho do v1 (> 2MB → rejeita) não pega isso: o texto da
licença é pequeno o bastante (781 bytes) pra passar. Fix: validar
magic bytes (JPEG FFD8/PNG) antes de aceitar, tentar seq+2/+3 se falhar,
e cair pro método do achado 2.7 (<img src> da página) como último
recurso — baixador-thumb.js v2. Também blindado no subidor.py: rejeita
qualquer upload cujo conteúdo não comece com magic bytes de imagem,
independente do nome do arquivo (defesa em camadas).
Lição: tamanho pequeno não é prova de "é a miniatura" — só magic bytes provam que é imagem de verdade.
2.8 Miniatura gerada pelo DSpace: sequência N+1 (quando contígua)
Pra item com bitstream original na sequência N, a miniatura que o DSpace
gera automaticamente costuma ficar na sequência N+1 — confirmado no handle
6066: seq 1 = master (7,7 MB), seq 2 = thumb (56 KB). Mesma rota
filename-agnostic do achado 2.4 original (o nome na URL não importa, só a
sequência). Quando as sequências não são contíguas (itens do achado 2.7 via
método 3), a miniatura de cada imagem é o próprio <img src> do
.file-wrapper correspondente — não precisa de request extra.
2.9 objdigital às vezes tem PDF (álbum), não só JPG — extração pegava o identificador errado
Alguns itens têm mais de um DC.identifier apontando pro objdigital: um
.htm (página de landing) e um .pdf (o álbum de verdade, múltiplas
páginas — mesmo fenômeno do PDF de 71,9 MB do item 14582, achado 2.2). A
extração original pegava o primeiro identificador que batesse com
"objdigital", que pra 44 itens (a maioria uma sequência do Museu
Aeroespacial, 14526-14570, mais o 584) era o .htm, não o .pdf —
perdendo o conteúdo real. De 235 itens com PDF disponível, 191 já estavam
certos por acaso (o PDF vinha primeiro na lista); só 44 precisaram de
correção manual (feita em catalogo.jsonl e no IndexedDB, antes do
baixador.py --somente-legado alcançar esses handles — nada foi
contaminado no bucket). Vale re-checar outros itens com múltiplos
DC.identifier de objdigital por precaução, não só os que têm .pdf.
Recheque feito (2026-09-10): mapeamos todos os padrões de extensão em 2.231 itens com 2+ identifiers objdigital. Achados adicionais:
- 5 itens (
1081, 1082, 1084, 4077, 4084) têm só HTML, sem.jpg/.pdfnenhum — são páginas de um visualizador de zoom profundo (OpenSeadragon/DZI, pirâmide de blocos, não um arquivo único). 3 já tinham sido baixados e subidos como se fossem imagem (arquivos de ~2,4 KB, só a página HTML do visualizador) — limpo do bucket,legacy_urlzerado pros 5 (não vale a complexidade de espelhar a pirâmide de tiles pra tão poucos itens). - 11 itens têm
.sid(MrSID, formato comprimido de imagem grande) além do.jpg— não capturado, ficou como gap conhecido (baixo volume, não priorizado).
2.10 O crawl da Fase 1 não é 100% completo — achado via referência cruzada com o WordPress
Cruzando os handles citados nos 636 posts do WordPress contra o catálogo,
2 itens reais (1799 "Princesa Isabel menina", 4798 "Vista panorâmica de
Canudos...") existem no site mas não foram enumerados pela Fase 1 — ambos
sem citation_pdf_url, formato de metadado antigo (um é de 2015-04-16,
uma das primeiras entradas do sistema). Adicionados manualmente ao
catálogo depois de descobertos.
Isso só foi achado por acaso (porque um post do blog citava esses
handles especificamente) — não existe verificação exaustiva de que a
enumeração por browse?type=title capturou 100% dos itens de cada
comunidade. Pode haver mais itens faltando que nenhum post referencia.
Não investigado a fundo: seria preciso comparar a contagem de cada
comunidade contra alguma fonte independente (a BN não expõe OAI-PMH nem
count via API, até onde sabemos).
2.11 O objdigital só responde em HTTPS — não era bloqueio
legacy_url na fonte vem como http://objdigital.bn.br/.... Conexão HTTP
simples (porta 80) é resetada (Recv failure: Connection reset by peer),
local e da Finlândia. HTTPS funciona liso com curl puro, local (não
testado da Finlândia — motivo original de "não alcançável" pode ser outro,
não investigado). Fix: forçar https:// no legacy_url antes de baixar
(já aplicado em baixador.py).
2.12 Caractere # no nome do arquivo corrompe URL no IndexedDB
78 itens (mesmo álbum "Album 0035/0259/0260") têm # literal no nome real
do arquivo (ex.: Alb 0260 199 CT #.jpg). Algum processo que passou esse
nome por new URL(...).pathname sofreu o efeito clássico: # não
percentado é tratado como início de fragmento da URL, e tudo depois
dele é descartado — a URL salva no IndexedDB virou .../Alb%20...%20CT%20
(sem sequência, sem #, sem .jpg), 404 garantido. O catalogo.jsonl
local nunca foi tocado por esse bug (tem a URL certa, com %23) — fix é
só reescrever o campo no IndexedDB a partir do catálogo
(pipeline/reparo-hash-url.js).
Lição: nunca usar new URL()/.pathname pra manipular nomes de
arquivo vindos de fonte externa sem antes confirmar que não têm #, ?
ou outros caracteres especiais de URL não codificados.
2.13 O mesmo # quebra de novo — desta vez no redirect do próprio DSpace
Mesmo com a URL do achado 2.12 corrigida no IndexedDB (%23 correto, forma
antiga /bitstream/PREFIX/ID/SEQ/arquivo), os 78 itens continuavam dando
404. O DSpace responde a essa forma antiga com um redirect para a forma
canônica nova (/bitstream/handle/PREFIX/ID/arquivo, sem número de
sequência) — e o Location do redirect tem o # sem escapar de novo,
então o fetch() do navegador trunca no fragmento ao seguir o redirect
(finalUrl chega faltando #.jpg, 404). Fix: pedir direto a forma
canônica (/bitstream/handle/...), pulando o redirect — testado, 200,
JPEG válido. preservation_url desses 78 itens reescrito no IndexedDB
para a forma canônica.
Lição: com # no nome do arquivo, não confiar em nenhum redirect do
servidor — ele pode ter o mesmo bug do lado de lá. Preferir sempre a URL
final/canônica quando ela for conhecida.
2.14 Dá pra ler o progresso do BAIXA/BAIXA_THUMB sem o Chrome conectado
O progresso das trilhas via navegador (localStorage.bras_baixados,
bras_thumbs_v2) sobrevive num arquivo leveldb comum no disco —
~/Library/Application Support/Google/Chrome/Default/Local Storage/leveldb
— mesmo com a extensão Claude-in-Chrome desconectada (ex.: conflito de conta
OAuth, sessão anterior perdida). Basta copiar o diretório (evita brigar com
o LOCK que o Chrome mantém aberto) e ler com uma lib leveldb qualquer
(classic-level via npm, sem dependência nativa externa). O valor vem com
1 byte de prefixo indicando encoding (0x00=UTF-16LE, 0x01=UTF-8/Latin1)
antes do JSON de verdade. Script pronto: pipeline/tools/ler-localstorage.js.
Lição: perder a conexão com a extensão do navegador não significa perder visibilidade do progresso — boa parte do estado do app mora em arquivos comuns no disco do usuário, não só "dentro do navegador".
3. O acervo
DSpace 4.2, handles 20.500.12156.1/*. 13.058 itens reais (13.059
descobertos no crawl, menos 1 falso-positivo — .../1 é a página raiz da
comunidade, não um item). Contagem original por comunidade abaixo era de
13.036; a diferença é ruído de borda (comunidades ganham/perdem item ao
longo do tempo), não erro de coleta.
| Instituição | Itens | Instituição | Itens | |
|---|---|---|---|---|
| Instituto Moreira Salles | 5.133 | Fiocruz | 548 | |
| Biblioteca Nacional | 2.726 | Marinha (DPHDM) | 456 | |
| Museu Aeroespacial | 1.143 | Arquivo Nacional | 383 | |
| Museu da República | 906 | Arq. Geral da Cidade do RJ | 248 | |
| Museu Histórico Nacional | 649 | Leibniz-Institut, Leipzig | 216 | |
| IHGB | 206 | Fund. Joaquim Nabuco | 190 | |
| Museu Goeldi | 95 | FGV CPDOC | 79 | |
| IBGE | 58 |
~139,5 GB projetados (recalculado em 2026-09-10 com médias reais de 357-474 arquivos já no bucket por categoria, não mais os 6 originais): preservação+extras ~136,9 GB (13.152 arquivos, 10,7 MB médio), thumbnails ~0,9 GB, legado ~1,5 GB (taxa de sucesso ~75%, muito 404 genuíno), metadados+WordPress+catálogo <0,2 GB combinados.
4. Runbook
Fase 1 — metadados (navegador) ✅ COMPLETA
Cole pipeline/coletor-resume.js (pendentes + erros juntos, numa passada só)
numa aba em https://brasilianafotografica.bn.gov.br/brasiliana/. Acompanhar
com await BRAS.status(). Deixe a aba ativa na janela dela: o Chromium
estrangula setTimeout em abas de fundo até 1×/min, e o loop passa a
rastejar sem erro nenhum. Ao terminar: await BRAS.exportar().
Fases 2 e 3 — trilha única via navegador (não tem mais trilha A/servidor)
Ver achado 2.6. Na mesma aba (mesmo IndexedDB bras), cole em sequência:
// pipeline/baixador-navegador.js -- imagem principal, todos os itens
BAIXA.quantos(); BAIXA.iniciar();
// pipeline/baixador-thumb.js -- miniaturas
BAIXA_THUMB.quantos(); BAIXA_THUMB.iniciar();
// pipeline/baixador-extras.js -- 2a+ imagem dos itens com multiplos bitstreams
// (rodar reparo-multibitstream.js antes, se ainda nao rodou)
BAIXA_EXTRA.quantos(); BAIXA_EXTRA.iniciar();
Em paralelo, em outro terminal:
cd pipeline
set -a; . .s3env; set +a
python3 subidor.py --vigiar --catalogo catalogo.jsonl
Downloads automáticos do Chrome exigem permissão em
chrome://settings/content/automaticDownloads (adicionar
https://brasilianafotografica.bn.gov.br) — sem isso o download "funciona"
no JS (sem erro) mas nenhum arquivo chega no disco. Vale pro domínio
inteiro, uma vez só.
Fase 4 — cópias legadas (máquina local)
cd pipeline
set -a; . .s3env; set +a
python3 baixador.py --catalogo catalogo.jsonl --somente-legado
Via curl direto, sem navegador (ver achado 2.11). ~2.707 itens têm
legacy_url, ~328 KB em média.
5. Arquivos e credenciais
Layout do repo (detalhe em README.md → "Estrutura do repositório"):
scripts + estado ao vivo em pipeline/, visualizações em web/, item de
referência em examples/, código morto em archive/.
| Arquivo | O quê |
|---|---|
tasks/PLANO.md |
Este documento |
README.md |
Referência técnica completa (raiz do projeto) |
pipeline/coletor.js |
Fase 1 — console do navegador, IndexedDB, autoinício |
pipeline/baixador.py |
Fases 2 e 4 — curl → S3, um arquivo por vez |
pipeline/baixador-navegador.js |
Fase 3 — navegador → pasta Downloads |
pipeline/subidor.py |
Fase 3 — Downloads → S3, apaga na hora |
archive/censo.py |
Versão Playwright — não funciona, mantida pelo parsing |
pipeline/.s3env.exemplo |
Modelo; chaves reais em /Users/polux/Projetos/tocador/.env |
S3: hel1.your-objectstorage.com, bucket brasiliana (Hetzner).
Credenciais em /Users/polux/Projetos/tocador/.env
(AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY). Cópia local em
pipeline/.s3env. Na Finlândia: /root/.s3env.
Servidor: ssh finland → 89.167.95.136 (Hetzner Helsinki, root, 31 GB livres).
6. Estrutura no bucket
s3://brasiliana/
MANIFEST.md o que é, como foi coletado, quando
catalogo.jsonl uma linha por item
itens/20.500.12156.1_6066/
metadata.json Dublin Core + URL de origem + data UTC
preservacao/imagem.jpg 5533×4065, 7,4 MB
legado/icon843660.jpg 147 KB, referência de origem
manifest-sha256.txt checksum de cada arquivo
Não negociável: SHA-256 de tudo e URL de origem + data/hora de captura. Sem os dois é pasta de imagens, não arquivo.
7. Pendências
Terminar a Fase 1 e exportar o catálogo.✅ 13.060 itens, 2026-09-13.Medir a fração da trilha B.Obsoleto: desde 2026-09-10 tudo roda por uma trilha única no navegador (ver 2.6), e a coleta acabou.- ~
Confirmar a projeção de✅ Medido: 127,4 GB de preservação e 139,2 GB no bucket, somando tudo.116 GB. Decidir sobre os PDFs de álbum do objdigital.✅ Guardados como cópia legada: são 213 PDF entre os 2.137 arquivos delegado/.Gerar✅MANIFEST.mdecatalogo.jsonlno bucket.catalogo.jsonlno bucket é idêntico ao local (ETag multipart confere);MANIFEST.mdfinalizado e reenviado em 2026-09-30.- Os 69 itens sem preservação dependem da origem voltar a servir o
bitstream (
errors.md). Não há ação possível do nosso lado. - O que falta da descrição e do mural está em §9 (0.2, 7.4). Lista única de
tarefas abertas:
tasks.md.
8. Direitos
Majoritariamente domínio público por antiguidade, mas as 15 instituições têm
políticas distintas. dc.rights e a instituição de origem são preservados
por item: a decisão de redistribuir é item a item, não do acervo em bloco.
Arquivar para si é uma coisa; republicar é outra.
9. Descrição arquivística (NOBRADE)
Resumo da norma e decisões de aplicação em CONARQ.md.
Implementação no branch feat/nobrade: cd pipeline && python3 -m nobrade && python3 -m nobrade.mural.
| # | Tarefa | Entrega | Depende de | Estado |
|---|---|---|---|---|
| 0 — Decisões | ||||
| 0.1 | Definir nome da entidade custodiadora e código provisório (BR RJXYZ) |
pipeline/nobrade/config.py |
— | ✅ provisório BR RJXYZ |
| 0.2 | Pedir código de entidade ao CONARQ | descricao/pedido-codigo-conarq.md |
0.1 | 📝 rascunho pronto (formulário CODEARQ, Res. CONARQ 28/2009); envio é do usuário |
| 0.3 | Fixar a convenção do código de referência (BR RJXYZ.BF.IMS.GF.12345.01) |
CONARQ.md §5.2 |
0.1 | ✅ |
| 1 — Normalizadores (cada um gera uma tabela de revisão) | ||||
| 1.1 | Datas: mais de 20 formatos de dc.date → forma NOBRADE ([1860?], [18--]) + ISO 8601 + original |
descricao/revisao/datas.tsv |
— | ✅ |
| 1.2 | Atribuir data aproximada aos s.d. a partir do fotógrafo |
coluna em datas.tsv |
1.1, 1.4 | ✅ |
| 1.3 | Séries: 2.657 combinações de dc.source → séries canônicas por instituição |
descricao/revisao/series.tsv |
— | ✅ |
| 1.4 | Autoridades: fotógrafos (dc.contributor) e colecionadores, com variantes deduplicadas |
descricao/autoridades.jsonl |
— | ✅ |
| 1.5 | Suporte/espécie: dc.type → gênero + espécie + suporte |
descricao/revisao/tipos.tsv |
— | ✅ |
| 1.6 | Direitos: dc.rights → ~4 categorias, mantendo o original |
descricao/revisao/direitos.tsv |
— | ✅ |
| 1.7 | Data tópica: dc.coverage → cidade (UF) |
campo 1.3 | — | ✅ |
| 1.8 | Assuntos: dc.subject separado em pt/en |
campo 8.1 | — | ✅ |
| 2 — Montagem da hierarquia | ||||
| 2.1 | nobrade: níveis 0→5 com id, parent_id, nivel, codigo |
descricao/unidades.jsonl |
0.3, 1.3 | ✅ |
| 2.2 | Preencher os elementos por nível a partir dos normalizadores | campos "1.3", "2.1"… |
1.x, 2.1 | ✅ |
| 2.3 | Nível 5 para os handles com várias imagens | registros filhos | 2.1 | ✅ toda imagem é nível 5 |
| 2.4 | Somar dimensão e suporte nos níveis 1–3 | campo 1.5 agregado | 2.2 | ✅ |
| 3 — Textos dos níveis altos | ||||
| 3.1 | Nível 1: história arquivística, procedência, acesso, arranjo | descricao/textos/nivel1.md |
— | ✅ |
| 3.2 | Nível 2: breve histórico das 15 instituições | descricao/textos/secoes/ |
— | ✅ fatos conferidos na web, fontes em cada arquivo (2026-09-30) |
| 3.3 | Nível 3: âmbito e conteúdo das séries principais | descricao/textos/series/ |
1.3 | ✅ resumo automático |
| 3.4 | Biografias de fotógrafos a partir dos posts do WordPress | campo 2.2 das autoridades | 1.4 | ✅ fontes nas autoridades |
| 4 — Relações e fontes | ||||
| 4.1 | 5.1 Originais: instituição + handle + Sophia + objdigital | campo automático | 2.1 | ✅ |
| 4.2 | 5.2 Cópias: preservação, legado, miniaturas no S3 | campo automático | 2.1 | ✅ |
| 4.3 | 5.4 Publicações: posts do WordPress → handles citados | campo 5.4 | — | ✅ |
| 5 — Validação | ||||
| 5.1 | Validador dos 7 obrigatórios por nível | descricao/pendencias.md |
2.x | ✅ |
| 5.2 | Rodar, corrigir e repetir até zerar as pendências | relatório limpo | 5.1 | ✅ 0 pendências |
| 6 — Exportação e publicação | ||||
| 6.1 | Exportar EAD 3 | descricao/ead/brasiliana.xml |
5.2 | ✅ valida |
| 6.2 | Exportar EAC-CPF | descricao/eac/*.xml |
1.4 | ✅ valida |
| 6.3 | Validar contra os XSD | xmllint limpo | 6.1, 6.2 | ✅ |
| 6.4 | Subir descricao/ para s3://brasiliana/descricao/ e atualizar o MANIFEST |
objetos no bucket | 6.3 | ✅ 487 objetos, 172 MB, com manifest-sha256.txt; MANIFEST final (2026-09-30) |
| 6.5 | (opcional) CSV de importação do AtoM | descricao/atom.csv |
5.2 | ✅ |
| 7 — Mural | ||||
| 7.1 | Cartão vira visor: painel à esquerda (desktop) ou folha abaixo da imagem (celular); palco com zoom real (roda, pinça, duplo clique, arrastar, + − encaixar, F = só a imagem); barra "← mural | filtros (n)" no topo do painel para voltar ao Atlas 3D e abrir os filtros por cima do visor | web/wall.html |
2.2 | ✅ |
| 7.2 | Ficha arquivística recolhível com os obrigatórios NOBRADE: código (clique copia), nível, arranjo clicável (Brasiliana › instituição › série), data na forma da norma + "na origem", selo "atribuída" nas datas atribuídas pelo arquivista, produtor na forma autorizada ISAAR, dimensão e suporte, original (5.1), reprodução (4.2), citar (copia a referência com o código) | web/wall.html, nobrade/mural.py |
2.2 | ✅ |
| 7.2b | Filtros reagrupados pela NOBRADE: Arranjo (instituição → série em cascata), Data, Pontos de acesso (autor pela autoridade ISAAR, lugar, assunto, pessoa, coleção citada), Suporte e uso (espécie e suporte da 1.5, e condição de reprodução da 4.2, filtro novo); link direto #BR RJXYZ… abre a peça pelo código de referência |
web/wall.html |
7.2 | ✅ |
| 7.2c | Correções de dados que saíram do visor: ano implausível na origem (ex. 20-12-1395) vira data ilegível, com nota; datas atribuídas por série ou instituição usam o miolo p10–p90 ([1933-1943?] em vez de [1800-1999?]); o histograma do mural só usa datas com até 30 anos de amplitude |
nobrade/datas.py, montar.py, mural.py |
1.1 | ✅ |
| 7.3 | Publicar em xyz/brasiliana |
commit | 7.x | ✅ publicado em 30/09 (index.html + atlas-map.json), no ar em https://xn--2dk.xyz/brasiliana/ |
| 7.4 | Derivado derivados/grande/ (WebP de 2.560 px) para zoom nítido. O visor já carrega sob demanda se o mapa tiver grande: true; falta gerar a partir das imagens de preservação no bucket |
derivados/grande/ |
7.1 | ⏳ |