Índice

  1. Visão geral
  2. Páginas do módulo
  3. Como usar a pesquisa
  4. Termos de pesquisa e sintaxe PubMed
  5. Alertas de novos artigos
  6. Serviço de monitorização (monitor.py)
  7. Notificações por email
  8. Estrutura da base de dados
  9. API REST (endpoints)
  10. Manutenção e diagnóstico

1. Visão geral ↑ topo

O módulo PubMed é um agregador pessoal de literatura científica que consulta a API pública do NCBI PubMed. Permite:

Todos os dados ficam em cache local na base de dados MariaDB (analytics), reduzindo chamadas à API e permitindo acesso offline aos metadados já descarregados.

A arquitectura é simples: um script Python corre via cron e alimenta a base de dados; as páginas PHP consomem essa BD e chamam a API PubMed apenas quando necessário (ex: abstracts ainda não em cache).

2. Páginas do módulo ↑ topo

URLFicheiroFunçãoAcesso
/pubmed/ index.php Pesquisa interactiva de artigos. Selecciona termos por chips, filtra por ano, ordena por data ou relevância, pagina resultados. Público
/pubmed/alertas.php alertas.php Lista os artigos novos detectados pelo monitor. Mostra ponto verde nos não lidos. Permite marcar todos como vistos. Público
/pubmed/guardados.php guardados.php Artigos marcados como favoritos, visitados ou avaliados. Filtrável por tag e texto. Vista pessoal de curadoria. Público
/pubmed/stats.php stats.php Estatísticas da BD local: artigos por termo, por ano, top journals, tipos de publicação, actividade dos alertas por semana, top avaliados. Público
/pubmed/termos.php termos.php Gerir os termos de pesquisa: criar, editar, activar/desactivar, eliminar, reordenar por drag-and-drop. 🔒 Login
/pubmed/manual.php manual.php Esta página. Público

3. Como usar a pesquisa ↑ topo

Chips de termos

No topo da página de pesquisa aparecem chips para cada termo activo. Por omissão todos estão seleccionados (fundo accent). Clica num chip para o desactivar — os artigos desse termo deixam de aparecer nos resultados.

Filtros de data

Os campos De e Até limitam os resultados por ano de publicação. O botão 📅 Último mês activa um filtro para artigos publicados nos últimos 30 dias (limpa os filtros de ano).

Ordenação

Campo de texto livre

Adiciona termos adicionais em linguagem natural ou com qualificadores PubMed ([Author], [MeSH Terms], etc.). É combinado com os chips seleccionados via AND. Premindo Enter pesquisa imediatamente.

Acções por artigo

Clicar no título do artigo abre o abstract (descarregado da API em tempo real, com cache automática) e marca-o como visitado.

Paginação

25 artigos por página. A navegação rola automaticamente para o topo da lista ao mudar de página.

4. Termos de pesquisa e sintaxe PubMed ↑ topo

Os termos são geridos em /pubmed/termos.php (requer login). Cada termo tem:

Termos activos de momento

NomeQueryDescrição
FMUP "FMUP"[Affiliation] OR "Faculdade de Medicina da Universidade do Porto"[Affiliation] Faculdade de Medicina UP
CINTESIS "CINTESIS"[Affiliation] Centro de Investigação em Tecnologias e Serviços de Saúde
Universidade do Porto "Universidade do Porto"[Affiliation]
Rise Health "Rise Health"[Affiliation] Rise Health

Sintaxe das queries PubMed

O PubMed suporta qualificadores de campo entre parêntesis rectos. Exemplos úteis:

QualificadorExemploSignificado
[Affiliation]"FMUP"[Affiliation]Afiliação dos autores contém "FMUP"
[Author]"Silva J"[Author]Autor com esse nome
[MeSH Terms]cardiology[MeSH Terms]Indexado com esse termo MeSH
[Title/Abstract]"machine learning"[Title/Abstract]Palavra no título ou abstract
[Journal]"Lancet"[Journal]Publicado nessa revista
[Publication Type]"Review"[Publication Type]Tipo de publicação

Operadores lógicos: AND, OR, NOT. Múltiplos termos num mesmo chip devem ser ligados com OR:

"CINTESIS"[Affiliation] OR "CINTESIS"[Author Affiliation]
"Universidade do Porto"[Affiliation] AND "cardiology"[MeSH Terms]
Podes testar qualquer query directamente em pubmed.ncbi.nlm.nih.gov antes de a adicionar aqui. O PubMed mostra quantos artigos correspondem e permite refinar a expressão.

5. Alertas de novos artigos ↑ topo

Sempre que o monitor detecta um artigo que ainda não foi alertado, insere um registo em pubmed_alertas com visto=0. Esse registo aparece em /pubmed/alertas.php com um ponto verde.

Estado actual: 158 alertas totais, dos quais 158 por ver.

