Commit 2838dba1 by Arthur Barrett

fix pep8 violations

parent dd583ce4
......@@ -28,6 +28,7 @@ API_SETTINGS = {
#----------------------------------------------------------------------#
# API requests are routed through api_request() using the resource map.
def api_enabled(request, course_id):
'''
Returns True if the api is enabled for the course, otherwise False.
......@@ -35,6 +36,7 @@ def api_enabled(request, course_id):
course = _get_course(request, course_id)
return notes_enabled_for_course(course)
@login_required
def api_request(request, course_id, **kwargs):
'''
......@@ -86,6 +88,7 @@ def api_request(request, course_id, **kwargs):
return response
def api_format(request, response, data):
'''
Returns a two-element list containing the content type and content.
......@@ -97,6 +100,7 @@ def api_format(request, response, data):
content = json.dumps(data)
return [content_type, content]
def _get_course(request, course_id):
'''
Helper function to load and return a user's course.
......@@ -106,6 +110,7 @@ def _get_course(request, course_id):
#----------------------------------------------------------------------#
# API actions exposed via the resource map.
def index(request, course_id):
'''
Returns a list of annotation objects.
......@@ -117,6 +122,7 @@ def index(request, course_id):
return [HttpResponse(), [note.as_dict() for note in notes]]
def create(request, course_id):
'''
Receives an annotation object to create and returns a 303 with the read location.
......@@ -135,6 +141,7 @@ def create(request, course_id):
return [response, None]
def read(request, course_id, note_id):
'''
Returns a single annotation object.
......@@ -149,6 +156,7 @@ def read(request, course_id, note_id):
return [HttpResponse(), note.as_dict()]
def update(request, course_id, note_id):
'''
Updates an annotation object and returns a 303 with the read location.
......@@ -174,6 +182,7 @@ def update(request, course_id, note_id):
return [response, None]
def delete(request, course_id, note_id):
'''
Deletes the annotation object and returns a 204 with no content.
......@@ -190,6 +199,7 @@ def delete(request, course_id, note_id):
return [HttpResponse('', status=204), None]
def search(request, course_id):
'''
Returns a subset of annotation objects based on a search query.
......@@ -222,7 +232,7 @@ def search(request, course_id):
# retrieve notes
notes = Note.objects.order_by('id').filter(**filters)
total = notes.count()
rows = notes[offset:offset+limit]
rows = notes[offset:offset + limit]
result = {
'total': total,
'rows': [note.as_dict() for note in rows]
......@@ -230,6 +240,7 @@ def search(request, course_id):
return [HttpResponse(), result]
def root(request, course_id):
'''
Returns version information about the API.
......
......@@ -2,12 +2,12 @@ from django.db import models
from django.contrib.auth.models import User
from django.core.urlresolvers import reverse
from django.core.exceptions import ValidationError
import json
import logging
log = logging.getLogger(__name__)
class Note(models.Model):
user = models.ForeignKey(User, db_index=True)
course_id = models.CharField(max_length=255, db_index=True)
......
......@@ -14,6 +14,7 @@ import logging
from . import utils, api, models
class UtilsTest(TestCase):
def setUp(self):
'''
......@@ -35,13 +36,13 @@ class UtilsTest(TestCase):
Tests that notes are enabled when the course tab configuration contains
a tab with type "notes."
'''
self.course.tabs = [
{'type': 'foo'},
self.course.tabs = [{'type': 'foo'},
{'name': 'My Notes', 'type': 'notes'},
{'type':'bar'}]
{'type': 'bar'}]
self.assertTrue(utils.notes_enabled_for_course(self.course))
class ApiTest(TestCase):
def setUp(self):
......@@ -57,16 +58,16 @@ class ApiTest(TestCase):
self.instructor = User.objects.create_user('instructor', 'instructor@test.com', self.password)
self.course_id = 'HarvardX/CB22x/The_Ancient_Greek_Hero'
self.note = {
'user':self.student,
'course_id':self.course_id,
'uri':'/',
'text':'foo',
'quote':'bar',
'range_start':0,
'range_start_offset':0,
'range_end':100,
'range_end_offset':0,
'tags':'a,b,c'
'user': self.student,
'course_id': self.course_id,
'uri': '/',
'text': 'foo',
'quote': 'bar',
'range_start': 0,
'range_start_offset': 0,
'range_end': 100,
'range_end_offset': 0,
'tags': 'a,b,c'
}
def mock_api_enabled(self, is_enabled):
......@@ -84,7 +85,7 @@ class ApiTest(TestCase):
self.client.login(username=username, password=password)
def url(self, name, args={}):
args.update({'course_id':self.course_id})
args.update({'course_id': self.course_id})
return reverse(name, kwargs=args)
def create_notes(self, num_notes, create=True):
......@@ -105,7 +106,7 @@ class ApiTest(TestCase):
content = json.loads(resp.content)
self.assertEqual(set(('name','version')), set(content.keys()))
self.assertEqual(set(('name', 'version')), set(content.keys()))
self.assertIsInstance(content['version'], int)
self.assertEqual(content['name'], 'Notes API')
......@@ -155,9 +156,10 @@ class ApiTest(TestCase):
note_dict = notes[0].as_dict()
excluded_fields = ['id', 'user_id', 'created', 'updated']
note = dict([(k, v) for k,v in note_dict.items() if k not in excluded_fields])
note = dict([(k, v) for k, v in note_dict.items() if k not in excluded_fields])
resp = self.client.post(self.url('notes_api_notes'), json.dumps(note),
resp = self.client.post(self.url('notes_api_notes'),
json.dumps(note),
content_type='application/json',
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
......@@ -168,7 +170,8 @@ class ApiTest(TestCase):
self.login()
for empty_test in [None, [], '']:
resp = self.client.post(self.url('notes_api_notes'), json.dumps(empty_test),
resp = self.client.post(self.url('notes_api_notes'),
json.dumps(empty_test),
content_type='application/json',
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertEqual(resp.status_code, 500)
......@@ -181,9 +184,10 @@ class ApiTest(TestCase):
note_dict = notes[0].as_dict()
excluded_fields = ['id', 'user_id', 'created', 'updated'] + ['ranges']
note = dict([(k, v) for k,v in note_dict.items() if k not in excluded_fields])
note = dict([(k, v) for k, v in note_dict.items() if k not in excluded_fields])
resp = self.client.post(self.url('notes_api_notes'), json.dumps(note),
resp = self.client.post(self.url('notes_api_notes'),
json.dumps(note),
content_type='application/json',
HTTP_X_REQUESTED_WITH='XMLHttpRequest')
self.assertEqual(resp.status_code, 500)
......@@ -220,12 +224,14 @@ class ApiTest(TestCase):
# set the student id to a different student (not the one that created the notes)
self.login(as_student=self.student2)
resp = self.client.get(self.url('notes_api_note', { 'note_id': note.id}))
resp = self.client.get(self.url('notes_api_note', {'note_id': note.id}))
self.assertEqual(resp.status_code, 403)
self.assertEqual(resp.content, '')
@unittest.skip("skipping update test stub")
def test_update_note(self): pass
def test_update_note(self):
pass
@unittest.skip("skipping search test stub")
def test_search_note(self): pass
def test_search_note(self):
pass
from django.conf.urls import patterns, url
id_regex = r"(?P<note_id>[0-9A-Fa-f]+)"
urlpatterns = patterns('notes.api',
url(r'^api$', 'api_request', {'resource':'root'}, name='notes_api_root'),
url(r'^api/annotations$', 'api_request', {'resource':'notes'}, name='notes_api_notes'),
url(r'^api/annotations/' + id_regex + r'$', 'api_request', {'resource':'note'}, name='notes_api_note'),
url(r'^api/search', 'api_request', {'resource':'search'}, name='notes_api_search')
)
url(r'^api$', 'api_request', {'resource': 'root'}, name='notes_api_root'),
url(r'^api/annotations$', 'api_request', {'resource': 'notes'}, name='notes_api_notes'),
url(r'^api/annotations/' + id_regex + r'$', 'api_request', {'resource': 'note'}, name='notes_api_note'),
url(r'^api/search', 'api_request', {'resource': 'search'}, name='notes_api_search')
)
from django.conf import settings
def notes_enabled_for_course(course):
'''
Returns True if the notes app is enabled for the course, False otherwise.
In order for the app to be enabled it must be:
1) enabled globally via MITX_FEATURES.
2) present in the course tab configuration.
'''
# TODO: create a separate policy setting to enable/disable notes
tab_type = 'notes'
tabs = course.tabs
tab_found = next((True for t in tabs if t['type'] == tab_type), False)
return tab_found
tab_found = next((True for t in course.tabs if t['type'] == 'notes'), False)
feature_enabled = settings.MITX_FEATURES.get('ENABLE_STUDENT_NOTES')
return feature_enabled and tab_found
......@@ -6,6 +6,7 @@ from notes.models import Note
from notes.utils import notes_enabled_for_course
import json
@login_required
def notes(request, course_id):
''' Displays the student's notes. '''
......
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