Skip to content

Refatoração da coleta e armazenamento dos dados de Journal#1403

Merged
robertatakenaka merged 7 commits intoscieloorg:mainfrom
robertatakenaka:aprimora_obtencao_de_dados_de_journal
Mar 12, 2026
Merged

Refatoração da coleta e armazenamento dos dados de Journal#1403
robertatakenaka merged 7 commits intoscieloorg:mainfrom
robertatakenaka:aprimora_obtencao_de_dados_de_journal

Conversation

@robertatakenaka
Copy link
Member

Contexto

Este PR corrige um conjunto de falhas relacionadas ao registro de títulos paralelos de periódicos e à propagação inconsistente de parâmetros em toda a cadeia de processamento do módulo journal. Os problemas centrais eram: ocorrência de MultipleObjectsReturned em JournalParallelTitle, uso de verify=False hardcoded em chamadas HTTP, e referências a collection.domain em vez de collection.base_url.


Mudanças

journal/models.py — JournalParallelTitle refatorado

Adiciona constraint unique_together em (official_journal, text, language) para prevenir duplicatas no banco. Extrai método cls.get() com lógica de deduplicação quando MultipleObjectsReturned é detectado. Adiciona cls.create() que remove duplicatas antes de inserir o novo registro. Reescreve create_or_update() usando os novos get() e create(), com suporte ao parâmetro user para atribuição de creator e updated_by.

journal/sources/am_to_core.py

Substitui get_or_create por create_or_update no registro de títulos paralelos vindos do ArticleMeta. Passa language=None explicitamente e utiliza o novo JournalParallelTitle.create_or_update(), eliminando a origem dos erros de MultipleObjectsReturned nesse fluxo.

journal/sources/article_meta.py

Adiciona verify=True em _get_collection_journals, _fetch_and_store_journal e process_journal_article_meta, substituindo o verify=False hardcoded em todas as chamadas a fetch_data.

journal/sources/classic_website.py

Substitui collection.domain por collection.base_url no loader do classic_website, alinhando com o campo correto do modelo de coleção.

journal/tasks.py

  • Adiciona verify=True em load_journal_from_article_meta e load_journal_from_article_meta_for_one_collection
  • Força load_data=True quando AMJournal não possui registros para a coleção/ISSN
  • Sempre executa _register_journal_data após load_data, removendo o bloco else que podia impedir o processamento
  • Substitui collection.domain por collection.base_url na construção da URL de logo e em fetch_and_process_journal_logo

journal/scripts/

Adiciona verify=True nos scripts harvest_am_journal.py e load_journal_from_am_journal.py, tornando o comportamento consistente com o restante do módulo.

bigbang/tasks_scheduler.py

Passa verify=True nos kwargs de schedule_load_journal_from_article_meta e schedule_collect_journals_from_am, habilitando verificação SSL no agendamento das tarefas de journals.


Impacto

  • Elimina MultipleObjectsReturned no registro de títulos paralelos
  • Remove verify=False de todas as chamadas HTTP do módulo journal
  • Uniformiza o uso de collection.base_url em loaders, tasks e scripts
  • Garante que _register_journal_data seja sempre executado após o carregamento dos dados

…urned

- Adiciona constraint unique_together em (official_journal, text, language)
- Extrai cls.get() com lógica de deduplicação em caso de MultipleObjectsReturned
- Adiciona cls.create() que remove duplicatas antes de inserir
- Reescreve create_or_update() usando get() + create(), com suporte ao
  parâmetro user para atribuição de creator e updated_by
…alelos

Evita MultipleObjectsReturned ao registrar títulos paralelos vindos do AM.
Passa language=None explicitamente e usa o novo JournalParallelTitle.create_or_update().
Adiciona verify=True em _get_collection_journals, _fetch_and_store_journal
e process_journal_article_meta, substituindo verify=False hardcoded em
todas as chamadas a fetch_data.
- Adiciona verify=True em load_journal_from_article_meta e
  load_journal_from_article_meta_for_one_collection
- Força load_data=True quando AMJournal não possui registros para a coleção/issn
- Sempre executa _register_journal_data após load_data (remove bloco else)
- Substitui collection.domain por collection.base_url no construtor de URL
  de logo e em fetch_and_process_journal_logo
…s do AM