Marcar como visto

Badge na navbar

O número de alertas não vistos aparece como badge laranja no menu de navegação, ao lado de "Alertas". Actualiza a cada carregamento de página.

Limite de apresentação

A página mostra os 200 alertas mais recentes (o histórico completo fica na BD). Os artigos sem metadados na cache aparecem apenas com o PMID até que o monitor os processe.

6. Serviço de monitorização (monitor.py) ↑ topo

Localização e configuração

/home/pi/pubmed/monitor.py   # script principal
/home/pi/pubmed/monitor.log  # log de execuções

A configuração está no dicionário CONFIG no início do ficheiro:

ParâmetroValor actualDescrição
pubmed.api_key(vazio)Chave NCBI opcional — sem chave: 3 req/s; com chave: 10 req/s
pubmed.emailjagsilva+pubmed@gmail.comObrigatório pela política NCBI (identifica o utilizador)
pubmed.retmax100Máximo de PMIDs por termo por execução
pubmed.dias_atras7Janela de pesquisa: artigos publicados nos últimos N dias
email.enabledFalseEnvio de email ao encontrar novos artigos (ver secção 7)

Agendamento (cron)

Corre 4 vezes por dia, de 6 em 6 horas, com output para o log:

0 0,6,12,18 * * *  /usr/bin/python3 /home/pi/pubmed/monitor.py >> /home/pi/pubmed/monitor.log 2>&1

O que o monitor faz em cada execução

  1. Lê os termos activos da BD (pubmed_termos WHERE ativo=1)
  2. Para cada termo: chama esearch.fcgi com a query + filtro de data (últimos 7 dias) → obtém lista de PMIDs
  3. Descarta os PMIDs já presentes em pubmed_alertas
  4. Para os novos: chama esummary.fcgi em lotes de 50 para obter metadados
  5. Insere os artigos em pubmed_artigos e cria registo em pubmed_alertas com visto=0
  6. Associa o artigo ao termo em pubmed_artigo_termos
  7. Faz commit à BD e (se configurado) envia email

Correr manualmente

python3 /home/pi/pubmed/monitor.py

Ver o log em tempo real

tail -f /home/pi/pubmed/monitor.log

Exemplo de output normal:

2026-06-07 06:00:01 [INFO] === Monitor PubMed iniciado ===
2026-06-07 06:00:01 [INFO] A pesquisar: FMUP
2026-06-07 06:00:02 [INFO]   → 16 PMIDs encontrados
2026-06-07 06:00:02 [INFO]   → 2 novos (não alertados ainda)
2026-06-07 06:00:03 [INFO] A pesquisar: CINTESIS
2026-06-07 06:00:04 [INFO]   → 10 PMIDs encontrados
2026-06-07 06:00:04 [INFO]   → 0 novos (não alertados ainda)
2026-06-07 06:00:07 [INFO] Total de novos artigos: 4
2026-06-07 06:00:07 [INFO] === Monitor concluído ===

Obter uma API Key NCBI (opcional)

Sem chave o monitor respeita o limite de 3 req/s (pause de 350 ms entre pedidos). Com chave sobe para 10 req/s. Para activar:

  1. Regista conta em ncbi.nlm.nih.gov/account
  2. Vai a Settings → API Key Management e gera uma chave
  3. Em /home/pi/pubmed/monitor.py, edita: "api_key": "TUA_CHAVE_AQUI"

7. Notificações por email ↑ topo

O monitor pode enviar um email sempre que encontra artigos novos. Por omissão está desactivado. Para activar, edita /home/pi/pubmed/monitor.py:

"email": {
    "enabled":   True,                    # activar
    "smtp_host": "smtp.gmail.com",
    "smtp_port": 587,
    "user":      "tua_conta@gmail.com",   # conta de envio
    "password":  "password_app_gmail",    # password de app (não a da conta)
    "para":      "jagsilva+pubmed@gmail.com",
},
O Gmail exige uma Password de Aplicação (não a password normal) quando a autenticação em 2 passos está activa. Gera em: Conta Google → Segurança → Passwords de aplicação.

O email lista até 20 artigos com título truncado e link directo para o PubMed.

8. Estrutura da base de dados ↑ topo

Todas as tabelas estão na base de dados analytics e são criadas automaticamente na primeira execução de db.php.

pubmed_termos

ColunaTipoDescrição
idINT PKIdentificador
nomeVARCHAR(200)Nome curto exibido nos chips
queryVARCHAR(1000)Expressão PubMed enviada à API
descricaoVARCHAR(500)Texto explicativo opcional
ativoTINYINT(1)1 = activo; 0 = ignorado pelo monitor
ordemSMALLINTPosição nos chips (drag-and-drop)

pubmed_artigos

Cache local dos metadados vindos da API NCBI esummary.fcgi.

