diff --git a/.gitignore b/.gitignore index d230d7d5..3eeb0786 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ var/ *.egg-info/ .installed.cfg *.egg +src/ # PyInstaller # Usually these files are written by a python script from a template diff --git a/opac/tests/test_controller.py b/opac/tests/test_controller.py index e85c045b..b780319a 100644 --- a/opac/tests/test_controller.py +++ b/opac/tests/test_controller.py @@ -1969,3 +1969,72 @@ def test_add_filter_without_embargo_returns_filter_if_input_is_public_false( expected = {"is_public": False, "publication_date__lte": "2021-01-01"} result = controllers.add_filter_without_embargo(kwargs) self.assertDictEqual(expected, result) + + +class CrossmarkPolicyPageControllerTestCase(BaseTestCase): + def _make_journal(self, attrib=None): + return utils.makeOneJournal(attrib=attrib) + + def _make_crossmark(self, journal, attrib=None): + return utils.makeOneCrossmarkPage(journal, attrib=attrib) + + def test_returns_url_when_active_crossmark_exists(self): + """ + Retorna URL quando há CrossmarkPage ativa para o periódico e idioma. + """ + journal = self._make_journal() + self._make_crossmark( + journal, + { + "doi": "10.1590/crossmark-policy", + "url": "https://www.crossref.org/crossmark-policy", + "language": "en", + "is_doi_active": True, + }, + ) + result = controllers.get_crossmark_policy_page(journal, "en") + self.assertEqual("https://www.crossref.org/crossmark-policy", result) + + def test_returns_none_when_active_crossmark_has_no_url(self): + """ + Retorna None quando CrossmarkPage ativa não possui url. + """ + journal = self._make_journal() + self._make_crossmark( + journal, + {"doi": "10.1590/crossmark-policy", "language": "en", "is_doi_active": True}, + ) + result = controllers.get_crossmark_policy_page(journal, "en") + self.assertIsNone(result) + + def test_returns_none_when_no_crossmark_exists(self): + """ + Retorna None quando não há CrossmarkPage para o periódico e idioma. + """ + journal = self._make_journal() + result = controllers.get_crossmark_policy_page(journal, "en") + self.assertIsNone(result) + + def test_returns_none_when_crossmark_is_not_active(self): + """ + Retorna None quando CrossmarkPage existe mas is_doi_active=False. + """ + journal = self._make_journal() + self._make_crossmark( + journal, + {"doi": "10.1590/crossmark-policy", "language": "pt", "is_doi_active": False}, + ) + result = controllers.get_crossmark_policy_page(journal, "pt") + self.assertIsNone(result) + + def test_returns_none_when_language_does_not_match(self): + """ + Retorna None quando CrossmarkPage existe para idioma diferente. + """ + journal = self._make_journal() + self._make_crossmark( + journal, + {"doi": "10.1590/crossmark-policy", "language": "en", "is_doi_active": True}, + ) + result = controllers.get_crossmark_policy_page(journal, "pt") + self.assertIsNone(result) diff --git a/opac/tests/utils.py b/opac/tests/utils.py index e240054b..ba6a9f8f 100644 --- a/opac/tests/utils.py +++ b/opac/tests/utils.py @@ -377,3 +377,20 @@ def getLastIssue(attrib=None): # noqa last_issue.get("suppl_text") or "", ) return models.LastIssue(**last_issue) + + +def makeOneCrossmarkPage(journal, attrib=None): # noqa + """ + Retorna um objeto ``CrossmarkPage`` com os atributos obrigatórios: + ``doi``, ``language``, ``journal``. + Atualiza o objeto de retorno com os valores do param ``attrib``. + """ + attrib = attrib or {} + crossmark = { + "doi": attrib.get("doi", "10.1590/crossmark-policy"), + "is_doi_active": attrib.get("is_doi_active", True), + "language": attrib.get("language", "en"), + "journal": journal, + } + crossmark.update({k: v for k, v in attrib.items() if k not in crossmark}) + return models.CrossmarkPage(**crossmark).save() diff --git a/opac/webapp/controllers.py b/opac/webapp/controllers.py index a80d5d8d..29e96272 100644 --- a/opac/webapp/controllers.py +++ b/opac/webapp/controllers.py @@ -35,6 +35,7 @@ PressRelease, Sponsor, LastIssue, + CrossmarkPage, ) from scieloh5m5 import h5m5 from slugify import slugify @@ -1114,6 +1115,22 @@ def get_article(aid, journal_url_seg, lang=None, gs_abstract=False): return lang, article, {"next_article": next_article, "previous_article": previous_article} +def get_crossmark_policy_page(journal, lang): + """ + Retorna a URL da página de política do Crossmark para o periódico e idioma + informados, ou ``None`` caso não exista registro ativo. + + - ``journal``: objeto Journal do artigo; + - ``lang``: string, código do idioma (ex.: ``'pt'``, ``'en'``). + """ + crossmark = CrossmarkPage.objects( + journal=journal, language=lang, is_doi_active=True + ).first() + if crossmark: + return crossmark.url + return None + + def get_existing_lang(article, lang, gs_abstract): """ Evita falha de recurso não encontrado, diff --git a/opac/webapp/main/views.py b/opac/webapp/main/views.py index b7ad9972..6665a965 100644 --- a/opac/webapp/main/views.py +++ b/opac/webapp/main/views.py @@ -1085,7 +1085,7 @@ def article_detail_pid(pid): ) -def render_html_from_xml(article, lang, gs_abstract=False): +def render_html_from_xml(article, lang, gs_abstract=False, crossmark_policy_page=None): logger.debug("Get XML: %s", article.xml) if current_app.config["SSM_XML_URL_REWRITE"]: @@ -1105,6 +1105,7 @@ def render_html_from_xml(article, lang, gs_abstract=False): gs_abstract=gs_abstract, output_style="website", xslt=xslt, + crossmark_policy_page=crossmark_policy_page, ) return generator.generate(lang), generator.languages @@ -1136,9 +1137,9 @@ def render_html_abstract(article, lang): return abstract_text, article.abstract_languages -def render_html(article, lang, gs_abstract=False): +def render_html(article, lang, gs_abstract=False, crossmark_policy_page=None): if article.xml: - return render_html_from_xml(article, lang, gs_abstract) + return render_html_from_xml(article, lang, gs_abstract, crossmark_policy_page) elif article.htmls: if gs_abstract: return render_html_abstract(article, lang) @@ -1274,8 +1275,13 @@ def _handle_html(): website = "{}://{}".format(parsed_url.scheme, parsed_url.netloc) if citation_pdf_url: citation_pdf_url = "{}{}".format(website, citation_pdf_url) + crossmark_policy_page = controllers.get_crossmark_policy_page( + article.journal, qs_lang + ) try: - html, text_languages = render_html(article, qs_lang, gs_abstract) + html, text_languages = render_html( + article, qs_lang, gs_abstract, crossmark_policy_page + ) except (ValueError, utils.NonRetryableError): abort(404, _("HTML do Artigo não encontrado ou indisponível")) except utils.RetryableError as exc: diff --git a/requirements.txt b/requirements.txt index ab770352..a7fe31db 100644 --- a/requirements.txt +++ b/requirements.txt @@ -94,6 +94,6 @@ zope.interface==5.5.2 tox==4.3.5 PyJWT==2.8.0 tenacity==8.2.3 --e git+https://git@github.com/scieloorg/opac_schema@v2.9.0#egg=Opac_Schema --e git+https://git@github.com/scieloorg/packtools@4.12.4#egg=packtools +-e git+https://git@github.com/scieloorg/opac_schema@60cde7880684bf360602ce49ebfbf494fc4a0682#egg=Opac_Schema +-e git+https://git@github.com/scieloorg/packtools@2960c53f6e94ce1a55e11f72d9b9b9da217c3d73#egg=packtools -e git+https://github.com/scieloorg/scieloh5m5.git@1.9.5#egg=scieloh5m5