diff --git a/core/models.py b/core/models.py index 78f6b235..b0e849f1 100755 --- a/core/models.py +++ b/core/models.py @@ -5,6 +5,7 @@ from django.db import models, IntegrityError from django.db.models import Case, When, Value, IntegerField from django.utils.translation import gettext as _ +from django.utils.html import strip_tags from wagtail.admin.panels import FieldPanel from wagtail.fields import RichTextField from wagtail.search import index @@ -268,7 +269,11 @@ class RichTextWithLanguage(models.Model): AutocompletePanel("language"), FieldPanel("rich_text"), ] - + + @property + def get_text_pure(self): + return strip_tags(self.rich_text) + objects = LanguageFallbackManager() class Meta: diff --git a/core/utils/api_articlemeta_format.py b/core/utils/api_articlemeta_format.py new file mode 100644 index 00000000..93d21676 --- /dev/null +++ b/core/utils/api_articlemeta_format.py @@ -0,0 +1,9 @@ +def add_items(key, items, dictonary): + for item in items: + add_to_result(key, item, dictonary) + +def add_to_result(key, value, dictonary): + if value: + if key not in dictonary: + dictonary[key] = [] + dictonary[key].append({"_": value}) diff --git a/institution/models.py b/institution/models.py index a1f195bd..3f6b57d9 100755 --- a/institution/models.py +++ b/institution/models.py @@ -436,6 +436,49 @@ def __str__(self): return self.institution.institution.institution_identification.name except AttributeError: return '' + + @property + def get_institution_name(self): + try: + return self.institution.institution.institution_identification.name + except AttributeError: + return None + + @property + def get_institution_city_name(self): + try: + return self.institution.institution.location.city.name + except AttributeError: + return None + + @property + def get_institution_country_name(self): + try: + return self.institution.institution.location.country.name + except AttributeError: + return None + + @property + def get_institution_country_acronym(self): + try: + return self.institution.institution.location.country.acronym + except AttributeError: + return None + + @property + def get_institution_state_name(self): + try: + return self.institution.institution.location.state.name + except AttributeError: + return None + + @property + def get_instition_state_acronym(self): + try: + return self.institution.institution.location.state.acronym + except AttributeError: + return None + class BaseInstitution(CommonControlField): institution = models.ForeignKey( diff --git a/issue/api/v1/views.py b/issue/api/v1/views.py index c14d45c6..9b7a3408 100644 --- a/issue/api/v1/views.py +++ b/issue/api/v1/views.py @@ -1,12 +1,19 @@ from rest_framework.exceptions import ValidationError from django.db.models import Q -from rest_framework import viewsets +from rest_framework import viewsets, serializers from article import models from core.validators import validate_params from .serializers import IssueSerializer +class ArticleMetaFormatIssueSerializer(serializers.ModelSerializer): + class Meta: + model = models.Issue + + def to_representation(self, instance): + return instance.articlemeta_format + class GenericIssueViewSet(viewsets.ModelViewSet): serializer_class = IssueSerializer @@ -53,6 +60,7 @@ def get_queryset(self): "number", "supplement", "page", + "formats", "", ) @@ -85,4 +93,8 @@ def get_queryset(self): queryset = queryset.filter(**params) return queryset - \ No newline at end of file + def get_serializer_class(self): + format_param = self.request.query_params.get("formats") + if format_param == "articlemeta": + return ArticleMetaFormatIssueSerializer + return IssueSerializer \ No newline at end of file diff --git a/issue/models.py b/issue/models.py index 310af6ea..b3ce2d2a 100755 --- a/issue/models.py +++ b/issue/models.py @@ -209,6 +209,10 @@ def __str__(self): return "%s, %s, %s" % (self.journal, issue_info, self.year) + @property + def articlemeta_format(self): + from .sources.articlemeta_format import get_articlemeta_format_issue + return get_articlemeta_format_issue(self) base_form_class = CoreAdminModelForm diff --git a/issue/sources/articlemeta_format.py b/issue/sources/articlemeta_format.py new file mode 100644 index 00000000..2a4d02b8 --- /dev/null +++ b/issue/sources/articlemeta_format.py @@ -0,0 +1,32 @@ +from journal.models import SciELOJournal, TitleInDatabase +from core.utils.api_articlemeta_format import add_to_result, add_items + +def get_articlemeta_format_issue(obj): + result = {} + + scielo_issn = SciELOJournal.objects.filter(journal=obj.journal).first().issn_scielo + + add_to_result("v30", obj.journal.short_title, result) + add_to_result("v31", obj.volume, result) + add_to_result("v32", obj.number, result) + add_to_result("v35", scielo_issn, result) + add_items("v62", [ch.get_institution_name for ch in obj.journal.copyright_holder_history.all()], result) + + # Data de publicação do fascículo + year = obj.year + month = obj.month + if year and month: + add_to_result("v64", year + month, result) + elif year: + add_to_result("v64", year, result) + add_to_result("v117", obj.journal.standard.code if obj.journal.standard else None, result) + add_to_result("v130", obj.journal.title if obj.journal.title else None, result) + add_items("v140", [sponsor.get_institution_name for sponsor in obj.journal.sponsor_history.all()], result) + add_to_result("v151", obj.journal.official.iso_short_title if obj.journal.official and obj.journal.official.iso_short_title else None, result) + add_items("v230", [pt.text for pt in obj.journal.official.parallel_titles if obj.journal.official and pt.text], result) + medline_titles = TitleInDatabase.objects.filter(journal=obj.journal, indexed_at__acronym__iexact="medline") + add_items("v421", [medline.title for medline in medline_titles], result) + + add_items("v480", [publisher.get_institution_name for publisher in obj.journal.publisher_history.all()], result) + + return result diff --git a/journal/api/v1/serializers.py b/journal/api/v1/serializers.py index 009598fa..3987ed94 100644 --- a/journal/api/v1/serializers.py +++ b/journal/api/v1/serializers.py @@ -67,7 +67,7 @@ class Meta: class MissionSerializer(serializers.ModelSerializer): - language = serializers.CharField(source="language.code2") + language = serializers.SerializerMethodField() class Meta: model = models.Mission @@ -75,7 +75,10 @@ class Meta: "rich_text", "language", ] - + def get_language(self, obj): + if obj.language is not None: + return obj.language.code2 + return None class JournalSerializer(serializers.ModelSerializer): # Serializadores para campos de relacionamento, como 'official', devem corresponder aos campos do modelo. @@ -182,7 +185,7 @@ def get_other_titles(self, obj): def get_next_journal_title(self, obj): if obj.official and obj.official.next_journal_title: try: - journal_new_title = models.Journal.objects.get(title__icontains=obj.official.next_journal_title) + journal_new_title = models.Journal.objects.get(title__exact=obj.official.next_journal_title) issn_print = journal_new_title.official.issn_print issn_electronic = journal_new_title.official.issn_electronic except models.Journal.DoesNotExist: @@ -198,7 +201,7 @@ def get_previous_journal_title(self, obj): if obj.official and obj.official.previous_journal_titles: try: old_journal = obj.official.old_title.get( - title__icontains=obj.official.previous_journal_titles + title__exact=obj.official.previous_journal_titles ) old_issn_print = old_journal.issn_print old_issn_electronic = old_journal.issn_electronic diff --git a/journal/api/v1/views.py b/journal/api/v1/views.py index 46d69027..957878df 100644 --- a/journal/api/v1/views.py +++ b/journal/api/v1/views.py @@ -1,12 +1,17 @@ from django.db.models import Q -from rest_framework import viewsets +from rest_framework import viewsets, serializers from journal import models from .serializers import JournalSerializer from core.validators import validate_params +class ArticleMetaFormatSerializer(serializers.ModelSerializer): + class Meta: + model = models.Journal + def to_representation(self, instance): + return instance.articlemeta_format class GenericJournalViewSet(viewsets.ModelViewSet): serializer_class = JournalSerializer @@ -42,6 +47,7 @@ def get_queryset(self): "until_date_created", "from_date_updated", "until_date_updated", + "formats", "", ) @@ -72,3 +78,9 @@ def get_queryset(self): params["updated__lte"] = until_date_updated.replace("/", "-") return queryset.filter(**params) + + def get_serializer_class(self): + format_param = self.request.query_params.get("formats") + if format_param == "articlemeta": + return ArticleMetaFormatSerializer + return JournalSerializer diff --git a/journal/models.py b/journal/models.py index 6b9b7907..26467f9d 100755 --- a/journal/models.py +++ b/journal/models.py @@ -903,6 +903,11 @@ def __str__(self): title = self.title or str(self.official) return f"{title} ({collection_acronym}) | ({issns})" + @property + def articlemeta_format(self): + from .sources.articlemeta_format import get_articlemeta_format_title + return get_articlemeta_format_title(self) + base_form_class = CoreAdminModelForm diff --git a/journal/sources/articlemeta_format.py b/journal/sources/articlemeta_format.py new file mode 100644 index 00000000..9ce7b69c --- /dev/null +++ b/journal/sources/articlemeta_format.py @@ -0,0 +1,168 @@ +from journal.models import SciELOJournal, TitleInDatabase +from journal.choices import STATUS +from core.utils.api_articlemeta_format import add_to_result, add_items + +def get_articlemeta_format_title(obj): + result = {} + scielo_journal = SciELOJournal.objects.filter( + journal=obj, collection__is_active=True + ).first() + publisher_history = obj.publisher_history.all() + + add_to_result( + "collection", + ( + scielo_journal.collection.acron3 + if scielo_journal and scielo_journal.collection + else None + ), result + ) + add_to_result("v5", obj.type_of_literature, result) + add_to_result("v6", obj.treatment_level, result) + add_to_result("v10", obj.center_code, result) + add_to_result("v20", obj.national_code, result) + add_to_result("v30", obj.identification_number, result) + + secs_code = TitleInDatabase.objects.filter( + journal=obj, indexed_at__acronym__iexact="secs" + ) + add_items("v37", [sc.identifier for sc in secs_code if sc.identifier], result) + add_to_result( + "v50", scielo_journal.status.lower() if scielo_journal.status else None, result + ) + add_items( + "v62", [ch.get_institution_name for ch in obj.copyright_holder_history.all()], result + ) + add_to_result("v66", obj.ftp, result) + add_to_result("v67", obj.user_subscription, result) + add_to_result( + "v68", + ( + scielo_journal.journal_acron + if scielo_journal and scielo_journal.journal_acron + else None + ), result + ) + add_to_result("v69", obj.journal_url, result) + add_to_result("v85", obj.vocabulary.acronym, result) + add_to_result("v110", obj.subtitle, result) + add_to_result( + "v117", obj.standard.code if obj.standard and obj.standard.code else None, result + ) + add_to_result("v130", obj.section, result) + add_items( + "v140", [sponsor.get_institution_name for sponsor in obj.sponsor_history.all()], result + ) + add_to_result("v150", obj.short_title, result) + add_to_result("v240", [other_title.title for other_title in obj.other_titles.all()], result) + + # Data of the object official + if obj.official: + add_to_result("v100", obj.title if obj.official.title else None, result) + add_to_result( + "v151", + obj.official.iso_short_title if obj.official.iso_short_title else None, + result + ) + add_items("v230", [pt.text for pt in obj.official.parallel_titles if pt.text], result) + add_to_result( + "v301", obj.official.initial_year if obj.official.initial_year else None, result + ) + add_to_result( + "v302", obj.official.initial_volume if obj.official.initial_volume else None, result + ) + add_to_result( + "v303", obj.official.initial_number if obj.official.initial_number else None, result + ) + + year = obj.official.terminate_year + month = obj.official.terminate_month + + if year and month: + add_to_result("v304", year + month, result) + elif year: + add_to_result("v304", year, result) + add_to_result( + "v305", obj.official.final_volume if obj.official.final_volume else None, result + ) + add_to_result( + "v306", + ( + obj.official.final_number + if obj.official and obj.official.final_number + else None + ), result + ) + + issns = [] + if obj.official.issn_print: + issns.append({"_": obj.official.issn_print, "t": "PRINT"}) + if obj.official.issn_electronic: + issns.append({"_": obj.official.issn_electronic, "t": "ONLIN"}) + result["435"] = issns + + if obj.official.old_title.all(): + add_items( + "v610", [old_title.title for old_title in obj.official.old_title.all()], result + ) + if obj.official.new_title: + add_to_result("v710", obj.official.new_title.title, result) + + if publisher_history: + add_items( + "v310", + [publisher.get_institution_country_name for publisher in publisher_history], + result + ) + add_items( + "v320", + [publisher.get_instition_state_acronym for publisher in publisher_history], + result + ) + add_items( + "v480", [publisher.get_institution_name for publisher in publisher_history], + result + ) + add_items( + "v490", + [publisher.get_institution_city_name for publisher in publisher_history], + result + ) + + add_to_result( + "v330", obj.level_of_publication if obj.level_of_publication else None, result + ) + add_to_result("v340", obj.alphabet if obj.alphabet else None, result) + add_items("v350", [lang.code2 for lang in obj.text_language.all()], result) + add_items("v360", [lang.code2 for lang in obj.abstract_language.all()], result) + add_to_result("v380", obj.frequency if obj.frequency else None, result) + + medline_titles = TitleInDatabase.objects.filter( + journal=obj, indexed_at__acronym__iexact="medline" + ) + add_items("v420", [medline.identifier for medline in medline_titles], result) + add_items("v421", [medline.title for medline in medline_titles], result) + add_to_result("v430", obj.classification, result) + + add_items("v440", [descriptor.value for descriptor in obj.subject_descriptor.all()], result) + add_items("v441", [subject.value for subject in obj.subject.all()], result) + add_items("v450", [index.name for index in obj.indexed_at.all()], result) + + add_to_result("v550", obj.has_supplement, result) + add_to_result("v560", obj.is_supplement, result) + + add_items("v900", [annotation.notes for annotation in obj.annotation.all()], result) + result["v901"] = ( + [ + {"l": mission.language.code2, "_": mission.get_text_pure} + for mission in obj.mission.all() + if mission.language and mission.get_text_pure + ] + if obj.mission + else None + ) + + add_to_result("v940", obj.created, result) + add_to_result("v941", obj.updated, result) + + return result