feat: visor da peça com zoom real, ficha NOBRADE e filtros agrupados pela norma

- painel à esquerda (folha no celular) com barra ← mural | filtros, palco com
  roda, pinça, duplo clique, arrastar e modo só a imagem (F)
- ficha arquivística: código, nível, arranjo clicável, data da norma com selo
  de atribuída, produtor ISAAR, suporte, original, reprodução e citação
- filtros em Arranjo, Data, Pontos de acesso e Suporte e uso; autor pela
  autoridade, espécie da 1.5 e condição de reprodução; link pelo código
- datas: ano implausível vira ilegível, atribuição pelo miolo p10–p90 e
  histograma só com datas de até 30 anos de amplitude
This commit is contained in:
2026-09-30 22:30:13 +02:00
parent 23b56e8c87
commit 5c84619e5d
5 changed files with 668 additions and 311 deletions
+17 -2
View File
@@ -21,6 +21,7 @@ from __future__ import annotations
import re
import unicodedata
from dataclasses import dataclass, field
from datetime import date
MESES = {
'jan': 1, 'janeiro': 1, 'fev': 2, 'fevereiro': 2, 'mar': 3, 'março': 3, 'marco': 3,
@@ -247,6 +248,20 @@ def _intervalo(s: str) -> tuple[Ponto | None, Ponto | None, bool]:
return None, None, False
ANO_MIN, ANO_MAX = 1500, date.today().year
def _plausivel(d: Data) -> Data:
"""Um ano fora do possível ("20-12-1395") é erro de digitação na origem: não vira data."""
anos = [x for x in d.anos() if x is not None]
if anos and (min(anos) < ANO_MIN or max(anos) > ANO_MAX):
d.notas.append(f'ano implausível na origem ({d.original}); data desconsiderada')
d.inicio_p = d.fim_p = None
d.relacao = ''
d.motivo = 'ilegível'
return d
def interpreta(texto: str | None) -> Data:
original = (texto or '').strip()
d = Data(original)
@@ -311,11 +326,11 @@ def interpreta(texto: str | None) -> Data:
p, inc = _ponto(s)
if p:
d.inicio_p, d.incerta = p, d.incerta or inc
return d
return _plausivel(d)
a, b, inc = _intervalo(s)
if a:
d.inicio_p, d.fim_p, d.incerta = a, b, d.incerta or inc
return d
return _plausivel(d)
# "1900-" (colchete aberto): dali em diante
if m := re.fullmatch(r'(\d{4})\s*-', s):
d.inicio_p, d.relacao = Ponto(int(m[1])), 'depois'