From e9b3d8e8ec04dfda30ac5b81decf4532c2ce9674 Mon Sep 17 00:00:00 2001 From: Ayub khan Date: Tue, 9 Jul 2019 14:19:16 +0500 Subject: [PATCH] INCR-333 python3 compatibility --- cms/djangoapps/contentstore/views/__init__.py | 13 +++-- cms/djangoapps/contentstore/views/access.py | 2 + .../contentstore/views/certificates.py | 13 +++-- .../contentstore/views/checklists.py | 4 +- cms/djangoapps/contentstore/views/course.py | 49 ++++++++++--------- .../contentstore/views/entrance_exam.py | 21 ++++---- cms/djangoapps/contentstore/views/error.py | 2 + .../contentstore/views/organization.py | 2 + cms/djangoapps/contentstore/views/tabs.py | 5 +- .../contentstore/views/transcripts_ajax.py | 22 +++++---- 10 files changed, 77 insertions(+), 56 deletions(-) diff --git a/cms/djangoapps/contentstore/views/__init__.py b/cms/djangoapps/contentstore/views/__init__.py index e90628aef4..3f81e7f8f9 100644 --- a/cms/djangoapps/contentstore/views/__init__.py +++ b/cms/djangoapps/contentstore/views/__init__.py @@ -2,26 +2,25 @@ "All view functions for contentstore, broken out into submodules" -# Disable warnings about import from wildcard -# All files below declare exports with __all__ from .assets import * +from .checklists import * from .component import * from .course import * -from .checklists import * from .entrance_exam import * from .error import * +from .export_git import * from .helpers import * -from .item import * from .import_export import * +from .item import * from .library import * from .preview import * from .public import * -from .export_git import * -from .user import * from .tabs import * -from .videos import * from .transcript_settings import * from .transcripts_ajax import * +from .user import * +from .videos import * + try: from .dev import * except ImportError: diff --git a/cms/djangoapps/contentstore/views/access.py b/cms/djangoapps/contentstore/views/access.py index 50fb74e55c..2ed9de9453 100644 --- a/cms/djangoapps/contentstore/views/access.py +++ b/cms/djangoapps/contentstore/views/access.py @@ -1,5 +1,7 @@ """ Helper methods for determining user access permissions in Studio """ +from __future__ import absolute_import + from student import auth from student.roles import CourseInstructorRole diff --git a/cms/djangoapps/contentstore/views/certificates.py b/cms/djangoapps/contentstore/views/certificates.py index acef5a41d1..a47af6ec8f 100644 --- a/cms/djangoapps/contentstore/views/certificates.py +++ b/cms/djangoapps/contentstore/views/certificates.py @@ -21,9 +21,12 @@ course.certificates: { ] } """ +from __future__ import absolute_import + import json import logging +import six from django.conf import settings from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied @@ -31,6 +34,7 @@ from django.http import HttpResponse from django.utils.translation import ugettext as _ from django.views.decorators.csrf import ensure_csrf_cookie from django.views.decorators.http import require_http_methods +from eventtracking import tracker from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import AssetKey, CourseKey from six import text_type @@ -40,7 +44,6 @@ from contentstore.views.assets import delete_asset from contentstore.views.exception import AssetNotFoundException from course_modes.models import CourseMode from edxmako.shortcuts import render_to_response -from eventtracking import tracker from student.auth import has_studio_write_access from student.roles import GlobalStaff from util.db import MYSQL_MAX_INT, generate_int_id @@ -358,7 +361,7 @@ def certificate_activation_handler(request, course_key_string): store.update_item(course, request.user.id) cert_event_type = 'activated' if is_active else 'deactivated' CertificateManager.track_event(cert_event_type, { - 'course_id': unicode(course.id), + 'course_id': six.text_type(course.id), }) return HttpResponse(status=200) @@ -446,7 +449,7 @@ def certificates_list_handler(request, course_key_string): ) store.update_item(course, request.user.id) CertificateManager.track_event('created', { - 'course_id': unicode(course.id), + 'course_id': six.text_type(course.id), 'configuration_id': new_certificate.id }) course = _get_course_and_check_access(course_key, request.user) @@ -503,7 +506,7 @@ def certificates_detail_handler(request, course_key_string, certificate_id): store.update_item(course, request.user.id) CertificateManager.track_event(cert_event_type, { - 'course_id': unicode(course.id), + 'course_id': six.text_type(course.id), 'configuration_id': serialized_certificate["id"] }) return JsonResponse(serialized_certificate, status=201) @@ -525,7 +528,7 @@ def certificates_detail_handler(request, course_key_string, certificate_id): certificate_id=certificate_id ) CertificateManager.track_event('deleted', { - 'course_id': unicode(course.id), + 'course_id': six.text_type(course.id), 'configuration_id': certificate_id }) return JsonResponse(status=204) diff --git a/cms/djangoapps/contentstore/views/checklists.py b/cms/djangoapps/contentstore/views/checklists.py index f3fb7cffba..ebea256a50 100644 --- a/cms/djangoapps/contentstore/views/checklists.py +++ b/cms/djangoapps/contentstore/views/checklists.py @@ -1,12 +1,14 @@ # pylint: disable=missing-docstring +from __future__ import absolute_import + from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied from django.views.decorators.csrf import ensure_csrf_cookie from opaque_keys.edx.keys import CourseKey -from xmodule.modulestore.django import modulestore from edxmako.shortcuts import render_to_response from student.auth import has_course_author_access +from xmodule.modulestore.django import modulestore __all__ = ['checklists_handler'] diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index 0aa32a6647..f4ef8c320f 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -1,13 +1,15 @@ """ Views related to operations on course objects """ -from collections import defaultdict +from __future__ import absolute_import + import copy import json import logging import random import re import string +from collections import defaultdict import django.utils import six @@ -15,20 +17,18 @@ from ccx_keys.locator import CCXLocator from django.conf import settings from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied, ValidationError -from django.urls import reverse from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponseNotFound from django.shortcuts import redirect +from django.urls import reverse from django.utils.translation import ugettext as _ from django.views.decorators.csrf import ensure_csrf_cookie from django.views.decorators.http import require_GET, require_http_methods +from milestones import api as milestones_api from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.locator import BlockUsageLocator -from openedx.core.djangoapps.content.course_overviews.models import CourseOverview -from openedx.core.djangoapps.waffle_utils import WaffleSwitchNamespace -from openedx.features.course_experience.waffle import waffle as course_experience_waffle -from openedx.features.course_experience.waffle import ENABLE_COURSE_ABOUT_SIDEBAR_HTML from six import text_type +from six.moves import filter from contentstore.course_group_config import ( COHORT_SCHEME, @@ -56,19 +56,22 @@ from course_action_state.managers import CourseActionStateItemNotFoundError from course_action_state.models import CourseRerunState, CourseRerunUIStateManager from course_creators.views import add_user_with_status_unrequested, get_course_creator_status from edxmako.shortcuts import render_to_response -from milestones import api as milestones_api from models.settings.course_grading import CourseGradingModel from models.settings.course_metadata import CourseMetadata from models.settings.encoder import CourseSettingsEncoder +from openedx.core.djangoapps.content.course_overviews.models import CourseOverview from openedx.core.djangoapps.credit.api import get_credit_requirements, is_credit_course from openedx.core.djangoapps.credit.tasks import update_credit_course_requirements from openedx.core.djangoapps.models.course_details import CourseDetails from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers +from openedx.core.djangoapps.waffle_utils import WaffleSwitchNamespace from openedx.core.djangolib.js_utils import dump_js_escaped_json from openedx.core.lib.course_tabs import CourseTabPluginManager from openedx.core.lib.courses import course_image_url -from openedx.features.content_type_gating.partitions import CONTENT_TYPE_GATING_SCHEME from openedx.features.content_type_gating.models import ContentTypeGatingConfig +from openedx.features.content_type_gating.partitions import CONTENT_TYPE_GATING_SCHEME +from openedx.features.course_experience.waffle import ENABLE_COURSE_ABOUT_SIDEBAR_HTML +from openedx.features.course_experience.waffle import waffle as course_experience_waffle from student import auth from student.auth import has_course_author_access, has_studio_read_access, has_studio_write_access from student.roles import CourseCreatorRole, CourseInstructorRole, CourseStaffRole, GlobalStaff, UserBasedRole @@ -460,7 +463,7 @@ def _accessible_courses_list_from_groups(request): instructor_courses = UserBasedRole(request.user, CourseInstructorRole.ROLE).courses_with_role() staff_courses = UserBasedRole(request.user, CourseStaffRole.ROLE).courses_with_role() - all_courses = filter(filter_ccx, instructor_courses | staff_courses) + all_courses = list(filter(filter_ccx, instructor_courses | staff_courses)) courses_list = [] course_keys = {} @@ -469,7 +472,7 @@ def _accessible_courses_list_from_groups(request): raise AccessListFallback course_keys[course_access.course_id] = course_access.course_id - course_keys = course_keys.values() + course_keys = list(course_keys.values()) if course_keys: courses_list = modulestore().get_course_summaries(course_keys=course_keys) @@ -514,7 +517,7 @@ def course_listing(request): """ return { u'display_name': uca.display_name, - u'course_key': unicode(uca.course_key), + u'course_key': six.text_type(uca.course_key), u'org': uca.course_key.org, u'number': uca.course_key.course, u'run': uca.course_key.run, @@ -536,8 +539,8 @@ def course_listing(request): return { u'display_name': library.display_name, - u'library_key': unicode(library.location.library_key), - u'url': reverse_library_url(u'library_handler', unicode(library.location.library_key)), + u'library_key': six.text_type(library.location.library_key), + u'url': reverse_library_url(u'library_handler', six.text_type(library.location.library_key)), u'org': library.display_org_with_default, u'number': library.display_number_with_default, u'can_edit': has_studio_write_access(request.user, library.location.library_key), @@ -624,7 +627,7 @@ def course_index(request, course_key): lms_link = get_lms_link_for_item(course_module.location) reindex_link = None if settings.FEATURES.get('ENABLE_COURSEWARE_INDEX', False): - reindex_link = "/course/{course_id}/search_reindex".format(course_id=unicode(course_key)) + reindex_link = "/course/{course_id}/search_reindex".format(course_id=six.text_type(course_key)) sections = course_module.get_children() course_structure = _course_outline_json(request, course_module) locator_to_show = request.GET.get('show', None) @@ -708,7 +711,7 @@ def _process_courses_list(courses_iter, in_process_course_actions, split_archive """ return { 'display_name': course.display_name, - 'course_key': unicode(course.location.course_key), + 'course_key': six.text_type(course.location.course_key), 'url': reverse_course_url('course_handler', course.id), 'lms_link': get_lms_link_for_item(course.location), 'rerun_link': _get_rerun_link_for_item(course.id), @@ -819,14 +822,14 @@ def _create_or_rerun_course(request): destination_course_key = rerun_course(request.user, source_course_key, org, course, run, fields) return JsonResponse({ 'url': reverse_url('course_handler'), - 'destination_course_key': unicode(destination_course_key) + 'destination_course_key': six.text_type(destination_course_key) }) else: try: new_course = create_new_course(request.user, org, course, run, fields) return JsonResponse({ 'url': reverse_course_url('course_handler', new_course.id), - 'course_key': unicode(new_course.id), + 'course_key': six.text_type(new_course.id), }) except ValidationError as ex: return JsonResponse({'error': text_type(ex)}, status=400) @@ -928,7 +931,7 @@ def rerun_course(user, source_course_key, org, number, run, fields, background=T fields['video_upload_pipeline'] = {} json_fields = json.dumps(fields, cls=EdxJSONEncoder) - args = [unicode(source_course_key), unicode(destination_course_key), user.id, json_fields] + args = [six.text_type(source_course_key), six.text_type(destination_course_key), user.id, json_fields] if background: rerun_course_task.delay(*args) @@ -1221,7 +1224,7 @@ def grading_handler(request, course_key_string, grader_index=None): # update credit course requirements if 'minimum_grade_credit' # field value is changed if 'minimum_grade_credit' in request.json: - update_credit_course_requirements.delay(unicode(course_key)) + update_credit_course_requirements.delay(six.text_type(course_key)) # None implies update the whole model (cutoffs, graceperiod, and graders) not a specific grader if grader_index is None: @@ -1369,7 +1372,7 @@ def validate_textbook_json(textbook): """ Validate the given text as representing a list of PDF textbooks """ - if isinstance(textbook, basestring): + if isinstance(textbook, six.string_types): try: textbook = json.loads(textbook) except ValueError: @@ -1378,7 +1381,7 @@ def validate_textbook_json(textbook): raise TextbookValidationError("must be JSON object") if not textbook.get("tab_title"): raise TextbookValidationError("must have tab_title") - tid = unicode(textbook.get("id", "")) + tid = six.text_type(textbook.get("id", "")) if tid and not tid[0].isdigit(): raise TextbookValidationError("textbook ID must start with a digit") return textbook @@ -1495,7 +1498,7 @@ def textbooks_detail_handler(request, course_key_string, textbook_id): with store.bulk_operations(course_key): course_module = get_course_and_check_access(course_key, request.user) matching_id = [tb for tb in course_module.pdf_textbooks - if unicode(tb.get("id")) == unicode(textbook_id)] + if six.text_type(tb.get("id")) == six.text_type(textbook_id)] if matching_id: textbook = matching_id[0] else: @@ -1683,7 +1686,7 @@ def group_configurations_detail_handler(request, course_key_string, group_config with store.bulk_operations(course_key): course = get_course_and_check_access(course_key, request.user) matching_id = [p for p in course.user_partitions - if unicode(p.id) == unicode(group_configuration_id)] + if six.text_type(p.id) == six.text_type(group_configuration_id)] if matching_id: configuration = matching_id[0] else: diff --git a/cms/djangoapps/contentstore/views/entrance_exam.py b/cms/djangoapps/contentstore/views/entrance_exam.py index c6944a5673..b1d9d0d5db 100644 --- a/cms/djangoapps/contentstore/views/entrance_exam.py +++ b/cms/djangoapps/contentstore/views/entrance_exam.py @@ -2,9 +2,12 @@ Entrance Exams view module -- handles all requests related to entrance exam management via Studio Intended to be utilized as an AJAX callback handler, versus a proper view/screen """ +from __future__ import absolute_import + import logging from functools import wraps +import six from django.conf import settings from django.contrib.auth.decorators import login_required from django.http import HttpResponse, HttpResponseBadRequest @@ -130,7 +133,7 @@ def _create_entrance_exam(request, course_key, entrance_exam_minimum_score_pct=N return HttpResponse(status=400) # Create the entrance exam item (currently it's just a chapter) - parent_locator = unicode(course.location) + parent_locator = six.text_type(course.location) created_block = create_xblock( parent_locator=parent_locator, user=request.user, @@ -145,13 +148,13 @@ def _create_entrance_exam(request, course_key, entrance_exam_minimum_score_pct=N metadata = { 'entrance_exam_enabled': True, 'entrance_exam_minimum_score_pct': entrance_exam_minimum_score_pct, - 'entrance_exam_id': unicode(created_block.location), + 'entrance_exam_id': six.text_type(created_block.location), } CourseMetadata.update_from_dict(metadata, course, request.user) # Create the entrance exam section item. create_xblock( - parent_locator=unicode(created_block.location), + parent_locator=six.text_type(created_block.location), user=request.user, category='sequential', display_name=_('Entrance Exam - Subsection') @@ -177,7 +180,7 @@ def _get_entrance_exam(request, course_key): # pylint: disable=W0613 try: exam_descriptor = modulestore().get_item(exam_key) return HttpResponse( - dump_js_escaped_json({'locator': unicode(exam_descriptor.location)}), + dump_js_escaped_json({'locator': six.text_type(exam_descriptor.location)}), status=200, content_type='application/json') except ItemNotFoundError: return HttpResponse(status=404) @@ -246,7 +249,7 @@ def add_entrance_exam_milestone(course_id, x_block): if len(milestones): milestone = milestones[0] else: - description = u'Autogenerated during {} entrance exam creation.'.format(unicode(course_id)) + description = u'Autogenerated during {} entrance exam creation.'.format(six.text_type(course_id)) milestone = milestones_helpers.add_milestone({ 'name': _('Completed Course Entrance Exam'), 'namespace': milestone_namespace, @@ -254,13 +257,13 @@ def add_entrance_exam_milestone(course_id, x_block): }) relationship_types = milestones_helpers.get_milestone_relationship_types() milestones_helpers.add_course_milestone( - unicode(course_id), + six.text_type(course_id), relationship_types['REQUIRES'], milestone ) milestones_helpers.add_course_content_milestone( - unicode(course_id), - unicode(x_block.location), + six.text_type(course_id), + six.text_type(x_block.location), relationship_types['FULFILLS'], milestone ) @@ -277,4 +280,4 @@ def remove_entrance_exam_milestone_reference(request, course_key): for course_child in course_children: if course_child.is_entrance_exam: delete_item(request, course_child.scope_ids.usage_id) - milestones_helpers.remove_content_references(unicode(course_child.scope_ids.usage_id)) + milestones_helpers.remove_content_references(six.text_type(course_child.scope_ids.usage_id)) diff --git a/cms/djangoapps/contentstore/views/error.py b/cms/djangoapps/contentstore/views/error.py index 755417bda4..8045b0fd4a 100644 --- a/cms/djangoapps/contentstore/views/error.py +++ b/cms/djangoapps/contentstore/views/error.py @@ -1,5 +1,7 @@ # pylint: disable=missing-docstring,unused-argument +from __future__ import absolute_import + import functools from django.http import HttpResponse, HttpResponseNotFound, HttpResponseServerError diff --git a/cms/djangoapps/contentstore/views/organization.py b/cms/djangoapps/contentstore/views/organization.py index 253229963a..7fa03d51ce 100644 --- a/cms/djangoapps/contentstore/views/organization.py +++ b/cms/djangoapps/contentstore/views/organization.py @@ -1,4 +1,6 @@ """Organizations views for use with Studio.""" +from __future__ import absolute_import + from django.contrib.auth.decorators import login_required from django.http import HttpResponse from django.utils.decorators import method_decorator diff --git a/cms/djangoapps/contentstore/views/tabs.py b/cms/djangoapps/contentstore/views/tabs.py index edfb438165..f5438f1ab5 100644 --- a/cms/djangoapps/contentstore/views/tabs.py +++ b/cms/djangoapps/contentstore/views/tabs.py @@ -1,6 +1,9 @@ """ Views related to course tabs """ +from __future__ import absolute_import + +import six from django.contrib.auth.decorators import login_required from django.core.exceptions import PermissionDenied from django.http import HttpResponseNotFound @@ -197,7 +200,7 @@ def primitive_delete(course, num): def primitive_insert(course, num, tab_type, name): "Inserts a new tab at the given number (0 based)." validate_args(num, tab_type) - new_tab = CourseTab.from_json({u'type': unicode(tab_type), u'name': unicode(name)}) + new_tab = CourseTab.from_json({u'type': six.text_type(tab_type), u'name': six.text_type(name)}) tabs = course.tabs tabs.insert(num, new_tab) modulestore().update_item(course, ModuleStoreEnum.UserID.primitive_command) diff --git a/cms/djangoapps/contentstore/views/transcripts_ajax.py b/cms/djangoapps/contentstore/views/transcripts_ajax.py index 9f4de090a3..8c1a76b722 100644 --- a/cms/djangoapps/contentstore/views/transcripts_ajax.py +++ b/cms/djangoapps/contentstore/views/transcripts_ajax.py @@ -5,6 +5,8 @@ Actions manager for transcripts ajax calls. Module do not support rollback (pressing "Cancel" button in Studio) All user changes are saved immediately. """ +from __future__ import absolute_import + import copy import json import logging @@ -17,10 +19,12 @@ from django.core.exceptions import PermissionDenied from django.core.files.base import ContentFile from django.http import Http404, HttpResponse from django.utils.translation import ugettext as _ +from edxval.api import create_external_video, create_or_update_video_transcript from opaque_keys import InvalidKeyError from opaque_keys.edx.keys import UsageKey from six import text_type -from edxval.api import create_or_update_video_transcript, create_external_video + +from cms.djangoapps.contentstore.views.videos import TranscriptProvider from student.auth import has_course_author_access from util.json_request import JsonResponse from xmodule.contentstore.content import StaticContent @@ -29,21 +33,19 @@ from xmodule.exceptions import NotFoundError from xmodule.modulestore.django import modulestore from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.video_module.transcripts_utils import ( + GetTranscriptsFromYouTubeException, + Transcript, + TranscriptsGenerationException, + TranscriptsRequestValidationException, clean_video_id, download_youtube_subs, - GetTranscriptsFromYouTubeException, - get_transcript_for_video, - get_transcripts_from_youtube, - Transcript, - TranscriptsRequestValidationException, - TranscriptsGenerationException, - youtube_video_transcript_name, get_transcript, + get_transcript_for_video, get_transcript_from_val, + get_transcripts_from_youtube, + youtube_video_transcript_name ) -from cms.djangoapps.contentstore.views.videos import TranscriptProvider - __all__ = [ 'upload_transcripts', 'download_transcripts',