Passa verify=True nos kwargs de schedule_load_journal_from_article_meta
e schedule_collect_journals_from_am para habilitar verificação SSL.
Copilot AI review requested due to automatic review settings March 12, 2026 21:39
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Este PR busca corrigir falhas na coleta/armazenamento de dados de journals (deduplicação de JournalParallelTitle, padronização de verify em requisições HTTP e troca de collection.domain por collection.base_url) e ajustar o fluxo de carga a partir do ArticleMeta.

Changes:

  • Propaga verify (default True) para as chamadas de coleta via ArticleMeta e para o agendamento/execução das tasks relacionadas.
  • Ajusta fontes/loaders e tasks para usar collection.base_url em vez de collection.domain e garante execução de _register_journal_data.
  • Refatora JournalParallelTitle com novos métodos (get/create/create_or_update) e tentativa de constraint de unicidade.

Reviewed changes

Copilot reviewed 8 out of 8 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
journal/tasks.py Propaga verify, ajusta fluxo de carga/registro e troca domain por base_url ao construir URL de logo.
journal/sources/classic_website.py Usa collection.base_url nas requisições ao classic website.
journal/sources/article_meta.py Adiciona verify às chamadas fetch_data e ajusta o pipeline de coleta/registro.
journal/sources/am_to_core.py Troca criação de títulos paralelos para usar JournalParallelTitle.create_or_update.
journal/scripts/load_journal_from_am_journal.py Passa verify=True para a task.
journal/scripts/harvest_am_journal.py Passa verify=True para a task.
journal/models.py Refatora JournalParallelTitle e altera comportamento de painéis Wagtail (InlinePanels).
bigbang/tasks_scheduler.py Atualiza agendamentos/limpeza de tasks e adiciona verify=True em tasks de journal.
Comments suppressed due to low confidence (1)

bigbang/tasks_scheduler.py:168

  • schedule_task_export_articles_to_articlemeta passa issn, number e volume em kwargs, mas a task article.tasks.task_export_articles_to_articlemeta não aceita esses parâmetros (assinatura atual só inclui collection_acron_list, journal_acron_list, from_*, until_*, etc.). Isso deve causar TypeError: got an unexpected keyword argument ... quando a PeriodicTask rodar; remova esses kwargs ou atualize a assinatura/encaminhamento para suportá-los.
        task="article.tasks.task_export_articles_to_articlemeta",
        name="article.tasks.task_export_articles_to_articlemeta",
        kwargs=dict(
            collection_acron_list=[],
            issn=None,
            number=None,
            volume=None,
            year_of_publication=None,

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +422 to +423
task="issue.tasks.load_issue_from_articlemeta",
name="load_issue_from_articlemeta",
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

O scheduler está configurado para executar issue.tasks.load_issue_from_articlemeta, mas a task existente em issue/tasks.py é load_issue_from_article_meta (com _meta). Do jeito que está, a execução vai falhar por task inexistente; alinhe o path/nome da task agendada com a função Celery real.

Suggested change
task="issue.tasks.load_issue_from_articlemeta",
name="load_issue_from_articlemeta",
task="issue.tasks.load_issue_from_article_meta",
name="load_issue_from_article_meta",

Copilot uses AI. Check for mistakes.
Comment on lines 234 to 238
"function": "journal.sources.article_meta._register_journal_data",
"collection": collection_acron3,
"issn": journal_am.scielo_issn,
"issn": journal_am.scielo_issn, # Mudança aqui: scielo_issn -> pid
"data_journal": journal_am.data,
},
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aqui é usado journal_am.scielo_issn, mas o modelo AMJournal possui o campo pid. Isso pode gerar AttributeError na criação do UnexpectedEvent e perder a informação do erro original; troque para journal_am.pid e remova/atualize o comentário inline.

Copilot uses AI. Check for mistakes.
@@ -1,4 +1,5 @@
import sys
import logging
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Import logging foi adicionado mas não é usado em nenhum ponto do módulo. Remover o import evita ruído e ajuda ferramentas de lint/CI a passarem sem falsos positivos.

Suggested change
import logging

Copilot uses AI. Check for mistakes.
]

class Meta:
unique_together = ("official_journal", "text", "language")
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Foi adicionado unique_together = ("official_journal", "text", "language"), mas (1) não há migration no app journal aplicando essa alteração no banco, e (2) como language é NULL=True (herdado de TextWithLang), a constraint não impede duplicatas quando language é NULL (caso que o próprio fluxo está passando explicitamente como None). Para realmente evitar duplicatas, considere tornar language não-nulo (ou definir um valor padrão) ou usar UniqueConstraint condicional para language__isnull=True, e inclua migration (idealmente com deduplicação prévia dos registros já duplicados) para não quebrar o deploy.

