Commit 1e2e4a40 by Oleg Marshev

Fix quality.

parent 53acb6b7
...@@ -6,14 +6,18 @@ from notesapi.v1.models import NoteMappingType ...@@ -6,14 +6,18 @@ from notesapi.v1.models import NoteMappingType
class Command(BaseCommand): class Command(BaseCommand):
"""
Indexing and mapping commands.
"""
help = 'Creates index and the mapping.' help = 'Creates index and the mapping.'
option_list = BaseCommand.option_list + ( option_list = BaseCommand.option_list + (
make_option('--drop', make_option(
'--drop',
action='store_true', action='store_true',
dest='drop', dest='drop',
default=False, default=False,
help='Recreate index'), help='Recreate index'),
) )
def handle(self, *args, **options): def handle(self, *args, **options):
if options['drop']: if options['drop']:
......
...@@ -6,7 +6,11 @@ from django.db.models import signals ...@@ -6,7 +6,11 @@ from django.db.models import signals
from django.dispatch import receiver from django.dispatch import receiver
from elasticutils.contrib.django import Indexable, MappingType, get_es from elasticutils.contrib.django import Indexable, MappingType, get_es
class Note(models.Model): class Note(models.Model):
"""
Annotation model.
"""
user_id = models.CharField(max_length=255) user_id = models.CharField(max_length=255)
course_id = models.CharField(max_length=255) course_id = models.CharField(max_length=255)
usage_id = models.CharField(max_length=255) usage_id = models.CharField(max_length=255)
...@@ -16,7 +20,6 @@ class Note(models.Model): ...@@ -16,7 +20,6 @@ class Note(models.Model):
created = models.DateTimeField(auto_now_add=True) created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True) updated = models.DateTimeField(auto_now=True)
def clean(self, note): def clean(self, note):
""" """
Clean the note object or raises a ValidationError. Clean the note object or raises a ValidationError.
...@@ -64,16 +67,15 @@ class Note(models.Model): ...@@ -64,16 +67,15 @@ class Note(models.Model):
} }
@receiver(signals.post_save, sender=Note) @receiver(signals.post_save, sender=Note)
def update_in_index(sender, instance, **kw): def update_in_index(sender, instance, **kwargs):
if settings.ES_DISABLED: if settings.ES_DISABLED:
return return
NoteMappingType.index(instance.as_dict(), id_=instance.id, overwrite_existing=True) NoteMappingType.index(instance.as_dict(), id_=instance.id, overwrite_existing=True)
@receiver(signals.post_delete, sender=Note) @receiver(signals.post_delete, sender=Note)
def delete_in_index(sender, instance, **kw): def delete_in_index(sender, instance, **kwargs):
if settings.ES_DISABLED: if settings.ES_DISABLED:
return return
NoteMappingType.unindex(id_=instance.id) NoteMappingType.unindex(id_=instance.id)
......
...@@ -57,4 +57,4 @@ class HasAccessToken(BasePermission): ...@@ -57,4 +57,4 @@ class HasAccessToken(BasePermission):
logger.debug("Could not decode token {}".format(token)) logger.debug("Could not decode token {}".format(token))
except TokenWrongIssuer: except TokenWrongIssuer:
logger.debug("Token has wrong issuer {}".format(token)) logger.debug("Token has wrong issuer {}".format(token))
return False return False
\ No newline at end of file
import json
from unittest import TestCase from unittest import TestCase
from notesapi.v1.models import Note, NoteMappingType from notesapi.v1.models import Note, NoteMappingType
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
......
...@@ -3,7 +3,6 @@ import jwt ...@@ -3,7 +3,6 @@ import jwt
from calendar import timegm from calendar import timegm
from datetime import datetime, timedelta from datetime import datetime, timedelta
from mock import patch from mock import patch
import unittest
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.conf import settings from django.conf import settings
...@@ -143,7 +142,6 @@ class AnnotationViewTests(BaseAnnotationViewTests): ...@@ -143,7 +142,6 @@ class AnnotationViewTests(BaseAnnotationViewTests):
annotation = self._get_annotation(response.data['id']) annotation = self._get_annotation(response.data['id'])
self.assertNotEqual(annotation['created'], 'abc', "annotation 'created' field should not be used by API") self.assertNotEqual(annotation['created'], 'abc', "annotation 'created' field should not be used by API")
def test_create_ignore_updated(self): def test_create_ignore_updated(self):
""" """
Test if annotation 'updated' field is not used by API. Test if annotation 'updated' field is not used by API.
...@@ -193,18 +191,21 @@ class AnnotationViewTests(BaseAnnotationViewTests): ...@@ -193,18 +191,21 @@ class AnnotationViewTests(BaseAnnotationViewTests):
Create a note that has several ranges and read it Create a note that has several ranges and read it
""" """
note = self.payload.copy() note = self.payload.copy()
ranges = [{ ranges = [
"start": "/p[1]", {
"end": "/p[1]", "start": "/p[1]",
"startOffset": 0, "end": "/p[1]",
"endOffset": 10, "startOffset": 0,
}, { "endOffset": 10,
"start": "/p[2]", },
"end": "/p[2]", {
"startOffset": 20, "start": "/p[2]",
"endOffset": 22, "end": "/p[2]",
} "startOffset": 20,
] "endOffset": 22,
}
]
note['ranges'] = ranges note['ranges'] = ranges
note_id = self._create_annotation(**note)['id'] note_id = self._create_annotation(**note)['id']
...@@ -226,7 +227,6 @@ class AnnotationViewTests(BaseAnnotationViewTests): ...@@ -226,7 +227,6 @@ class AnnotationViewTests(BaseAnnotationViewTests):
response = self.client.get(url, self.headers) response = self.client.get(url, self.headers)
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND, "response should be 404 NOT FOUND") self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND, "response should be 404 NOT FOUND")
def test_update(self): def test_update(self):
""" """
Ensure we can update an existing annotation. Ensure we can update an existing annotation.
...@@ -315,9 +315,9 @@ class AnnotationViewTests(BaseAnnotationViewTests): ...@@ -315,9 +315,9 @@ class AnnotationViewTests(BaseAnnotationViewTests):
""" """
Tests for search method. Tests for search method.
""" """
note_1 = self._create_annotation(text=u'First one') self._create_annotation(text=u'First one')
note_2 = self._create_annotation(text=u'Second note') self._create_annotation(text=u'Second note')
note_3 = self._create_annotation(text=u'Third note') self._create_annotation(text=u'Third note')
results = self._get_search_results() results = self._get_search_results()
self.assertEqual(results['total'], 3) self.assertEqual(results['total'], 3)
......
from django.conf.urls import patterns, url from django.conf.urls import patterns, url
from django.views.generic import RedirectView
from django.core.urlresolvers import reverse_lazy
from notesapi.v1.views import AnnotationListView, AnnotationDetailView, AnnotationSearchView from notesapi.v1.views import AnnotationListView, AnnotationDetailView, AnnotationSearchView
urlpatterns = patterns( urlpatterns = patterns(
'', '',
url(r'^annotations/$', AnnotationListView.as_view(), name='annotations'), url(r'^annotations/$', AnnotationListView.as_view(), name='annotations'),
url(r'^annotations/(?P<annotation_id>[a-zA-Z0-9_-]+)/?$', AnnotationDetailView.as_view(), name='annotations_detail'), url(
r'^annotations/(?P<annotation_id>[a-zA-Z0-9_-]+)/?$',
AnnotationDetailView.as_view(),
name='annotations_detail'
),
url(r'^search/$', AnnotationSearchView.as_view(), name='annotations_search'), url(r'^search/$', AnnotationSearchView.as_view(), name='annotations_search'),
) )
import logging import logging
from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
...@@ -27,6 +26,7 @@ class AnnotationSearchView(APIView): ...@@ -27,6 +26,7 @@ class AnnotationSearchView(APIView):
if field in params: if field in params:
params[field + "__match"] = params[field] params[field + "__match"] = params[field]
del params[field] del params[field]
if params.get('highlight'): if params.get('highlight'):
# Currently we do not use highlight_class and highlight_tag in service. # Currently we do not use highlight_class and highlight_tag in service.
...@@ -35,14 +35,15 @@ class AnnotationSearchView(APIView): ...@@ -35,14 +35,15 @@ class AnnotationSearchView(APIView):
results = NoteMappingType.process_result( results = NoteMappingType.process_result(
list( list(
note_searcher.query(**params).order_by("-created").values_dict("_source") \ note_searcher.query(**params).order_by("-created").values_dict("_source")
.highlight("text", pre_tags=['<span>'], post_tags=['</span>']) .highlight("text", pre_tags=['<span>'], post_tags=['</span>'])
) )
) )
else: else:
results = NoteMappingType.process_result( results = NoteMappingType.process_result(
list(note_searcher.query(**params).order_by("-created").values_dict("_source")) list(note_searcher.query(**params).order_by("-created").values_dict("_source"))
) )
return Response({'total': len(results), 'rows': results}) return Response({'total': len(results), 'rows': results})
......
...@@ -5,6 +5,7 @@ from django.core.urlresolvers import reverse ...@@ -5,6 +5,7 @@ from django.core.urlresolvers import reverse
from rest_framework.test import APITestCase from rest_framework.test import APITestCase
from elasticsearch.exceptions import TransportError from elasticsearch.exceptions import TransportError
class OperationalEndpointsTest(APITestCase): class OperationalEndpointsTest(APITestCase):
""" """
Tests for operational endpoints. Tests for operational endpoints.
...@@ -41,6 +42,7 @@ class OperationalEndpointsTest(APITestCase): ...@@ -41,6 +42,7 @@ class OperationalEndpointsTest(APITestCase):
} }
) )
class OperationalAuthEndpointsTest(APITestCase): class OperationalAuthEndpointsTest(APITestCase):
""" """
Tests for operational authenticated endpoints. Tests for operational authenticated endpoints.
......
...@@ -3,8 +3,7 @@ import datetime ...@@ -3,8 +3,7 @@ import datetime
from rest_framework import status from rest_framework import status
from rest_framework.permissions import AllowAny from rest_framework.permissions import AllowAny
from rest_framework.response import Response from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.decorators import api_view, permission_classes
from rest_framework.decorators import api_view, permission_classes, authentication_classes
from elasticsearch.exceptions import TransportError from elasticsearch.exceptions import TransportError
from elasticutils import get_es from elasticutils import get_es
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment