Loading oai/apps.py +2 −2 Original line number Diff line number Diff line Loading @@ -2,5 +2,5 @@ from django.apps import AppConfig class OaiConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'oai' default_auto_field = "django.db.models.BigAutoField" name = "oai" oai/views.py +59 −9 Original line number Diff line number Diff line Loading @@ -14,6 +14,19 @@ from django.core.paginator import Paginator PAGINATION_SIZE = 100 def _set_spec_to_collection(set_spec: str) -> Collection: try: last_id = int(set_spec.split(":")[-1]) collection = Collection.objects.get(pk=last_id) return collection except (ValueError, Collection.DoesNotExist): raise ValueError("no such collection") def _collection_to_set_spec(collection: Collection) -> str: return collection.oai_setspec() def _validate_date(in_date: str) -> bool: try: res = bool(datetime.strptime(in_date, "%Y-%m-%d")) Loading Loading @@ -74,7 +87,9 @@ def _get_record(owner: User, request: HttpRequest) -> HttpResponse: def _identify(owner: User, request: HttpRequest) -> HttpResponse: earliest_record = ( Collection.objects.filter(is_oai_record=True).order_by("created_at").first() Collection.objects.filter(is_oai_record=True, owner=owner) .order_by("created_at") .first() ) return HttpResponse( render_to_string( Loading Loading @@ -113,27 +128,56 @@ def _list_records( resumption_token = request.GET.get("resumptionToken") or request.POST.get( "resumptionToken" ) # # Get page number (ie. resumption token) # if resumption_token: try: page_number = abs(int(resumption_token)) except ValueError: pass from_date = request.GET.get("from") or request.POST.get("from") if not from_date: earliest_record = ( Collection.objects.filter(is_oai_record=True).order_by("created_at").first() ) from_date = earliest_record.created_at.strftime("%Y-%m-%d") if not _validate_date(from_date): # # Get from date # from_date = request.GET.get("from") or request.POST.get("until") if from_date and not _validate_date(from_date): return _oai_error(owner, request, {"badArgument": "bad from date format"}) # # Get until date # until_date = request.GET.get("until") or request.POST.get("until") if until_date and not _validate_date(until_date): return _oai_error(owner, request, {"badArgument": "bad until date format"}) # # Get setSpec collection # spec_collection = None set_spec = request.GET.get("set") or request.POST.get("set") if set_spec: spec_collection = _set_spec_to_collection(set_spec=set_spec) # # Build query # all_records = Collection.objects.filter( is_oai_record=True, created_at__gte=from_date is_oai_record=True, owner=owner, public_access=True ).order_by("created_at") if from_date: all_records = all_records.filter(created_at__gte=from_date) if until_date: all_records = all_records.filter(created_at__lte=until_date) if spec_collection: all_records = all_records.filter( parent__in=spec_collection.descendants_and_self_ids() ) # # Paginate, render. # total_count = all_records.count() if total_count == 0: return _oai_error(owner, request, {"noRecordsMatch": "no records match"}) Loading @@ -156,6 +200,7 @@ def _list_records( "total_pages": paginator.num_pages, "nb_of_already_delivered_identifiers": (page_number - 1) * PAGINATION_SIZE, "spec_collection": spec_collection, }, ), content_type="text/xml", Loading @@ -163,12 +208,16 @@ def _list_records( def _list_sets(owner: User, request: HttpRequest) -> HttpResponse: collections = Collection.objects.filter( owner=owner, is_oai_record=False, public_access=True ) return HttpResponse( render_to_string( "oai/list_sets.xml", { "owner": owner, "base_url": settings.JAMA_SITE, "collections": collections, }, ), content_type="text/xml", Loading Loading @@ -201,5 +250,6 @@ def oai(request: HttpRequest, owner_id: int) -> HttpResponse: return _list_records(owner, request) if oai_verb == "ListSets": return _list_sets(owner, request) # each user/owner has his own endpoint except User.DoesNotExist: raise Http404() resources/models.py +18 −0 Original line number Diff line number Diff line Loading @@ -335,6 +335,12 @@ class Collection(models.Model): """ return Resource.objects.raw(sql, [self.id]) def descendants_and_self_ids(self) -> List[int]: ids = [self.pk] for descendant in self.descendants(): ids.append(descendant.pk) return ids def descendants_count(self) -> int: with connection.cursor() as cursor: cursor.execute( Loading Loading @@ -448,6 +454,18 @@ class Collection(models.Model): except MetadataSet.DoesNotExist: return [] def oai_setspec(self) -> str: """ Get setSpec value for OAI-PMH xml. (see https://www.openarchives.org/OAI/openarchivesprotocol.html#Set) """ ids = [] ancestors = self.ancestors() for ancestor in ancestors[1:]: ids.append(str(ancestor.pk)) ids.append(str(self.pk)) return ":".join(ids) class MetadataCollectionValue(models.Model): metadata = models.ForeignKey(Metadata, on_delete=models.CASCADE) Loading templates/oai/list_identifiers.xml +6 −8 Original line number Diff line number Diff line Loading @@ -5,11 +5,9 @@ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd"> <responseDate>{% now "c" %}</responseDate> <request verb="ListIdentifiers" from="{{ from }}" {% if until %} until="{{ until }}" {% endif %} set="physics:hep" {% if from %}from="{{ from }}"{% endif %} {% if until %}until="{{ until }}"{% endif %} {% if spec_collection %}set="{{ spec_collection.oai_setspec }}"{% endif %} metadataPrefix="oai_dc"> {{ base_url }}oai/{{ owner.pk }} </request> Loading @@ -19,9 +17,9 @@ <header> <identifier>{{ collection.pk }}</identifier> <datestamp>{{ collection.created_at | date:"Y-m-d" }}</datestamp> {% for ancestor in collection.ancestors|slice:"1:" %} <setSpec>{{ ancestor.title }}</setSpec> {% endfor %} {% if collection.parent %} <setSpec>{{ collection.parent.oai_setspec }}</setSpec> {% endif %} </header> </record> {% endfor %} Loading templates/oai/list_records.xml +8 −4 Original line number Diff line number Diff line Loading @@ -5,11 +5,15 @@ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd"> <responseDate>{% now "c" %}</responseDate> <request verb="ListRecords" {% if from %} from="{{ from }}" {% endif %} {% if until %} until="{{ until }}" {% endif %} set="physics:hep" {% if spec_collection %} set="{{ spec_collection.oai_setspec }}" {% endif %} metadataPrefix="oai_dc"> {{ base_url }}oai/{{ owner.pk }} </request> Loading @@ -19,9 +23,9 @@ <header> <identifier>{{ collection.pk }}</identifier> <datestamp>{{ collection.created_at | date:"Y-m-d" }}</datestamp> {% for ancestor in collection.ancestors|slice:"1:" %} <setSpec>{{ ancestor.title }}</setSpec> {% endfor %} {% if collection.parent %} <setSpec>{{ collection.parent.oai_setspec }}</setSpec> {% endif %} </header> <metadata> <oai_dc:dc Loading Loading
oai/apps.py +2 −2 Original line number Diff line number Diff line Loading @@ -2,5 +2,5 @@ from django.apps import AppConfig class OaiConfig(AppConfig): default_auto_field = 'django.db.models.BigAutoField' name = 'oai' default_auto_field = "django.db.models.BigAutoField" name = "oai"
oai/views.py +59 −9 Original line number Diff line number Diff line Loading @@ -14,6 +14,19 @@ from django.core.paginator import Paginator PAGINATION_SIZE = 100 def _set_spec_to_collection(set_spec: str) -> Collection: try: last_id = int(set_spec.split(":")[-1]) collection = Collection.objects.get(pk=last_id) return collection except (ValueError, Collection.DoesNotExist): raise ValueError("no such collection") def _collection_to_set_spec(collection: Collection) -> str: return collection.oai_setspec() def _validate_date(in_date: str) -> bool: try: res = bool(datetime.strptime(in_date, "%Y-%m-%d")) Loading Loading @@ -74,7 +87,9 @@ def _get_record(owner: User, request: HttpRequest) -> HttpResponse: def _identify(owner: User, request: HttpRequest) -> HttpResponse: earliest_record = ( Collection.objects.filter(is_oai_record=True).order_by("created_at").first() Collection.objects.filter(is_oai_record=True, owner=owner) .order_by("created_at") .first() ) return HttpResponse( render_to_string( Loading Loading @@ -113,27 +128,56 @@ def _list_records( resumption_token = request.GET.get("resumptionToken") or request.POST.get( "resumptionToken" ) # # Get page number (ie. resumption token) # if resumption_token: try: page_number = abs(int(resumption_token)) except ValueError: pass from_date = request.GET.get("from") or request.POST.get("from") if not from_date: earliest_record = ( Collection.objects.filter(is_oai_record=True).order_by("created_at").first() ) from_date = earliest_record.created_at.strftime("%Y-%m-%d") if not _validate_date(from_date): # # Get from date # from_date = request.GET.get("from") or request.POST.get("until") if from_date and not _validate_date(from_date): return _oai_error(owner, request, {"badArgument": "bad from date format"}) # # Get until date # until_date = request.GET.get("until") or request.POST.get("until") if until_date and not _validate_date(until_date): return _oai_error(owner, request, {"badArgument": "bad until date format"}) # # Get setSpec collection # spec_collection = None set_spec = request.GET.get("set") or request.POST.get("set") if set_spec: spec_collection = _set_spec_to_collection(set_spec=set_spec) # # Build query # all_records = Collection.objects.filter( is_oai_record=True, created_at__gte=from_date is_oai_record=True, owner=owner, public_access=True ).order_by("created_at") if from_date: all_records = all_records.filter(created_at__gte=from_date) if until_date: all_records = all_records.filter(created_at__lte=until_date) if spec_collection: all_records = all_records.filter( parent__in=spec_collection.descendants_and_self_ids() ) # # Paginate, render. # total_count = all_records.count() if total_count == 0: return _oai_error(owner, request, {"noRecordsMatch": "no records match"}) Loading @@ -156,6 +200,7 @@ def _list_records( "total_pages": paginator.num_pages, "nb_of_already_delivered_identifiers": (page_number - 1) * PAGINATION_SIZE, "spec_collection": spec_collection, }, ), content_type="text/xml", Loading @@ -163,12 +208,16 @@ def _list_records( def _list_sets(owner: User, request: HttpRequest) -> HttpResponse: collections = Collection.objects.filter( owner=owner, is_oai_record=False, public_access=True ) return HttpResponse( render_to_string( "oai/list_sets.xml", { "owner": owner, "base_url": settings.JAMA_SITE, "collections": collections, }, ), content_type="text/xml", Loading Loading @@ -201,5 +250,6 @@ def oai(request: HttpRequest, owner_id: int) -> HttpResponse: return _list_records(owner, request) if oai_verb == "ListSets": return _list_sets(owner, request) # each user/owner has his own endpoint except User.DoesNotExist: raise Http404()
resources/models.py +18 −0 Original line number Diff line number Diff line Loading @@ -335,6 +335,12 @@ class Collection(models.Model): """ return Resource.objects.raw(sql, [self.id]) def descendants_and_self_ids(self) -> List[int]: ids = [self.pk] for descendant in self.descendants(): ids.append(descendant.pk) return ids def descendants_count(self) -> int: with connection.cursor() as cursor: cursor.execute( Loading Loading @@ -448,6 +454,18 @@ class Collection(models.Model): except MetadataSet.DoesNotExist: return [] def oai_setspec(self) -> str: """ Get setSpec value for OAI-PMH xml. (see https://www.openarchives.org/OAI/openarchivesprotocol.html#Set) """ ids = [] ancestors = self.ancestors() for ancestor in ancestors[1:]: ids.append(str(ancestor.pk)) ids.append(str(self.pk)) return ":".join(ids) class MetadataCollectionValue(models.Model): metadata = models.ForeignKey(Metadata, on_delete=models.CASCADE) Loading
templates/oai/list_identifiers.xml +6 −8 Original line number Diff line number Diff line Loading @@ -5,11 +5,9 @@ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd"> <responseDate>{% now "c" %}</responseDate> <request verb="ListIdentifiers" from="{{ from }}" {% if until %} until="{{ until }}" {% endif %} set="physics:hep" {% if from %}from="{{ from }}"{% endif %} {% if until %}until="{{ until }}"{% endif %} {% if spec_collection %}set="{{ spec_collection.oai_setspec }}"{% endif %} metadataPrefix="oai_dc"> {{ base_url }}oai/{{ owner.pk }} </request> Loading @@ -19,9 +17,9 @@ <header> <identifier>{{ collection.pk }}</identifier> <datestamp>{{ collection.created_at | date:"Y-m-d" }}</datestamp> {% for ancestor in collection.ancestors|slice:"1:" %} <setSpec>{{ ancestor.title }}</setSpec> {% endfor %} {% if collection.parent %} <setSpec>{{ collection.parent.oai_setspec }}</setSpec> {% endif %} </header> </record> {% endfor %} Loading
templates/oai/list_records.xml +8 −4 Original line number Diff line number Diff line Loading @@ -5,11 +5,15 @@ http://www.openarchives.org/OAI/2.0/OAI-PMH.xsd"> <responseDate>{% now "c" %}</responseDate> <request verb="ListRecords" {% if from %} from="{{ from }}" {% endif %} {% if until %} until="{{ until }}" {% endif %} set="physics:hep" {% if spec_collection %} set="{{ spec_collection.oai_setspec }}" {% endif %} metadataPrefix="oai_dc"> {{ base_url }}oai/{{ owner.pk }} </request> Loading @@ -19,9 +23,9 @@ <header> <identifier>{{ collection.pk }}</identifier> <datestamp>{{ collection.created_at | date:"Y-m-d" }}</datestamp> {% for ancestor in collection.ancestors|slice:"1:" %} <setSpec>{{ ancestor.title }}</setSpec> {% endfor %} {% if collection.parent %} <setSpec>{{ collection.parent.oai_setspec }}</setSpec> {% endif %} </header> <metadata> <oai_dc:dc Loading