ColunaTipoDescrição
pmidINT PKIdentificador PubMed único
tituloTEXTTítulo completo
autoresTEXT (JSON)Array JSON de nomes de autores
journalVARCHAR(500)Nome completo da revista
journal_abrevVARCHAR(200)Abreviatura da revista (NLM)
volume / numero / paginasVARCHARLocalização bibliográfica
doiVARCHAR(300)Digital Object Identifier
data_pub / anoDATE / SMALLINTData e ano de publicação
abstractMEDIUMTEXTTexto do abstract (preenchido via efetch.fcgi)
keywordsTEXTPalavras-chave do autor
tipos_pubTEXT (JSON)Array JSON de tipos (Journal Article, Review, etc.)
pmc_idVARCHAR(50)ID PubMed Central (acesso ao texto integral)
cached_at / updated_atTIMESTAMPControlo de cache

pubmed_interacoes

Dados pessoais por artigo — um registo por PMID.

ColunaDescrição
pmidPK, referência ao artigo
favorito1 = marcado como favorito
visitado1 = abstract aberto pelo menos uma vez
visitado_emData/hora da primeira visita
ratingClassificação de 0 a 5 estrelas
notasTexto livre pessoal
tagsJSON array de tags (ex: ["revisão","metodologia"])

pubmed_alertas

ColunaDescrição
idPK auto-increment
pmidPMID do artigo (UNIQUE — cada artigo alerta uma vez)
termo_idTermo que gerou o alerta
visto0 = novo (ponto verde); 1 = já visto
created_atData em que o monitor detectou o artigo

pubmed_artigo_termos

Tabela de ligação many-to-many entre artigos e termos (para os badges coloridos nos cards).

Consultas úteis

# Alertas por ver
mysql -u jagsilva -praspberry analytics \
  -e "SELECT COUNT(*) FROM pubmed_alertas WHERE visto=0;"

# Artigos em cache
mysql -u jagsilva -praspberry analytics \
  -e "SELECT COUNT(*) FROM pubmed_artigos;"

# Últimos alertas detectados
mysql -u jagsilva -praspberry analytics \
  -e "SELECT pmid, termo_id, created_at FROM pubmed_alertas ORDER BY created_at DESC LIMIT 10;"

9. API REST (endpoints) ↑ topo

Todos os endpoints estão em /pubmed/api/ e devolvem JSON.

EndpointMétodoAuthDescrição
/pubmed/api/termos.php GET Lista todos os termos activos
/pubmed/api/termos.php POST🔒 Cria novo termo. Body JSON: {nome, query, descricao}
/pubmed/api/termos.php?id=N PUT🔒 Actualiza termo. Body JSON com campos a alterar
/pubmed/api/termos.php?id=N DELETE🔒 Elimina termo
/pubmed/api/pesquisa.php GET Pesquisa no PubMed. Parâmetros: termos (IDs separados por vírgula), q (texto livre), pagina, por_pag, sort (pub_date|relevance), ano_de, ano_ate, reldate (dias)
/pubmed/api/abstract.php?pmid=N GET Devolve abstract (da cache BD ou busca na API NCBI)
/pubmed/api/interacao.php POST🔒 Grava interacção pessoal. Body JSON: {pmid, favorito?, visitado?, rating?, notas?, tags?}
/pubmed/api/alerta.php POST🔒 Marca alerta como visto. Body JSON: {id}
Os endpoints de escrita (POST/PUT/DELETE) devolvem HTTP 401 com {"error":"Não autenticado"} se não houver sessão activa.

10. Manutenção e diagnóstico ↑ topo

Verificar se o cron está configurado

crontab -l | grep pubmed

Deve aparecer: 0 0,6,12,18 * * * /usr/bin/python3 /home/pi/pubmed/monitor.py ...

Verificar a última execução

tail -20 /home/pi/pubmed/monitor.log

Correr o monitor manualmente e ver output

python3 /home/pi/pubmed/monitor.py

O monitor não encontra artigos novos

Erro de ligação à API NCBI

O log mostrará [ERROR] Erro NCBI esearch.fcgi: .... Causas comuns:

Limpar alertas antigos

# Apagar alertas com mais de 6 meses já marcados como vistos
mysql -u jagsilva -praspberry analytics \
  -e "DELETE FROM pubmed_alertas WHERE visto=1 AND created_at < DATE_SUB(NOW(), INTERVAL 6 MONTH);"

Ficheiros relevantes

CaminhoFunção
/home/pi/pubmed/monitor.pyScript Python de monitorização
/home/pi/pubmed/monitor.logLog de todas as execuções
/var/www/html/pubmed/db.phpLigação à BD e criação das tabelas
/var/www/html/pubmed/api/pesquisa.phpProxy para a API PubMed (pesquisa)
/var/www/html/pubmed/api/abstract.phpProxy para abstracts + cache BD