Suggested change
unique_together = ("official_journal", "text", "language")
constraints = [
# Garante que não haja duplicatas para o mesmo (official_journal, text)
# quando language for NULL.
models.UniqueConstraint(
fields=("official_journal", "text"),
condition=Q(language__isnull=True),
name="uniq_journalparalleltitle_null_language",
),
# Garante unicidade para (official_journal, text, language)
# quando language não for NULL.
models.UniqueConstraint(
fields=("official_journal", "text", "language"),
condition=Q(language__isnull=False),
name="uniq_journalparalleltitle_with_language",
),
]

Copilot uses AI. Check for mistakes.
Comment on lines 196 to 200
"function": "journal.sources.article_meta._register_journal_data",
"collection": collection_acron3,
"issn": journal_am.scielo_issn,
"issn": journal_am.scielo_issn, # Mudança aqui: scielo_issn -> pid
"data_journal": journal_am.data,
},
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aqui é usado journal_am.scielo_issn, mas o modelo AMJournal possui o campo pid (renomeado em migrations anteriores). Isso pode gerar AttributeError durante o registro de erro e mascarar a exceção original; use journal_am.pid (ou outro atributo realmente existente) e ajuste o comentário inline.

Copilot uses AI. Check for mistakes.
try:
# Se load_data igual a True
# Carrega os dados obtidos de article meta em AMJournal
# Se load_data igual a Fase
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comentário diz "Se load_data igual a Fase" — parece ser um typo e deveria ser "False". Corrigir melhora a legibilidade do fluxo do task.

Suggested change
# Se load_data igual a Fase
# Se load_data igual a False

Copilot uses AI. Check for mistakes.
logger.warning("No collection provided for journal logo URL construction")
return None
if not collection.base_url:
logger.warning(f"Collection {collection.acron3} has no domain defined")
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A mensagem de warning ainda diz "has no domain defined", mas o código agora valida collection.base_url. Ajustar o texto para refletir base_url evita confusão ao depurar logs.

Suggested change
logger.warning(f"Collection {collection.acron3} has no domain defined")
logger.warning(f"Collection {collection.acron3} has no base_url defined")

Copilot uses AI. Check for mistakes.
Comment on lines +630 to +636
InlinePanel("other_titles", label=_("Other titles")),
]

panels_scope_and_about = [
InlinePanel("mission", label=_("Mission"), classname="collapsed"),
InlinePanel("history", label=_("Brief History"), classname="collapsed"),
InlinePanel("focus", label=_("Focus and Scope"), classname="collapsed"),
InlinePanel("mission", label=_("Mission")),
InlinePanel("history", label=_("Brief History")),
InlinePanel("focus", label=_("Focus and Scope")),
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Este PR removeu classname="collapsed" de vários InlinePanels, alterando o comportamento/UX do admin do Wagtail, mas isso não aparece no contexto/descrição do PR (que foca em coleta/armazenamento e SSL verify). Se não for intencional, vale reverter para reduzir o escopo/risco; se for intencional, documentar na descrição ajuda revisores e release notes.

Copilot uses AI. Check for mistakes.
for title in titles:
JournalParallelTitle.objects.get_or_create(
# Usa create_or_update em vez de get_or_create para evitar MultipleObjectsReturned
from journal.models import JournalParallelTitle
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dentro do loop já existe import de JournalParallelTitle no topo do arquivo; este from journal.models import JournalParallelTitle dentro de get_or_update_parallel_titles é redundante e adiciona overhead/ruído. Remova o import local e use a referência já importada no módulo.

Suggested change
from journal.models import JournalParallelTitle

Copilot uses AI. Check for mistakes.
Comment on lines +125 to +126
task="article.tasks.task_dispatch_articles",
name="article.tasks.task_dispatch_articles",
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

schedule_task_dispatch_articles agenda a tarefa article.tasks.task_dispatch_articles, mas não existe nenhuma função/task com esse nome no repositório (não há definição em article/tasks.py). Isso fará o scheduler criar PeriodicTasks que sempre falharão ao executar; ajuste para o nome correto da task existente ou inclua a implementação da task no PR.

Suggested change
task="article.tasks.task_dispatch_articles",
name="article.tasks.task_dispatch_articles",
task="article.tasks.load_articles",
name="article.tasks.load_articles",

Copilot uses AI. Check for mistakes.
@robertatakenaka robertatakenaka merged commit e46b362 into scieloorg:main Mar 12, 2026
5 of 7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants