Skip to content

Commit

Permalink
Merge pull request #323 from RockefellerArchiveCenter/development
Browse files Browse the repository at this point in the history
Adds citation endpoint
  • Loading branch information
helrond authored Nov 26, 2024
2 parents a8187ea + dbf76aa commit 3d1ac3a
Show file tree
Hide file tree
Showing 6 changed files with 80 additions and 3 deletions.
26 changes: 25 additions & 1 deletion api_formatter/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from argo import settings

from .view_helpers import date_string
from .view_helpers import citation_title, date_string, flatten_ancestors
from .views import (AgentViewSet, CollectionViewSet, MyListView, ObjectViewSet,
SearchView, TermViewSet)

Expand Down Expand Up @@ -229,6 +229,14 @@ def minimap_view(self, pk):
for key in ["index", "uri", "title", "online"]:
self.assertIsNot(result.get(key), None)

def citation_view(self, basename, pk):
"""Asserts citation is generated."""
response = self.client.get(reverse(f"{basename}-citation", args=[pk])).json()
self.assertIsInstance(response, str)
self.assertIn(settings.CITATION_REPOSITORY_NAME, response)
self.assertIn(settings.CITATION_REPOSITORY_BASEURL, response)
self.assertIn(settings.CITATION_SEPARATOR, response)

def mylist_view(self, added_ids):
"""Asserts the MyList view returns the expected response status and results."""
list = random.sample(added_ids, 5)
Expand All @@ -253,6 +261,7 @@ def test_documents(self):
added_ids = self.index_fixture_data('fixtures/{}'.format(doc_type), doc_cls)
self.list_view(doc_cls, doc_type, viewset, len(added_ids))
for ident in added_ids:
self.citation_view(doc_type, ident)
self.detail_view(doc_type, viewset, ident)
if doc_type in ["collection", "object"]:
self.ancestors_view(doc_type, viewset, ident)
Expand Down Expand Up @@ -286,3 +295,18 @@ def test_date_string(self):
([{"begin": "1945"}, {"expression": "1950"}], "1945, 1950"),
([{"begin": "1945", "end": "1946"}, {"expression": "1950"}], "1945-1946, 1950")]:
self.assertEqual(date_string(input), expected)

def test_flatten_ancestors(self):
input = {"title": "top level", "child": {"title": "second level", "child": {"title": "third level"}}}
output = flatten_ancestors(input)
self.assertEqual(output, ["top level", "second level", "third level"])

def test_citation_title(self):
for input, expected in [
(["foo", "bar"], "foo, bar"),
(["foo", None], "foo"),
([None, "bar"], "bar"),
(["foo", "foo"], "foo"),
]:
output = citation_title(*input)
self.assertEqual(output, expected)
20 changes: 20 additions & 0 deletions api_formatter/view_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -188,3 +188,23 @@ def date_string(dates):

def description_from_notes(notes):
return text_from_notes(notes, "abstract") if text_from_notes(notes, "abstract") else text_from_notes(notes, "scopecontent")


def flatten_ancestors(ancestors):
ancestors_list = []
for key, value in ancestors.items():
if isinstance(value, dict):
ancestors_list += flatten_ancestors(value)
elif key == 'title':
ancestors_list.append(value)
return ancestors_list


def citation_title(title, date_string):
if all([title, date_string]):
if title != date_string:
return f"{title}, {date_string}"
else:
return date_string
else:
return [t for t in [title, date_string] if t][0]
27 changes: 25 additions & 2 deletions api_formatter/views.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.http import Http404
from django.urls import reverse
from django_elasticsearch_dsl_drf.constants import SUGGESTER_TERM
from django_elasticsearch_dsl_drf.pagination import LimitOffsetPagination
from elasticsearch_dsl import A, Q
Expand All @@ -23,8 +24,9 @@
NESTED_FILTER_FIELDS, NUMBER_LOOKUPS,
ORDERING_FIELDS, SEARCH_BACKENDS, SEARCH_FIELDS,
SEARCH_NESTED_FIELDS, STRING_LOOKUPS,
ChildrenPaginator, SearchMixin, date_string,
description_from_notes)
ChildrenPaginator, SearchMixin, citation_title,
date_string, description_from_notes,
flatten_ancestors)


class AncestorMixin(object):
Expand Down Expand Up @@ -199,6 +201,27 @@ def get_structured_query(self):
def list_fields(self):
return list(set(list(self.filter_fields) + list(self.ordering_fields) + list(self.search_fields) + ["type", "dates"]))

@action(detail=True)
def citation(self, request, pk):
"""Returns a citation for a document"""
resolved = self.resolve_object(self.document, pk, source_fields=["dates", "title"])
dates = date_string(resolved.to_dict().get("dates", []))
title = resolved.title
object_path = reverse('object-detail', kwargs={'pk': pk}).lstrip('/')
url = f"{settings.CITATION_REPOSITORY_BASEURL.rstrip('/')}/{object_path}"
ancestors = []
if getattr(self, 'ancestors', False):
ancestors = settings.CITATION_SEPARATOR.join(
flatten_ancestors(self.ancestors(request, pk).data)
)

citation = [
citation_title(title, dates),
ancestors,
settings.CITATION_REPOSITORY_NAME,
url]
return Response(settings.CITATION_SEPARATOR.join([c for c in citation if c]))


class AgentViewSet(DocumentViewSet):
"""
Expand Down
3 changes: 3 additions & 0 deletions argo/config.py.deploy
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ SQL_HOST = "${SQL_HOST}"
SQL_PORT = ${SQL_PORT}
USE_X_FORWARDED_HOST = ${USE_X_FORWARDED_HOST}
SECURE_PROXY_SSL_HEADER = ${SECURE_PROXY_SSL_HEADER}
CITATION_REPOSITORY_NAME = "${REPOSITORY_NAME}"
CITATION_REPOSITORY_BASEURL = "${REPOSITORY_BASEURL}"
CITATION_SEPARATOR = "${CITATION_SEPARATOR}"
3 changes: 3 additions & 0 deletions argo/config.py.example
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,6 @@ SQL_HOST = "argo-db" # host for the application database (string)
SQL_PORT = 5432 # port on which the application database can be reached (integer)
USE_X_FORWARDED_HOST = False # Set to True if the application is behind a reverse proxy (boolean)
SECURE_PROXY_SSL_HEADER = ("HTTP_X_FORWARDED_PROTO", "https") # If the application is being a reverse proxy, and if a header value indicates an HTTPS connection proxied over HTTP, name that header and value (tuple)
CITATION_REPOSITORY_NAME = "Rockefeller Archive Center" # name of repository used in citations
CITATION_REPOSITORY_BASEURL = "https://dimes.rockarch.org/" # base url for citation links
CITATION_SEPARATOR = "; " # string to separate different parts of the citation
4 changes: 4 additions & 0 deletions argo/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,7 @@
CSP_FONT_SRC = ("'self'", "https://assets.rockarch.org")
CSP_FRAME_SRC = ("'none'")
CSP_FRAME_ANCESTORS = ("'none'")

CITATION_REPOSITORY_NAME = config.CITATION_REPOSITORY_NAME
CITATION_REPOSITORY_BASEURL = config.CITATION_REPOSITORY_BASEURL
CITATION_SEPARATOR = config.CITATION_SEPARATOR

0 comments on commit 3d1ac3a

Please sign in to comment.