boletins
v0.47.0
Published
CLI/TUI para indexar, baixar, extrair e buscar boletins administrativos do Portal IFRN
Downloads
28
Readme
boletins
CLI/TUI para indexar, baixar, extrair texto e buscar boletins administrativos do Portal IFRN.
Espelha a árvore de pastas do portal, baixa os PDFs, extrai o texto de cada página e permite buscar uma frase exata em todo o acervo — com prévia da página encontrada, abertura direta no ponto do resultado (local ou remoto) e recorte de intervalos de páginas em um novo PDF.
Publicação (mantenedores)
npm publishUm único comando: o hook prepack do package.json já roda npm run build
automaticamente antes de empacotar e publicar — não é preciso buildar à
parte. Para conferir o que seria publicado sem publicar de fato:
npm pack --dry-runRequisitos
- Node.js >= 22.5.0
Uso
Sem instalar nada, rode a partir do diretório onde quer manter os dados
baixados (cria uma pasta data/ ali):
npx boletinsIsso abre a TUI em tela cheia, já na tela de busca. Na primeira execução,
use F12 para ir a Configurações → Indexar (baixa os boletins do
portal) e depois Extrair texto (processa os PDFs baixados) antes de
buscar.
Para instalar de forma persistente:
npm install -g boletins
boletinsAtalhos na tela de busca
| Tecla | Ação |
| --------- | ------------------------------------------------------------ |
| Tab | Move entre os campos (frase, página inicial, ano) |
| Enter | Busca / confirma a opção selecionada |
| Esc | Limpa a frase buscada; se já estiver vazia, pergunta se deseja encerrar |
| F12 | Abre a tela de Configurações, mesmo com um campo em foco |
| ↑ ↓ | Navega pelos resultados / opções de um menu |
Modo comando direto (scriptável)
boletins search "termo exato" # busca direto, sem abrir o formulário
boletins exec [campus] # Passos 1 + 2: indexa e depois extrai
boletins exec index [campus] # Passo 1: indexa e baixa os PDFs novos
boletins exec extract [campus] [--force] # Passo 2: extrai o texto dos PDFs baixados
boletins config # mostra a configuração atual
boletins config --start-url <url> # define a URL de partida da indexação
boletins config --search-start-page <numero> # ignora matches antes dessa páginacampus, quando informado, restringe o comando a um único campus (slug usado
nas URLs do Portal IFRN, ex.: apodi, natalcentral, ipanguacu). Omitido,
o comando processa todos os campi do registro. Um slug inválido faz o comando
listar os slugs válidos e sair com erro.
--force (só em exec extract) reprocessa todos os PDFs já baixados, mesmo
os que já tiveram texto extraído — por padrão, só os pendentes são
processados.
bulletin também funciona como alias do comando (nome usado antes do pacote
ser publicado como boletins).
Sincronização remota (bulletin sync)
O Portal IFRN rejeita (503) requisições vindas de fora da rede do IFRN — então
exec index só funciona rodado de dentro dela. Se o servidor onde este app
está publicado (ver Docker abaixo) não está nessa rede, ele nunca
vai conseguir indexar sozinho. bulletin sync existe pra isso: você indexa
(e, se quiser, extrai) numa máquina com acesso ao portal, e envia só o que
falta pro servidor — sem precisar substituir o banco dele inteiro nem tirá-lo
do ar.
No servidor, uma vez, gera a chave de sincronização (fica só o hash gravado no banco — nenhuma env var nem redeploy necessários; rodar de novo troca a chave e invalida a anterior):
docker compose exec boletins node dist/cli/main.js authNa máquina com acesso ao portal, depois de indexar (e, se quiser, extrair localmente):
boletins exec index # precisa estar na rede do IFRN
boletins up --token <chave-gerada-no-auth> --url https://boletins.exemplo.com.br
# ou: BULLETIN_SYNC_URL=https://boletins.exemplo.com.br boletins up --token <chave>auth/up são atalhos de sync auth/sync up (os dois nomes funcionam,
chamam o mesmo comando). auth já imprime o comando up pronto, com a
chave, a flag --token e a URL preenchidas — basta copiar. No Coolify a URL
sai certa sozinha, via COOLIFY_FQDN (ver Variáveis de
ambiente); fora dele, defina BULLETIN_PUBLIC_URL
manualmente. Sem nenhuma das duas, auth chuta http://localhost:<PORT> e
avisa que é só um palpite — confira antes de copiar. Se --token for
omitido, o comando pede a chave interativamente (digitação
mascarada). Ele primeiro pergunta ao servidor o que já está sincronizado e
envia só pastas/arquivos novos ou alterados; interrompeu no meio (rede caiu,
Ctrl+C)? É só rodar up de novo — ele retoma sozinho, sem reenviar o
que já chegou.
Se você não rodou exec extract antes de sincronizar (pra não gastar
tempo/CPU da sua máquina extraindo), a busca só funciona depois de extrair o
texto — o que já pode ser feito no próprio servidor, porque exec extract
não depende do portal, só dos PDFs já no disco:
docker compose exec boletins node dist/cli/main.js exec extractDocker
O projeto tem um único Dockerfile (build multi-stage) que sobe o servidor
web (busca e resultados); indexação e extração continuam manuais, via CLI
dentro do container. A imagem não fixa NODE_ENV — quem sobe o container
decide o ambiente (ver Variáveis de ambiente
abaixo).
Build e subida via Compose (usa NODE_ENV=development, definido em
docker-compose.yml):
docker compose up --buildIsso expõe o servidor web em http://localhost:3000 e persiste os dados
(banco SQLite, PDFs baixados, textos extraídos) no volume boletins-data,
montado em /data.
Build manual da imagem:
docker build -t boletins .
docker run -p 3000:3000 -e NODE_ENV=production -v boletins-data:/data boletinsPara indexar/extrair dentro de um container já em execução:
docker compose exec boletins node dist/cli/main.js execDeploy no Coolify
O Dockerfile já define ENV BULLETIN_DATA_DIR=/data e VOLUME /data, mas
o Coolify não persiste automaticamente um volume anônimo entre deploys — é
preciso criar manualmente, na aba Storages do recurso, um volume
persistente chamado data apontando para o path de destino /data. Sem
isso, o banco SQLite e os PDFs baixados são perdidos a cada novo deploy.
NODE_ENV=production também precisa ser definida manualmente, na aba
Environment Variables do recurso — a imagem não a define sozinha.
Variáveis de ambiente
| Variável | Padrão | Descrição |
| -------------------- | ------------- | -------------------------------------------------------------------------- |
| BULLETIN_DATA_DIR | (heurística*) | Diretório onde ficam o banco SQLite, os PDFs baixados e os textos extraídos. Definida automaticamente como /data nas imagens Docker. |
| PORT | 3000 | Porta em que o servidor web escuta. |
| NODE_ENV | — | Não definida pela imagem. Configure production no Coolify (ou -e NODE_ENV=production no docker run); docker-compose.yml já define development para uso local. |
| BULLETIN_SYNC_URL | — | Só na máquina que roda bulletin up: URL do servidor de destino, alternativa a --url. |
| BULLETIN_SYNC_MAX_FILE_BYTES | 314572800 (300 MB) | Só no servidor: tamanho máximo aceito por arquivo em /sync/files. |
| BULLETIN_PUBLIC_URL | $COOLIFY_FQDN, senão http://localhost:<PORT> | Só no servidor: URL pública deste servidor, usada no comando pronto que bulletin auth imprime. No Coolify normalmente não precisa definir — auth já usa COOLIFY_FQDN (injetada automaticamente pelo Coolify quando o recurso tem domínio configurado na aba Domains) sozinho. Defina manualmente fora do Coolify, ou se o app tiver mais de um domínio e nenhum for o certo para sincronização. |
* Fora de containers, sem BULLETIN_DATA_DIR definida: em um checkout do
repositório (com .git), os dados ficam em data/ na raiz do projeto; via
pacote instalado (npm install -g ou npx), ficam na pasta de dados do
usuário do sistema operacional (%APPDATA%\boletins no Windows,
~/Library/Application Support/boletins no macOS, $XDG_DATA_HOME/boletins
ou ~/.local/share/boletins no Linux).
