Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Get annotation update #669

Merged
merged 3 commits into from
Dec 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 69 additions & 3 deletions project/annotation_project/annotations/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,25 @@ class AnnotationGetTest(TestCase):
def setUp(self):
source = Source.objects.create(uri='http://example.com/source1')
body = Body.objects.create(value='Annotation Test Content')
creator = Creator.objects.create(name='[email protected]')
creator = Creator.objects.create(name='http://13.51.205.39/profile/[email protected]')
selector = Selector.objects.create(start=0, end=5, source=source)
self.annotation = Annotation.objects.create(
body=body,
target=selector,
creator=creator,
created=datetime.now(),
)

source2 = Source.objects.create(uri='http://example.com/source2')
body2 = Body.objects.create(value='Annotation Test Content2')
creator2 = Creator.objects.create(name='http://13.51.205.39/profile/[email protected]')
selector2 = Selector.objects.create(start=0, end=5, source=source2)
self.annotation2 = Annotation.objects.create(
body=body2,
target=selector2,
creator=creator2,
created=datetime.now(),
)

def tearDown(self):
Annotation.objects.all().delete()
Expand All @@ -26,6 +37,61 @@ def tearDown(self):
Source.objects.all().delete()
print("All Annotation Get API Tests Completed")

#TODO: update matched annotations test

def test_get_matched_annotations(self):
client = Client()

url = reverse('get_annotation')
multicreator_data = {
'creator': [
'http://13.51.205.39/profile/[email protected]',
'http://13.51.205.39/profile/[email protected]']
}
multisource_data = {
'source' : [
'http://example.com/source1',
'http://example.com/source2'
]
}

data = {
'source' : 'http://example.com/source2',
'creator': 'http://13.51.205.39/profile/[email protected]'
}

response = client.get(url, multicreator_data, format='json')
self.assertEqual(response.status_code, 200, response.json())
self.assertEqual(len(response.json()), 2)

response = client.get(url, multisource_data, format='json')
self.assertEqual(response.status_code, 200, response.json())
self.assertEqual(len(response.json()), 2)

response = client.get(url, data, format='json')
self.assertEqual(response.status_code, 200, response.json())
response = response.json()[0]
self.assertEqual(response['@context'], 'http://www.w3.org/ns/anno.jsonld')
self.assertEqual(response['id'],f'http://13.51.55.11:8001/annotations/annotation/{self.annotation2.id}')
self.assertEqual(response['type'], self.annotation2.type)
self.assertEqual(response['body'], {
'type': self.annotation2.body.type,
'format': self.annotation2.body.format,
'language': self.annotation2.body.language,
'value': self.annotation2.body.value,
})
self.assertEqual(response['target'], {
'id': self.annotation2.target.source.uri,
'type': 'text',
'selector': {
'type': self.annotation2.target.type,
'start': self.annotation2.target.start,
'end': self.annotation2.target.end,
}
})
self.assertTrue(response['creator']['id'], self.annotation2.creator.name)
self.assertIn('created', response)

def test_get_annotation_by_id(self):
#Test the annotation response format
client = Client()
Expand Down Expand Up @@ -130,8 +196,8 @@ def test_create_annotation(self):
response = self.client.post(self.url, data=self.body_missing_creator, headers=self.headers)
self.assertEqual(response.status_code, 400, "Missing creator field test failed. expected 400, got " + str(response.status_code))

response = self.client.post(self.url, data=self.body, headers=self.headers, content_type='application/json')
self.assertEqual(response.status_code, 200, "Successful create annotation test failed. expected 200, got " + str(response.status_code))
response = self.client.post(self.url, data=self.body)
self.assertEqual(response.status_code, 201, "Successful create annotation test failed. expected 201, got " + str(response.status_code))

records = Annotation.objects.filter(id=response.json()['id'])
self.assertEqual(len(records), 1, "Successful create annotation test (database insertion) failed. expected 1 row, got " + str(len(records)))
Expand Down
65 changes: 42 additions & 23 deletions project/annotation_project/annotations/views.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
from django.http import JsonResponse
from django.views.decorators.csrf import csrf_exempt
from django.views.decorators.http import require_http_methods, etag
from django.views.decorators.vary import vary_on_headers
import json
import hashlib

from .models import *

Expand Down Expand Up @@ -31,41 +34,57 @@ def serialize_annotation(annotation):
'created': annotation.created,
}


@csrf_exempt
@require_http_methods(['GET', 'HEAD'])
@vary_on_headers('Accept')
def matched_annotations_get_view(request):
source_uri = request.GET.get('source')
creator_name = request.GET.get('creator')

source_uris = request.GET.getlist('source')
creator_names = request.GET.getlist('creator')
filtering_conditions = {}

if source_uri:
filtering_conditions['target__source__uri__iexact'] = source_uri
if creator_name:
filtering_conditions['creator__name__iexact'] = creator_name
if len(source_uris) > 0:
filtering_conditions['target__source__uri__in'] = source_uris
if len(creator_names) > 0:
filtering_conditions['creator__name__in'] = creator_names
try:
matched_annotations = Annotation.objects.filter(**filtering_conditions)
response = JsonResponse({'message': 'No annotation found!'}, status=404)
if len(matched_annotations) > 0:
matched_data = [
serialize_annotation(annotation) for annotation in matched_annotations
]
response = JsonResponse(matched_data, status=200, safe=False)
response['ETag'] = '"_{}"'.format(hashlib.md5(response.content).hexdigest())

if len(matched_annotations) == 0:
return JsonResponse({'message': 'No annotation found!'}, status=404)

matched_data = [
serialize_annotation(annotation) for annotation in matched_annotations
]

return JsonResponse(matched_data, status=200, safe=False)
except Exception as e:
return JsonResponse({'message': str(e)}, status=500)

response = JsonResponse({'message': str(e)}, status=500)
finally:
response.headers['Content-Type'] = 'application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"'
response.headers['Link'] = '<http://www.w3.org/ns/ldp#Resource>; rel="type"'
response['Allow'] = 'GET,OPTIONS,HEAD'
response['Vary'] = 'Accept'
return response

@csrf_exempt
@require_http_methods(['GET', 'HEAD'])
@vary_on_headers('Accept')
def get_annotation_by_id(request, annotation_id):
try:
annotation = Annotation.objects.get(id=annotation_id)
response = JsonResponse({'message': 'No annotation found!'}, status=404)
if annotation:
response_data = serialize_annotation(annotation)
response = JsonResponse(response_data, status=200)
response['ETag'] = '"_{}"'.format(hashlib.md5(response.content).hexdigest())

if not annotation:
return JsonResponse({'message': 'No annotation found!'}, status=404)
return JsonResponse(data = serialize_annotation(annotation), status=200)
except Exception as e:
return JsonResponse({'message': str(e)}, status=500)
response = JsonResponse({'message': str(e)}, status=500)
finally:
response.headers['Content-Type'] = 'application/ld+json; profile="http://www.w3.org/ns/anno.jsonld"'
response.headers['Link'] = '<http://www.w3.org/ns/ldp#Resource>; rel="type"'
response['Allow'] = 'GET,OPTIONS,HEAD'
response['Vary'] = 'Accept'
return response

@csrf_exempt
def create_annotation(request):
Expand Down Expand Up @@ -167,7 +186,7 @@ def create_annotation(request):

annotation_object.save()

return JsonResponse(data = serialize_annotation(annotation_object), status=200)
return JsonResponse(data = serialize_annotation(annotation_object), status=201)
except Exception as e:
if "duplicate key value violates unique constraint" in str(e):
return JsonResponse({'message': 'Annotation already exists!'}, status=400)
Expand Down