From 3ed4198204e7a062f47a25d9be915c40ecaf33fd Mon Sep 17 00:00:00 2001 From: Julian Arni Date: Wed, 14 Aug 2013 19:10:00 -0400 Subject: [PATCH] Contentstore views pylint fixes --- cms/djangoapps/contentstore/views/access.py | 10 +- cms/djangoapps/contentstore/views/assets.py | 71 +++--- .../contentstore/views/checklist.py | 15 +- .../contentstore/views/component.py | 165 +++++++++----- cms/djangoapps/contentstore/views/course.py | 204 ++++++++++++------ 5 files changed, 305 insertions(+), 160 deletions(-) diff --git a/cms/djangoapps/contentstore/views/access.py b/cms/djangoapps/contentstore/views/access.py index 49ce0c8733..5cb6b8c6f4 100644 --- a/cms/djangoapps/contentstore/views/access.py +++ b/cms/djangoapps/contentstore/views/access.py @@ -26,12 +26,16 @@ def has_access(user, location, role=STAFF_ROLE_NAME): There is a super-admin permissions if user.is_staff is set Also, since we're unifying the user database between LMS and CAS, I'm presuming that the course instructor (formally known as admin) - will not be in both INSTRUCTOR and STAFF groups, so we have to cascade our queries here as INSTRUCTOR - has all the rights that STAFF do + will not be in both INSTRUCTOR and STAFF groups, so we have to cascade our + queries here as INSTRUCTOR has all the rights that STAFF do ''' course_location = get_course_location_for_item(location) _has_access = is_user_in_course_group_role(user, course_location, role) # if we're not in STAFF, perhaps we're in INSTRUCTOR groups if not _has_access and role == STAFF_ROLE_NAME: - _has_access = is_user_in_course_group_role(user, course_location, INSTRUCTOR_ROLE_NAME) + _has_access = is_user_in_course_group_role( + user, + course_location, + INSTRUCTOR_ROLE_NAME + ) return _has_access diff --git a/cms/djangoapps/contentstore/views/assets.py b/cms/djangoapps/contentstore/views/assets.py index 94bfa55b58..ede6939398 100644 --- a/cms/djangoapps/contentstore/views/assets.py +++ b/cms/djangoapps/contentstore/views/assets.py @@ -4,6 +4,7 @@ import os import tarfile import shutil import cgi +from functools import partial from tempfile import mkdtemp from path import path @@ -34,7 +35,8 @@ from .access import get_location_and_verify_access from util.json_request import JsonResponse -__all__ = ['asset_index', 'upload_asset', 'import_course', 'generate_export_course', 'export_course'] +__all__ = ['asset_index', 'upload_asset', 'import_course', + 'generate_export_course', 'export_course'] def assets_to_json_dict(assets): @@ -58,13 +60,14 @@ def assets_to_json_dict(assets): obj["thumbnail"] = thumbnail id_info = asset.get("_id") if id_info: - obj["id"] = "/{tag}/{org}/{course}/{revision}/{category}/{name}".format( - org=id_info.get("org", ""), - course=id_info.get("course", ""), - revision=id_info.get("revision", ""), - tag=id_info.get("tag", ""), - category=id_info.get("category", ""), - name=id_info.get("name", ""), + obj["id"] = "/{tag}/{org}/{course}/{revision}/{category}/{name}" \ + .format( + org=id_info.get("org", ""), + course=id_info.get("course", ""), + revision=id_info.get("revision", ""), + tag=id_info.get("tag", ""), + category=id_info.get("category", ""), + name=id_info.get("name", ""), ) ret.append(obj) return ret @@ -132,14 +135,14 @@ def asset_index(request, org, course, name): @login_required def upload_asset(request, org, course, coursename): ''' - This method allows for POST uploading of files into the course asset library, which will - be supported by GridFS in MongoDB. + This method allows for POST uploading of files into the course asset + library, which will be supported by GridFS in MongoDB. ''' # construct a location from the passed in path location = get_location_and_verify_access(request, org, course, coursename) - # Does the course actually exist?!? Get anything from it to prove its existance - + # Does the course actually exist?!? Get anything from it to prove its + # existence try: modulestore().get_item(location) except: @@ -150,9 +153,10 @@ def upload_asset(request, org, course, coursename): if 'file' not in request.FILES: return HttpResponseBadRequest() - # compute a 'filename' which is similar to the location formatting, we're using the 'filename' - # nomenclature since we're using a FileSystem paradigm here. We're just imposing - # the Location string formatting expectations to keep things a bit more consistent + # compute a 'filename' which is similar to the location formatting, we're + # using the 'filename' nomenclature since we're using a FileSystem paradigm + # here. We're just imposing the Location string formatting expectations to + # keep things a bit more consistent upload_file = request.FILES['file'] filename = upload_file.name mime_type = upload_file.content_type @@ -160,20 +164,25 @@ def upload_asset(request, org, course, coursename): content_loc = StaticContent.compute_location(org, course, filename) chunked = upload_file.multiple_chunks() + sc_partial = partial(StaticContent, content_loc, filename, mime_type) if chunked: - content = StaticContent(content_loc, filename, mime_type, upload_file.chunks()) + content = sc_partial(upload_file.chunks()) + temp_filepath = upload_file.temporary_file_path() else: - content = StaticContent(content_loc, filename, mime_type, upload_file.read()) + content = sc_partial(upload_file.read()) + tempfile_path = None thumbnail_content = None thumbnail_location = None # first let's see if a thumbnail can be created - (thumbnail_content, thumbnail_location) = contentstore().generate_thumbnail(content, - tempfile_path=None if not chunked else - upload_file.temporary_file_path()) + (thumbnail_content, thumbnail_location) = contentstore().generate_thumbnail( + content, + tempfile_path=tempfile_path + ) - # delete cached thumbnail even if one couldn't be created this time (else the old thumbnail will continue to show) + # delete cached thumbnail even if one couldn't be created this time (else + # the old thumbnail will continue to show) del_cached_content(thumbnail_location) # now store thumbnail location only if we could create it if thumbnail_content is not None: @@ -186,13 +195,15 @@ def upload_asset(request, org, course, coursename): # readback the saved content - we need the database timestamp readback = contentstore().find(content.location) - response_payload = {'displayname': content.name, - 'uploadDate': get_default_time_display(readback.last_modified_at), - 'url': StaticContent.get_url_path_from_location(content.location), - 'portable_url': StaticContent.get_static_path_from_location(content.location), - 'thumb_url': StaticContent.get_url_path_from_location(thumbnail_location) if thumbnail_content is not None else None, - 'msg': 'Upload completed' - } + response_payload = { + 'displayname': content.name, + 'uploadDate': get_default_time_display(readback.last_modified_at), + 'url': StaticContent.get_url_path_from_location(content.location), + 'portable_url': StaticContent.get_static_path_from_location(content.location), + 'thumb_url': StaticContent.get_url_path_from_location(thumbnail_location) + if thumbnail_content is not None else None, + 'msg': 'Upload completed' + } response = JsonResponse(response_payload) return response @@ -202,8 +213,8 @@ def upload_asset(request, org, course, coursename): @login_required def remove_asset(request, org, course, name): ''' - This method will perform a 'soft-delete' of an asset, which is basically to copy the asset from - the main GridFS collection and into a Trashcan + This method will perform a 'soft-delete' of an asset, which is basically to + copy the asset from the main GridFS collection and into a Trashcan ''' get_location_and_verify_access(request, org, course, name) diff --git a/cms/djangoapps/contentstore/views/checklist.py b/cms/djangoapps/contentstore/views/checklist.py index 74f0a33769..030aa70693 100644 --- a/cms/djangoapps/contentstore/views/checklist.py +++ b/cms/djangoapps/contentstore/views/checklist.py @@ -30,7 +30,8 @@ def get_checklists(request, org, course, name): modulestore = get_modulestore(location) course_module = modulestore.get_item(location) - # If course was created before checklists were introduced, copy them over from the template. + # If course was created before checklists were introduced, copy them over + # from the template. copied = False if not course_module.checklists: course_module.checklists = CourseDescriptor.checklists.default @@ -68,7 +69,8 @@ def update_checklist(request, org, course, name, checklist_index=None): if checklist_index is not None and 0 <= int(checklist_index) < len(course_module.checklists): index = int(checklist_index) course_module.checklists[index] = json.loads(request.body) - # seeming noop which triggers kvs to record that the metadata is not default + # seeming noop which triggers kvs to record that the metadata is + # not default course_module.checklists = course_module.checklists checklists, _ = expand_checklist_action_urls(course_module) course_module.save() @@ -76,10 +78,13 @@ def update_checklist(request, org, course, name, checklist_index=None): return JsonResponse(checklists[index]) else: return HttpResponseBadRequest( - "Could not save checklist state because the checklist index was out of range or unspecified.", - content_type="text/plain") + ( "Could not save checklist state because the checklist index " + "was out of range or unspecified."), + content_type="text/plain" + ) elif request.method == 'GET': - # In the JavaScript view initialize method, we do a fetch to get all the checklists. + # In the JavaScript view initialize method, we do a fetch to get all + # the checklists. checklists, modified = expand_checklist_action_urls(course_module) if modified: course_module.save() diff --git a/cms/djangoapps/contentstore/views/component.py b/cms/djangoapps/contentstore/views/component.py index d7b41acb24..292bc841ff 100644 --- a/cms/djangoapps/contentstore/views/component.py +++ b/cms/djangoapps/contentstore/views/component.py @@ -2,7 +2,8 @@ import json import logging from collections import defaultdict -from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden +from django.http import HttpResponse, HttpResponseBadRequest, \ + HttpResponseForbidden from django.contrib.auth.decorators import login_required from django.views.decorators.http import require_http_methods from django.core.exceptions import PermissionDenied @@ -72,10 +73,15 @@ def edit_subsection(request, location): except ItemNotFoundError: return HttpResponseBadRequest() - lms_link = get_lms_link_for_item(location, course_id=course.location.course_id) - preview_link = get_lms_link_for_item(location, course_id=course.location.course_id, preview=True) + lms_link = get_lms_link_for_item( + location, course_id=course.location.course_id + ) + preview_link = get_lms_link_for_item( + location, course_id=course.location.course_id, preview=True + ) - # make sure that location references a 'sequential', otherwise return BadRequest + # make sure that location references a 'sequential', otherwise return + # BadRequest if item.location.category != 'sequential': return HttpResponseBadRequest() @@ -83,18 +89,22 @@ def edit_subsection(request, location): # we're for now assuming a single parent if len(parent_locs) != 1: - logging.error('Multiple (or none) parents have been found for {0}'.format(location)) + logging.error( + 'Multiple (or none) parents have been found for' + location + ) # this should blow up if we don't find any parents, which would be erroneous parent = modulestore().get_item(parent_locs[0]) - # remove all metadata from the generic dictionary that is presented in a more normalized UI + # remove all metadata from the generic dictionary that is presented in a + # more normalized UI policy_metadata = dict( (field.name, field.read_from(item)) for field in item.fields - if field.name not in ['display_name', 'start', 'due', 'format'] and field.scope == Scope.settings + if field.name not in ['display_name', 'start', 'due', 'format'] + and field.scope == Scope.settings ) can_view_live = False @@ -105,19 +115,22 @@ def edit_subsection(request, location): can_view_live = True break - return render_to_response('edit_subsection.html', - {'subsection': item, - 'context_course': course, - 'new_unit_category': 'vertical', - 'lms_link': lms_link, - 'preview_link': preview_link, - 'course_graders': json.dumps(CourseGradingModel.fetch(course.location).graders), - 'parent_location': course.location, - 'parent_item': parent, - 'policy_metadata': policy_metadata, - 'subsection_units': subsection_units, - 'can_view_live': can_view_live - }) + return render_to_response( + 'edit_subsection.html', + { + 'subsection': item, + 'context_course': course, + 'new_unit_category': 'vertical', + 'lms_link': lms_link, + 'preview_link': preview_link, + 'course_graders': json.dumps(CourseGradingModel.fetch(course.location).graders), + 'parent_location': course.location, + 'parent_item': parent, + 'policy_metadata': policy_metadata, + 'subsection_units': subsection_units, + 'can_view_live': can_view_live + } + ) @login_required @@ -125,7 +138,7 @@ def edit_unit(request, location): """ Display an editing page for the specified module. - Expects a GET request with the parameter 'id'. + Expects a GET request with the parameter `id`. id: A Location URL """ @@ -141,7 +154,10 @@ def edit_unit(request, location): item = modulestore().get_item(location, depth=1) except ItemNotFoundError: return HttpResponseBadRequest() - lms_link = get_lms_link_for_item(item.location, course_id=course.location.course_id) + lms_link = get_lms_link_for_item( + item.location, + course_id=course.location.course_id + ) component_templates = defaultdict(list) for category in COMPONENT_TYPES: @@ -162,17 +178,19 @@ def edit_unit(request, location): template.get('template_id') )) - # Check if there are any advanced modules specified in the course policy. These modules - # should be specified as a list of strings, where the strings are the names of the modules - # in ADVANCED_COMPONENT_TYPES that should be enabled for the course. + # Check if there are any advanced modules specified in the course policy. + # These modules should be specified as a list of strings, where the strings + # are the names of the modules in ADVANCED_COMPONENT_TYPES that should be + # enabled for the course. course_advanced_keys = course.advanced_modules # Set component types according to course policy file if isinstance(course_advanced_keys, list): for category in course_advanced_keys: if category in ADVANCED_COMPONENT_TYPES: - # Do I need to allow for boilerplates or just defaults on the class? i.e., can an advanced - # have more than one entry in the menu? one for default and others for prefilled boilerplates? + # Do I need to allow for boilerplates or just defaults on the + # class? i.e., can an advanced have more than one entry in the + # menu? one for default and others for prefilled boilerplates? try: component_class = XModuleDescriptor.load_class(category) @@ -183,13 +201,16 @@ def edit_unit(request, location): None # don't override default data )) except PluginMissingError: - # dhm: I got this once but it can happen any time the course author configures - # an advanced component which does not exist on the server. This code here merely - # prevents any authors from trying to instantiate the non-existent component type - # by not showing it in the menu + # dhm: I got this once but it can happen any time the + # course author configures an advanced component which does + # not exist on the server. This code here merely + # prevents any authors from trying to instantiate the + # non-existent component type by not showing it in the menu pass else: - log.error("Improper format for course advanced keys! {0}".format(course_advanced_keys)) + log.error( + "Improper format for course advanced keys!" + course_advanced_keys + ) components = [ component.location.url() @@ -201,16 +222,20 @@ def edit_unit(request, location): # this will need to change to check permissions correctly so as # to pick the correct parent subsection - containing_subsection_locs = modulestore().get_parent_locations(location, None) + containing_subsection_locs = modulestore().get_parent_locations( + location, None + ) containing_subsection = modulestore().get_item(containing_subsection_locs[0]) - - containing_section_locs = modulestore().get_parent_locations(containing_subsection.location, None) + containing_section_locs = modulestore().get_parent_locations( + containing_subsection.location, None + ) containing_section = modulestore().get_item(containing_section_locs[0]) # cdodge hack. We're having trouble previewing drafts via jump_to redirect # so let's generate the link url here - # need to figure out where this item is in the list of children as the preview will need this + # need to figure out where this item is in the list of children as the + # preview will need this index = 1 for child in containing_subsection.get_children(): if child.location == item.location: @@ -219,15 +244,19 @@ def edit_unit(request, location): preview_lms_base = settings.MITX_FEATURES.get('PREVIEW_LMS_BASE') - preview_lms_link = '//{preview_lms_base}/courses/{org}/{course}/{course_name}/courseware/{section}/{subsection}/{index}'.format( - preview_lms_base=preview_lms_base, - lms_base=settings.LMS_BASE, - org=course.location.org, - course=course.location.course, - course_name=course.location.name, - section=containing_section.location.name, - subsection=containing_subsection.location.name, - index=index) + preview_lms_link = ( + '//{preview_lms_base}/courses/{org}/{course}/' + '{course_name}/courseware/{section}/{subsection}/{index}' + ).format( + preview_lms_base=preview_lms_base, + lms_base=settings.LMS_BASE, + org=course.location.org, + course=course.location.course, + course_name=course.location.name, + section=containing_section.location.name, + subsection=containing_subsection.location.name, + index=index + ) unit_state = compute_unit_state(item) @@ -240,11 +269,13 @@ def edit_unit(request, location): 'draft_preview_link': preview_lms_link, 'published_preview_link': lms_link, 'subsection': containing_subsection, - 'release_date': get_default_time_display(containing_subsection.lms.start) if containing_subsection.lms.start is not None else None, + 'release_date': get_default_time_display(containing_subsection.lms.start) + if containing_subsection.lms.start is not None else None, 'section': containing_section, 'new_unit_category': 'vertical', 'unit_state': unit_state, - 'published_date': get_default_time_display(item.cms.published_date) if item.cms.published_date is not None else None + 'published_date': get_default_time_display(item.cms.published_date) + if item.cms.published_date is not None else None }) @@ -253,9 +284,10 @@ def edit_unit(request, location): @require_http_methods(("GET", "POST", "PUT")) @ensure_csrf_cookie def assignment_type_update(request, org, course, category, name): - ''' - CRUD operations on assignment types for sections and subsections and anything else gradable. - ''' + """ + CRUD operations on assignment types for sections and subsections and + anything else gradable. + """ location = Location(['i4x', org, course, category, name]) if not has_access(request.user, location): return HttpResponseForbidden() @@ -263,7 +295,9 @@ def assignment_type_update(request, org, course, category, name): if request.method == 'GET': return JsonResponse(CourseGradingModel.get_section_grader_type(location)) elif request.method in ('POST', 'PUT'): # post or put, doesn't matter. - return JsonResponse(CourseGradingModel.update_section_grader_type(location, request.POST)) + return JsonResponse(CourseGradingModel.update_section_grader_type( + location, request.POST + )) @login_required @@ -276,8 +310,8 @@ def create_draft(request): if not has_access(request.user, location): raise PermissionDenied() - # This clones the existing item location to a draft location (the draft is implicit, - # because modulestore is a Draft modulestore) + # This clones the existing item location to a draft location (the draft is + # implicit, because modulestore is a Draft modulestore) modulestore().convert_to_draft(location) return HttpResponse() @@ -286,7 +320,9 @@ def create_draft(request): @login_required @expect_json def publish_draft(request): - "Publish a draft" + """ + Publish a draft + """ location = request.POST['id'] # check permissions for this user within this course @@ -294,7 +330,10 @@ def publish_draft(request): raise PermissionDenied() item = modulestore().get_item(location) - _xmodule_recurse(item, lambda i: modulestore().publish(i.location, request.user.id)) + _xmodule_recurse( + item, + lambda i: modulestore().publish(i.location, request.user.id) + ) return HttpResponse() @@ -328,13 +367,23 @@ def module_info(request, module_location): raise PermissionDenied() rewrite_static_links = request.GET.get('rewrite_url_links', 'True') in ['True', 'true'] - logging.debug('rewrite_static_links = {0} {1}'.format(request.GET.get('rewrite_url_links', 'False'), rewrite_static_links)) + logging.debug('rewrite_static_links = {0} {1}'.format( + request.GET.get('rewrite_url_links', 'False'), + rewrite_static_links) + ) # check that logged in user has permissions to this item if not has_access(request.user, location): raise PermissionDenied() if request.method == 'GET': - return JsonResponse(get_module_info(get_modulestore(location), location, rewrite_static_links=rewrite_static_links)) + return JsonResponse(get_module_info( + get_modulestore(location), + location, + rewrite_static_links=rewrite_static_links + )) elif request.method in ("POST", "PUT"): - return JsonResponse(set_module_info(get_modulestore(location), location, request.POST)) + return JsonResponse(set_module_info( + get_modulestore(location), + location, request.POST + )) diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index a6b1b29aab..b47f8e9ffb 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -82,7 +82,9 @@ def course_index(request, org, course, name): 'context_course': course, 'lms_link': lms_link, 'sections': sections, - 'course_graders': json.dumps(CourseGradingModel.fetch(course.location).graders), + 'course_graders': json.dumps( + CourseGradingModel.fetch(course.location).graders + ), 'parent_location': course.location, 'new_section_category': 'chapter', 'new_subsection_category': 'sequential', @@ -120,24 +122,31 @@ def create_new_course(request): except ItemNotFoundError: pass if existing_course is not None: - return JsonResponse( - { - 'ErrMsg': _('There is already a course defined with the same organization, course number, and course run. Please change either organization or course number to be unique.'), - 'OrgErrMsg': _('Please change either the organization or course number so that it is unique.'), - 'CourseErrMsg': _('Please change either the organization or course number so that it is unique.'), - } - ) + return JsonResponse({ + 'ErrMsg': _(('There is already a course defined with the same ' + 'organization, course number, and course run. Please ' + 'change either organization or course number to be ' + 'unique.')), + 'OrgErrMsg': _(('Please change either the organization or ' + 'course number so that it is unique.')), + 'CourseErrMsg': _(('Please change either the organization or ' + 'course number so that it is unique.')), + }) - course_search_location = ['i4x', dest_location.org, dest_location.course, 'course', None] + course_search_location = ['i4x', dest_location.org, dest_location.course, + 'course', None + ] courses = modulestore().get_items(course_search_location) if len(courses) > 0: - return JsonResponse( - { - 'ErrMsg': _('There is already a course defined with the same organization and course number. Please change at least one field to be unique.'), - 'OrgErrMsg': _('Please change either the organization or course number so that it is unique.'), - 'CourseErrMsg': _('Please change either the organization or course number so that it is unique.'), - } - ) + return JsonResponse({ + 'ErrMsg': _(('There is already a course defined with the same ' + 'organization and course number. Please ' + 'change at least one field to be unique.')), + 'OrgErrMsg': _(('Please change either the organization or ' + 'course number so that it is unique.')), + 'CourseErrMsg': _(('Please change either the organization or ' + 'course number so that it is unique.')), + }) # instantiate the CourseDescriptor and then persist it # note: no system to pass @@ -145,11 +154,17 @@ def create_new_course(request): metadata = {} else: metadata = {'display_name': display_name} - modulestore('direct').create_and_save_xmodule(dest_location, metadata=metadata) + modulestore('direct').create_and_save_xmodule( + dest_location, + metadata=metadata + ) new_course = modulestore('direct').get_item(dest_location) # clone a default 'about' overview module as well - dest_about_location = dest_location.replace(category='about', name='overview') + dest_about_location = dest_location.replace( + category='about', + name='overview' + ) overview_template = AboutDescriptor.get_template('overview.yaml') modulestore('direct').create_and_save_xmodule( dest_about_location, @@ -164,7 +179,8 @@ def create_new_course(request): # seed the forums seed_permissions_roles(new_course.location.course_id) - # auto-enroll the course creator in the course so that "View Live" will work. + # auto-enroll the course creator in the course so that "View Live" will + # work. CourseEnrollment.enroll(request.user, new_course.location.course_id) return JsonResponse({'id': new_course.location.url()}) @@ -174,7 +190,8 @@ def create_new_course(request): @ensure_csrf_cookie def course_info(request, org, course, name, provided_id=None): """ - Send models and views as well as html for editing the course info to the client. + Send models and views as well as html for editing the course info to the + client. org, course, name: Attributes of the Location for the item to edit """ @@ -189,7 +206,8 @@ def course_info(request, org, course, name, provided_id=None): 'context_course': course_module, 'url_base': "/" + org + "/" + course + "/", 'course_updates': json.dumps(get_course_updates(location)), - 'handouts_location': Location(['i4x', org, course, 'course_info', 'handouts']).url() + 'handouts_location': Location(['i4x', org, course, 'course_info', + 'handouts']).url() }) @@ -202,14 +220,16 @@ def course_info_updates(request, org, course, provided_id=None): restful CRUD operations on course_info updates. org, course: Attributes of the Location for the item to edit - provided_id should be none if it's new (create) and a composite of the update db id + index otherwise. + provided_id should be none if it's new (create) and a composite of the + update db id + index otherwise. """ # ??? No way to check for access permission afaik # get current updates location = ['i4x', org, course, 'course_info', "updates"] - # Hmmm, provided_id is coming as empty string on create whereas I believe it used to be None :-( - # Possibly due to my removing the seemingly redundant pattern in urls.py + # Hmmm, provided_id is coming as empty string on create whereas I believe + # it used to be None :-( Possibly due to my removing the seemingly + # redundant pattern in urls.py if provided_id == '': provided_id = None @@ -221,13 +241,19 @@ def course_info_updates(request, org, course, provided_id=None): return JsonResponse(get_course_updates(location)) elif request.method == 'DELETE': try: - return JsonResponse(delete_course_update(location, request.POST, provided_id)) + return JsonResponse(delete_course_update(location, request.POST, + provided_id + )) except: return HttpResponseBadRequest("Failed to delete", content_type="text/plain") - elif request.method in ('POST', 'PUT'): # can be either and sometimes django is rewriting one to the other + elif request.method in ('POST', 'PUT'): # can be either and sometimes + # django is rewriting one to the + # other try: - return JsonResponse(update_course_updates(location, request.POST, provided_id)) + return JsonResponse(update_course_updates(location, request.POST, + provided_id + )) except: return HttpResponseBadRequest("Failed to save", content_type="text/plain") @@ -237,7 +263,8 @@ def course_info_updates(request, org, course, provided_id=None): @ensure_csrf_cookie def get_course_settings(request, org, course, name): """ - Send models and views as well as html for editing the course settings to the client. + Send models and views as well as html for editing the course settings to + the client. org, course, name: Attributes of the Location for the item to edit """ @@ -253,7 +280,9 @@ def get_course_settings(request, org, course, name): "course": course, "name": name, "section": "details"}), - 'about_page_editable': not settings.MITX_FEATURES.get('ENABLE_MKTG_SITE', False) + 'about_page_editable': not settings.MITX_FEATURES.get( + 'ENABLE_MKTG_SITE', False + ) }) @@ -261,7 +290,8 @@ def get_course_settings(request, org, course, name): @ensure_csrf_cookie def course_config_graders_page(request, org, course, name): """ - Send models and views as well as html for editing the course settings to the client. + Send models and views as well as html for editing the course settings to + the client. org, course, name: Attributes of the Location for the item to edit """ @@ -281,7 +311,8 @@ def course_config_graders_page(request, org, course, name): @ensure_csrf_cookie def course_config_advanced_page(request, org, course, name): """ - Send models and views as well as html for editing the advanced course settings to the client. + Send models and views as well as html for editing the advanced course + settings to the client. org, course, name: Attributes of the Location for the item to edit """ @@ -301,8 +332,9 @@ def course_config_advanced_page(request, org, course, name): @ensure_csrf_cookie def course_settings_updates(request, org, course, name, section): """ - restful CRUD operations on course settings. This differs from get_course_settings by communicating purely - through json (not rendering any html) and handles section level operations rather than whole page. + Restful CRUD operations on course settings. This differs from + get_course_settings by communicating purely through json (not rendering any + html) and handles section level operations rather than whole page. org, course: Attributes of the Location for the item to edit section: one of details, faculty, grading, problems, discussions @@ -318,9 +350,15 @@ def course_settings_updates(request, org, course, name, section): if request.method == 'GET': # Cannot just do a get w/o knowing the course name :-( - return JsonResponse(manager.fetch(Location(['i4x', org, course, 'course', name])), encoder=CourseSettingsEncoder) + return JsonResponse( + manager.fetch(Location(['i4x', org, course, 'course', name])), + encoder=CourseSettingsEncoder + ) elif request.method in ('POST', 'PUT'): # post or put, doesn't matter. - return JsonResponse(manager.update_from_json(request.POST), encoder=CourseSettingsEncoder) + return JsonResponse( + manager.update_from_json(request.POST), + encoder=CourseSettingsEncoder + ) @expect_json @@ -329,8 +367,9 @@ def course_settings_updates(request, org, course, name, section): @ensure_csrf_cookie def course_grader_updates(request, org, course, name, grader_index=None): """ - restful CRUD operations on course_info updates. This differs from get_course_settings by communicating purely - through json (not rendering any html) and handles section level operations rather than whole page. + Restful CRUD operations on course_info updates. This differs from + get_course_settings by communicating purely through json (not rendering any + html) and handles section level operations rather than whole page. org, course: Attributes of the Location for the item to edit """ @@ -339,13 +378,18 @@ def course_grader_updates(request, org, course, name, grader_index=None): if request.method == 'GET': # Cannot just do a get w/o knowing the course name :-( - return JsonResponse(CourseGradingModel.fetch_grader(Location(location), grader_index)) + return JsonResponse(CourseGradingModel.fetch_grader( + Location(location), grader_index + )) elif request.method == "DELETE": # ??? Should this return anything? Perhaps success fail? CourseGradingModel.delete_grader(Location(location), grader_index) return JsonResponse() else: # post or put, doesn't matter. - return JsonResponse(CourseGradingModel.update_grader_from_json(Location(location), request.POST)) + return JsonResponse(CourseGradingModel.update_grader_from_json( + Location(location), + request.POST + )) # # NB: expect_json failed on ["key", "key2"] and json payload @@ -354,8 +398,9 @@ def course_grader_updates(request, org, course, name, grader_index=None): @ensure_csrf_cookie def course_advanced_updates(request, org, course, name): """ - restful CRUD operations on metadata. The payload is a json rep of the metadata dicts. For delete, otoh, - the payload is either a key or a list of keys to delete. + Restful CRUD operations on metadata. The payload is a json rep of the + metadata dicts. For delete, otoh, the payload is either a key or a list of + keys to delete. org, course: Attributes of the Location for the item to edit """ @@ -364,20 +409,26 @@ def course_advanced_updates(request, org, course, name): if request.method == 'GET': return JsonResponse(CourseMetadata.fetch(location)) elif request.method == 'DELETE': - return JsonResponse(CourseMetadata.delete_key(location, json.loads(request.body))) + return JsonResponse(CourseMetadata.delete_key( + location, + json.loads(request.body) + )) else: # NOTE: request.POST is messed up because expect_json - # cloned_request.POST.copy() is creating a defective entry w/ the whole payload as the key + # cloned_request.POST.copy() is creating a defective entry w/ the whole + # payload as the key request_body = json.loads(request.body) # Whether or not to filter the tabs key out of the settings metadata filter_tabs = True - # Check to see if the user instantiated any advanced components. This is a hack - # that does the following : - # 1) adds/removes the open ended panel tab to a course automatically if the user - # has indicated that they want to edit the combinedopendended or peergrading module - # 2) adds/removes the notes panel tab to a course automatically if the user has - # indicated that they want the notes module enabled in their course + # Check to see if the user instantiated any advanced components. This + # is a hack that does the following : + # 1) adds/removes the open ended panel tab to a course automatically + # if the user has indicated that they want to edit the + # combinedopendended or peergrading module + # 2) adds/removes the notes panel tab to a course automatically if + # the user has indicated that they want the notes module enabled in + # their course # TODO refactor the above into distinct advanced policy settings if ADVANCED_COMPONENT_POLICY_KEY in request_body: # Get the course so that we can scrape current tabs @@ -389,19 +440,25 @@ def course_advanced_updates(request, org, course, name): 'notes': NOTE_COMPONENT_TYPES, } - # Check to see if the user instantiated any notes or open ended components + # Check to see if the user instantiated any notes or open ended + # components for tab_type in tab_component_map.keys(): component_types = tab_component_map.get(tab_type) found_ac_type = False for ac_type in component_types: if ac_type in request_body[ADVANCED_COMPONENT_POLICY_KEY]: # Add tab to the course if needed - changed, new_tabs = add_extra_panel_tab(tab_type, course_module) - # If a tab has been added to the course, then send the metadata along to CourseMetadata.update_from_json + changed, new_tabs = add_extra_panel_tab( + tab_type, + course_module + ) + # If a tab has been added to the course, then send the + # metadata along to CourseMetadata.update_from_json if changed: course_module.tabs = new_tabs request_body.update({'tabs': new_tabs}) - # Indicate that tabs should not be filtered out of the metadata + # Indicate that tabs should not be filtered out of + # the metadata filter_tabs = False # Set this flag to avoid the tab removal code below. found_ac_type = True @@ -410,18 +467,26 @@ def course_advanced_updates(request, org, course, name): # we may need to remove the tab from the course. if not found_ac_type: # Remove tab from the course if needed - changed, new_tabs = remove_extra_panel_tab(tab_type, course_module) + changed, new_tabs = remove_extra_panel_tab( + tab_type, course_module + ) if changed: course_module.tabs = new_tabs request_body.update({'tabs': new_tabs}) - # Indicate that tabs should *not* be filtered out of the metadata + # Indicate that tabs should *not* be filtered out of + # the metadata filter_tabs = False try: - return JsonResponse(CourseMetadata.update_from_json(location, - request_body, - filter_tabs=filter_tabs)) + return JsonResponse(CourseMetadata.update_from_json( + location, + request_body, + filter_tabs=filter_tabs + )) except (TypeError, ValueError) as err: - return HttpResponseBadRequest("Incorrect setting format. " + str(err), content_type="text/plain") + return HttpResponseBadRequest( + "Incorrect setting format. " + str(err), + content_type="text/plain" + ) class TextbookValidationError(Exception): @@ -498,7 +563,8 @@ def textbook_index(request, org, course, name): if request.is_ajax(): if request.method == 'GET': return JsonResponse(course_module.pdf_textbooks) - elif request.method in ('POST', 'PUT'): # can be either and sometimes django is rewriting one to the other + elif request.method in ('POST', 'PUT'): # can be either and sometimes + # django is rewriting one to the other try: textbooks = validate_textbooks_json(request.body) except TextbookValidationError as err: @@ -517,7 +583,10 @@ def textbook_index(request, org, course, name): # Save the data that we've just changed to the underlying # MongoKeyValueStore before we update the mongo datastore. course_module.save() - store.update_metadata(course_module.location, own_metadata(course_module)) + store.update_metadata( + course_module.location, + own_metadata(course_module) + ) return JsonResponse(course_module.pdf_textbooks) else: upload_asset_url = reverse('upload_asset', kwargs={ @@ -599,7 +668,8 @@ def textbook_by_id(request, org, course, name, tid): if not textbook: return JsonResponse(status=404) return JsonResponse(textbook) - elif request.method in ('POST', 'PUT'): # can be either and sometimes django is rewriting one to the other + elif request.method in ('POST', 'PUT'): # can be either and sometimes + # django is rewriting one to the other try: new_textbook = validate_textbook_json(request.body) except TextbookValidationError as err: @@ -616,7 +686,10 @@ def textbook_by_id(request, org, course, name, tid): # Save the data that we've just changed to the underlying # MongoKeyValueStore before we update the mongo datastore. course_module.save() - store.update_metadata(course_module.location, own_metadata(course_module)) + store.update_metadata( + course_module.location, + own_metadata(course_module) + ) return JsonResponse(new_textbook, status=201) elif request.method == 'DELETE': if not textbook: @@ -626,5 +699,8 @@ def textbook_by_id(request, org, course, name, tid): new_textbooks.extend(course_module.pdf_textbooks[i + 1:]) course_module.pdf_textbooks = new_textbooks course_module.save() - store.update_metadata(course_module.location, own_metadata(course_module)) + store.update_metadata( + course_module.location, + own_metadata(course_module) + ) return JsonResponse()