Skip to content

Commit

Permalink
Merge pull request #669 from bounswe/get-annotation-update
Browse files Browse the repository at this point in the history
Get annotation update
  • Loading branch information
hakanaktas0 authored Dec 22, 2023
2 parents b2c21ca + 2294a8d commit c44d425
Show file tree
Hide file tree
Showing 2 changed files with 111 additions and 26 deletions.
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

0 comments on commit c44d425

Please sign in to comment.