From de52c6d310c278fa679fd61e9a05d4e925089f04 Mon Sep 17 00:00:00 2001 From: Michael Youngstrom Date: Mon, 1 Apr 2019 14:28:04 -0400 Subject: [PATCH] INCR-186 --- openedx/core/djangoapps/credit/admin.py | 2 ++ openedx/core/djangoapps/credit/apps.py | 2 ++ openedx/core/djangoapps/credit/email_utils.py | 15 +++++++++------ openedx/core/djangoapps/credit/exceptions.py | 3 +-- openedx/core/djangoapps/credit/models.py | 9 ++++++--- openedx/core/djangoapps/credit/routers.py | 2 ++ openedx/core/djangoapps/credit/serializers.py | 5 +++-- openedx/core/djangoapps/credit/services.py | 5 ++++- openedx/core/djangoapps/credit/signals.py | 7 +++++-- openedx/core/djangoapps/credit/signature.py | 5 ++++- openedx/core/djangoapps/credit/tasks.py | 9 ++++++--- openedx/core/djangoapps/credit/urls.py | 2 ++ openedx/core/djangoapps/credit/utils.py | 2 ++ openedx/core/djangoapps/credit/views.py | 5 +++-- 14 files changed, 51 insertions(+), 22 deletions(-) diff --git a/openedx/core/djangoapps/credit/admin.py b/openedx/core/djangoapps/credit/admin.py index e1c500bd4b..1eb63fa04c 100644 --- a/openedx/core/djangoapps/credit/admin.py +++ b/openedx/core/djangoapps/credit/admin.py @@ -1,6 +1,8 @@ """ Django admin page for credit eligibility """ +from __future__ import absolute_import + from django.contrib import admin from openedx.core.djangoapps.credit.models import ( diff --git a/openedx/core/djangoapps/credit/apps.py b/openedx/core/djangoapps/credit/apps.py index 49ca822c9b..9e525f032e 100644 --- a/openedx/core/djangoapps/credit/apps.py +++ b/openedx/core/djangoapps/credit/apps.py @@ -2,6 +2,8 @@ Credit Application Configuration """ +from __future__ import absolute_import + from django.apps import AppConfig from django.conf import settings from edx_proctoring.runtime import set_runtime_service diff --git a/openedx/core/djangoapps/credit/email_utils.py b/openedx/core/djangoapps/credit/email_utils.py index bf2fc7c071..36450a594c 100644 --- a/openedx/core/djangoapps/credit/email_utils.py +++ b/openedx/core/djangoapps/credit/email_utils.py @@ -2,14 +2,17 @@ This file contains utility functions which will responsible for sending emails. """ -import HTMLParser +from __future__ import absolute_import + import logging import os -import urlparse import uuid from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart +import six +import six.moves.html_parser # pylint: disable=import-error +import six.moves.urllib.parse # pylint: disable=import-error from django.conf import settings from django.contrib.auth.models import User from django.contrib.staticfiles import finders @@ -17,10 +20,10 @@ from django.core.cache import cache from django.core.mail import EmailMessage, SafeMIMEText from django.urls import reverse from django.utils.translation import ugettext as _ +from eventtracking import tracker from edxmako.shortcuts import render_to_string from edxmako.template import Template -from eventtracking import tracker from openedx.core.djangoapps.commerce.utils import ecommerce_api_client from openedx.core.djangoapps.credit.models import CreditConfig, CreditProvider from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers @@ -106,7 +109,7 @@ def send_credit_notifications(username, course_key): cur_text = cur_file.read() # use html parser to unescape html characters which are changed # by the 'pynliner' while adding inline css to html content - html_parser = HTMLParser.HTMLParser() + html_parser = six.moves.html_parser.HTMLParser() email_body_content = html_parser.unescape(with_inline_css(cur_text)) # cache the email body content before rendering it since the # email context will change for each user e.g., 'full_name' @@ -193,7 +196,7 @@ def _email_url_parser(url_name, extra_param=None): site_name = configuration_helpers.get_value('SITE_NAME', settings.SITE_NAME) dashboard_url_path = reverse(url_name) + extra_param if extra_param else reverse(url_name) dashboard_link_parts = ("https", site_name, dashboard_url_path, '', '', '') - return urlparse.urlunparse(dashboard_link_parts) + return six.moves.urllib.parse.urlunparse(dashboard_link_parts) # pylint: disable=too-many-function-args def get_credit_provider_attribute_values(course_key, attribute_name): @@ -206,7 +209,7 @@ def get_credit_provider_attribute_values(course_key, attribute_name): Returns: List of provided credit provider attribute values. """ - course_id = unicode(course_key) + course_id = six.text_type(course_key) credit_config = CreditConfig.current() cache_key = None diff --git a/openedx/core/djangoapps/credit/exceptions.py b/openedx/core/djangoapps/credit/exceptions.py index 306985cdc4..a12b8e7f2c 100644 --- a/openedx/core/djangoapps/credit/exceptions.py +++ b/openedx/core/djangoapps/credit/exceptions.py @@ -1,11 +1,10 @@ """Exceptions raised by the credit API. """ -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals from django.utils.translation import ugettext_lazy as _ from rest_framework import status from rest_framework.exceptions import APIException - # TODO: Cleanup this mess! ECOM-2908 diff --git a/openedx/core/djangoapps/credit/models.py b/openedx/core/djangoapps/credit/models.py index 11693fe9cd..4c8472279d 100644 --- a/openedx/core/djangoapps/credit/models.py +++ b/openedx/core/djangoapps/credit/models.py @@ -6,11 +6,14 @@ Credit courses allow students to receive university credit for successful completion of a course on EdX """ +from __future__ import absolute_import + import datetime import logging from collections import defaultdict import pytz +import six from config_models.models import ConfigurationModel from django.conf import settings from django.core.cache import cache @@ -239,12 +242,12 @@ class CreditCourse(models.Model): credit_courses = cache.get(cls.CREDIT_COURSES_CACHE_KEY) if credit_courses is None: credit_courses = set( - unicode(course.course_key) + six.text_type(course.course_key) for course in cls.objects.filter(enabled=True) ) cache.set(cls.CREDIT_COURSES_CACHE_KEY, credit_courses) - return unicode(course_key) in credit_courses + return six.text_type(course_key) in credit_courses @classmethod def get_credit_course(cls, course_key): @@ -264,7 +267,7 @@ class CreditCourse(models.Model): def __unicode__(self): """Unicode representation of the credit course. """ - return unicode(self.course_key) + return six.text_type(self.course_key) @receiver(models.signals.post_save, sender=CreditCourse) diff --git a/openedx/core/djangoapps/credit/routers.py b/openedx/core/djangoapps/credit/routers.py index 33a031a6da..461c218d18 100644 --- a/openedx/core/djangoapps/credit/routers.py +++ b/openedx/core/djangoapps/credit/routers.py @@ -1,5 +1,7 @@ """ DRF routers. """ +from __future__ import absolute_import + from rest_framework import routers diff --git a/openedx/core/djangoapps/credit/serializers.py b/openedx/core/djangoapps/credit/serializers.py index ccb2e691e1..40f0f91c6d 100644 --- a/openedx/core/djangoapps/credit/serializers.py +++ b/openedx/core/djangoapps/credit/serializers.py @@ -1,11 +1,12 @@ """ Credit API Serializers """ -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals import datetime import logging import pytz +import six from django.conf import settings from rest_framework import serializers from rest_framework.exceptions import PermissionDenied @@ -47,7 +48,7 @@ class CreditEligibilitySerializer(serializers.ModelSerializer): def get_course_key(self, obj): """ Returns the course key associated with the course. """ - return unicode(obj.course.course_key) + return six.text_type(obj.course.course_key) class Meta(object): model = CreditEligibility diff --git a/openedx/core/djangoapps/credit/services.py b/openedx/core/djangoapps/credit/services.py index 50e4a1d27e..3cad7f56d4 100644 --- a/openedx/core/djangoapps/credit/services.py +++ b/openedx/core/djangoapps/credit/services.py @@ -2,8 +2,11 @@ Implementation of "credit" XBlock service """ +from __future__ import absolute_import + import logging +import six from django.contrib.auth.models import User from django.core.exceptions import ObjectDoesNotExist from opaque_keys.edx.keys import CourseKey @@ -21,7 +24,7 @@ def _get_course_key(course_key_or_id): """ return ( CourseKey.from_string(course_key_or_id) - if isinstance(course_key_or_id, basestring) + if isinstance(course_key_or_id, six.string_types) else course_key_or_id ) diff --git a/openedx/core/djangoapps/credit/signals.py b/openedx/core/djangoapps/credit/signals.py index 33ce52a7c9..8762b15a35 100644 --- a/openedx/core/djangoapps/credit/signals.py +++ b/openedx/core/djangoapps/credit/signals.py @@ -2,8 +2,11 @@ This file contains receivers of course publication signals. """ +from __future__ import absolute_import + import logging +import six from django.dispatch import receiver from django.utils import timezone from opaque_keys.edx.keys import CourseKey @@ -27,7 +30,7 @@ def on_course_publish(course_key): from openedx.core.djangoapps.credit import api, tasks if api.is_credit_course(course_key): - tasks.update_credit_course_requirements.delay(unicode(course_key)) + tasks.update_credit_course_requirements.delay(six.text_type(course_key)) log.info(u'Added task to update credit requirements for course "%s" to the task queue', course_key) @@ -49,7 +52,7 @@ def listen_for_grade_calculation(sender, user, course_grade, course_key, deadlin # This needs to be imported here to avoid a circular dependency # that can cause migrations to fail. from openedx.core.djangoapps.credit import api - course_id = CourseKey.from_string(unicode(course_key)) + course_id = CourseKey.from_string(six.text_type(course_key)) is_credit = api.is_credit_course(course_id) if is_credit: requirements = api.get_credit_requirements(course_id, namespace='grade') diff --git a/openedx/core/djangoapps/credit/signature.py b/openedx/core/djangoapps/credit/signature.py index 34a685c294..47aebfc468 100644 --- a/openedx/core/djangoapps/credit/signature.py +++ b/openedx/core/djangoapps/credit/signature.py @@ -16,10 +16,13 @@ we receive from the credit provider. """ +from __future__ import absolute_import + import hashlib import hmac import logging +import six from django.conf import settings log = logging.getLogger(__name__) @@ -31,7 +34,7 @@ def get_shared_secret_key(provider_id): """ secret = getattr(settings, "CREDIT_PROVIDER_SECRET_KEYS", {}).get(provider_id) - if isinstance(secret, unicode): + if isinstance(secret, six.text_type): try: secret = str(secret) except UnicodeEncodeError: diff --git a/openedx/core/djangoapps/credit/tasks.py b/openedx/core/djangoapps/credit/tasks.py index 81682bccb0..ad611c5991 100644 --- a/openedx/core/djangoapps/credit/tasks.py +++ b/openedx/core/djangoapps/credit/tasks.py @@ -2,6 +2,9 @@ This file contains celery tasks for credit course views. """ +from __future__ import absolute_import + +import six from celery import task from celery.utils.log import get_task_logger from django.conf import settings @@ -36,7 +39,7 @@ def update_credit_course_requirements(course_id): requirements = _get_course_credit_requirements(course_key) set_credit_requirements(course_key, requirements) except (InvalidKeyError, ItemNotFoundError, InvalidCreditRequirements) as exc: - LOGGER.error(u'Error on adding the requirements for course %s - %s', course_id, unicode(exc)) + LOGGER.error(u'Error on adding the requirements for course %s - %s', course_id, six.text_type(exc)) raise update_credit_course_requirements.retry(args=[course_id], exc=exc) else: LOGGER.info(u'Requirements added for course %s', course_id) @@ -95,7 +98,7 @@ def _get_min_grade_requirement(course_key): } ] except AttributeError: - LOGGER.error(u"The course %s does not has minimum_grade_credit attribute", unicode(course.id)) + LOGGER.error(u"The course %s does not has minimum_grade_credit attribute", six.text_type(course.id)) else: return [] @@ -121,7 +124,7 @@ def _get_proctoring_requirements(course_key): from edx_proctoring.api import get_all_exams_for_course requirements = [] - for exam in get_all_exams_for_course(unicode(course_key)): + for exam in get_all_exams_for_course(six.text_type(course_key)): if exam['is_proctored'] and exam['is_active'] and not exam['is_practice_exam']: try: usage_key = UsageKey.from_string(exam['content_id']) diff --git a/openedx/core/djangoapps/credit/urls.py b/openedx/core/djangoapps/credit/urls.py index 8621edca5f..736ea9514d 100644 --- a/openedx/core/djangoapps/credit/urls.py +++ b/openedx/core/djangoapps/credit/urls.py @@ -1,6 +1,8 @@ """ URLs for the credit app. """ +from __future__ import absolute_import + from django.conf.urls import include, url from openedx.core.djangoapps.credit import models, routers, views diff --git a/openedx/core/djangoapps/credit/utils.py b/openedx/core/djangoapps/credit/utils.py index ad4c6cb486..d69e6b403f 100644 --- a/openedx/core/djangoapps/credit/utils.py +++ b/openedx/core/djangoapps/credit/utils.py @@ -1,6 +1,8 @@ """ Utilities for the credit app. """ +from __future__ import absolute_import + from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.django import modulestore diff --git a/openedx/core/djangoapps/credit/views.py b/openedx/core/djangoapps/credit/views.py index 8ea058a4fb..20b657da9c 100644 --- a/openedx/core/djangoapps/credit/views.py +++ b/openedx/core/djangoapps/credit/views.py @@ -1,12 +1,13 @@ """ Views for the credit Django app. """ -from __future__ import unicode_literals +from __future__ import absolute_import, unicode_literals import datetime import logging import pytz +import six from django.conf import settings from django.utils.decorators import method_decorator from django.views.decorators.csrf import csrf_exempt @@ -158,7 +159,7 @@ class CreditEligibilityView(generics.ListAPIView): raise ValidationError( {'detail': 'Both the course_key and username querystring parameters must be supplied.'}) - course_key = unicode(course_key) + course_key = six.text_type(course_key) try: course_key = CourseKey.from_string(course_key)