diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index f5b3196ccb19..fbe04186c43c 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -143,7 +143,7 @@ def get_lms_link_for_item(location, preview=False, course_id=None): else: lms_base = settings.LMS_BASE - lms_link = "//{lms_base}/courses/{course_id}/jump_to/{location}".format( + lms_link = u"//{lms_base}/courses/{course_id}/jump_to/{location}".format( lms_base=lms_base, course_id=course_id, location=Location(location) @@ -179,7 +179,7 @@ def get_lms_link_for_about_page(location): about_base = None if about_base is not None: - lms_link = "//{about_base_url}/courses/{course_id}/about".format( + lms_link = u"//{about_base_url}/courses/{course_id}/about".format( about_base_url=about_base, course_id=Location(location).course_id ) diff --git a/cms/djangoapps/contentstore/views/component.py b/cms/djangoapps/contentstore/views/component.py index d466bbe73238..8c1bcb7a9df4 100644 --- a/cms/djangoapps/contentstore/views/component.py +++ b/cms/djangoapps/contentstore/views/component.py @@ -267,8 +267,7 @@ def unit_handler(request, tag=None, package_id=None, branch=None, version_guid=N preview_lms_base = settings.FEATURES.get('PREVIEW_LMS_BASE') preview_lms_link = ( - '//{preview_lms_base}/courses/{org}/{course}/' - '{course_name}/courseware/{section}/{subsection}/{index}' + u'//{preview_lms_base}/courses/{org}/{course}/{course_name}/courseware/{section}/{subsection}/{index}' ).format( preview_lms_base=preview_lms_base, lms_base=settings.LMS_BASE, diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index 89c5a33db779..e930e33c1a5e 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -251,7 +251,7 @@ def create_new_course(request): run = request.json.get('run') try: - dest_location = Location('i4x', org, number, 'course', run) + dest_location = Location(u'i4x', org, number, u'course', run) except InvalidLocationError as error: return JsonResponse({ "ErrMsg": _("Unable to create course '{name}'.\n\n{err}").format( @@ -286,8 +286,10 @@ def create_new_course(request): course_search_location = bson.son.SON({ '_id.tag': 'i4x', # cannot pass regex to Location constructor; thus this hack - '_id.org': re.compile('^{}$'.format(dest_location.org), re.IGNORECASE), - '_id.course': re.compile('^{}$'.format(dest_location.course), re.IGNORECASE), + # pylint: disable=E1101 + '_id.org': re.compile(u'^{}$'.format(dest_location.org), re.IGNORECASE | re.UNICODE), + # pylint: disable=E1101 + '_id.course': re.compile(u'^{}$'.format(dest_location.course), re.IGNORECASE | re.UNICODE), '_id.category': 'course', }) courses = modulestore().collection.find(course_search_location, fields=('_id')) diff --git a/cms/djangoapps/contentstore/views/preview.py b/cms/djangoapps/contentstore/views/preview.py index 19b351d59cb0..11bea40f9fa6 100644 --- a/cms/djangoapps/contentstore/views/preview.py +++ b/cms/djangoapps/contentstore/views/preview.py @@ -41,7 +41,7 @@ def handler_prefix(block, handler='', suffix=''): Trailing `/`s are removed from the returned url. """ return reverse('preview_handler', kwargs={ - 'usage_id': quote_slashes(str(block.scope_ids.usage_id)), + 'usage_id': quote_slashes(unicode(block.scope_ids.usage_id).encode('utf-8')), 'handler': handler, 'suffix': suffix, }).rstrip('/?') diff --git a/cms/static/js/index.js b/cms/static/js/index.js index d8a6903763c2..fff1923f4dba 100644 --- a/cms/static/js/index.js +++ b/cms/static/js/index.js @@ -84,8 +84,8 @@ require(["domReady", "jquery", "underscore", "js/utils/cancel_on_escape"], if (required) { return required; } - if (item !== encodeURIComponent(item)) { - return gettext('Please do not use any spaces or special characters in this field.'); + if (/\s/g.test(item)) { + return gettext('Please do not use any spaces in this field.'); } return ''; }; diff --git a/cms/templates/unit.html b/cms/templates/unit.html index 1151b4c5523c..04d73d8efd94 100644 --- a/cms/templates/unit.html +++ b/cms/templates/unit.html @@ -164,7 +164,7 @@

${_("Unit Settings")}

% endif ${_("with the subsection {link_start}{name}{link_end}").format( name=subsection.display_name_with_default, - link_start=''.format(url=subsection_url), + link_start=u''.format(url=subsection_url), link_end='', )}

diff --git a/common/djangoapps/cache_toolbox/core.py b/common/djangoapps/cache_toolbox/core.py index 9a7be940b894..3321f83d5ed2 100644 --- a/common/djangoapps/cache_toolbox/core.py +++ b/common/djangoapps/cache_toolbox/core.py @@ -110,12 +110,12 @@ def instance_key(model, instance_or_pk): def set_cached_content(content): - cache.set(str(content.location), content) + cache.set(unicode(content.location).encode("utf-8"), content) def get_cached_content(location): - return cache.get(str(location)) + return cache.get(unicode(location).encode("utf-8")) def del_cached_content(location): - cache.delete(str(location)) + cache.delete(unicode(location).encode("utf-8")) diff --git a/common/djangoapps/course_groups/cohorts.py b/common/djangoapps/course_groups/cohorts.py index d2c7e3a782f5..c6b93e563490 100644 --- a/common/djangoapps/course_groups/cohorts.py +++ b/common/djangoapps/course_groups/cohorts.py @@ -77,7 +77,7 @@ def is_commentable_cohorted(course_id, commentable_id): # inline discussions are cohorted by default ans = True - log.debug("is_commentable_cohorted({0}, {1}) = {2}".format(course_id, + log.debug(u"is_commentable_cohorted({0}, {1}) = {2}".format(course_id, commentable_id, ans)) return ans diff --git a/common/djangoapps/static_replace/__init__.py b/common/djangoapps/static_replace/__init__.py index a05129d86441..29dcf7455b03 100644 --- a/common/djangoapps/static_replace/__init__.py +++ b/common/djangoapps/static_replace/__init__.py @@ -19,7 +19,7 @@ def _url_replace_regex(prefix): To anyone contemplating making this more complicated: http://xkcd.com/1171/ """ - return r""" + return ur""" (?x) # flags=re.VERBOSE (?P\\?['"]) # the opening quotes (?P{prefix}) # the prefix @@ -152,7 +152,7 @@ def replace_static_url(match): return "".join([quote, url, quote]) return re.sub( - _url_replace_regex('(?:{static_url}|/static/)(?!{data_dir})'.format( + _url_replace_regex(u'(?:{static_url}|/static/)(?!{data_dir})'.format( static_url=settings.STATIC_URL, data_dir=static_asset_path or data_directory )), diff --git a/common/djangoapps/student/roles.py b/common/djangoapps/student/roles.py index daf3f6ee025b..a0783196b5de 100644 --- a/common/djangoapps/student/roles.py +++ b/common/djangoapps/student/roles.py @@ -159,30 +159,30 @@ def __init__(self, role, location, course_context=None): if isinstance(self.location, Location): try: - groupnames.append('{0}_{1}'.format(role, self.location.course_id)) + groupnames.append(u'{0}_{1}'.format(role, self.location.course_id)) course_context = self.location.course_id # course_id is valid for translation except InvalidLocationError: # will occur on old locations where location is not of category course if course_context is None: raise CourseContextRequired() else: - groupnames.append('{0}_{1}'.format(role, course_context)) + groupnames.append(u'{0}_{1}'.format(role, course_context)) try: locator = loc_mapper().translate_location_to_course_locator(course_context, self.location) - groupnames.append('{0}_{1}'.format(role, locator.package_id)) + groupnames.append(u'{0}_{1}'.format(role, locator.package_id)) except (InvalidLocationError, ItemNotFoundError): # if it's never been mapped, the auth won't be via the Locator syntax pass # least preferred legacy role_course format - groupnames.append('{0}_{1}'.format(role, self.location.course)) + groupnames.append(u'{0}_{1}'.format(role, self.location.course)) # pylint: disable=E1101, E1103 elif isinstance(self.location, CourseLocator): - groupnames.append('{0}_{1}'.format(role, self.location.package_id)) + groupnames.append(u'{0}_{1}'.format(role, self.location.package_id)) # handle old Location syntax old_location = loc_mapper().translate_locator_to_location(self.location, get_course=True) if old_location: # the slashified version of the course_id (myu/mycourse/myrun) - groupnames.append('{0}_{1}'.format(role, old_location.course_id)) + groupnames.append(u'{0}_{1}'.format(role, old_location.course_id)) # add the least desirable but sometimes occurring format. - groupnames.append('{0}_{1}'.format(role, old_location.course)) + groupnames.append(u'{0}_{1}'.format(role, old_location.course)) # pylint: disable=E1101, E1103 super(CourseRole, self).__init__(groupnames) @@ -193,12 +193,13 @@ class OrgRole(GroupBasedRole): """ def __init__(self, role, location): location = Location(location) - super(OrgRole, self).__init__(['{}_{}'.format(role, location.org)]) + super(OrgRole, self).__init__([u'{}_{}'.format(role, location.org)]) class CourseStaffRole(CourseRole): """A Staff member of a course""" ROLE = 'staff' + def __init__(self, *args, **kwargs): super(CourseStaffRole, self).__init__(self.ROLE, *args, **kwargs) diff --git a/common/djangoapps/student/views.py b/common/djangoapps/student/views.py index 007b894900da..5ab43a161d87 100644 --- a/common/djangoapps/student/views.py +++ b/common/djangoapps/student/views.py @@ -353,7 +353,7 @@ def dashboard(request): course_enrollment_pairs.append((course, enrollment)) except ItemNotFoundError: - log.error("User {0} enrolled in non-existent course {1}" + log.error(u"User {0} enrolled in non-existent course {1}" .format(user.username, enrollment.course_id)) course_optouts = Optout.objects.filter(user=user).values_list('course_id', flat=True) @@ -495,9 +495,9 @@ def change_enrollment(request): org, course_num, run = course_id.split("/") dog_stats_api.increment( "common.student.enrollment", - tags=["org:{0}".format(org), - "course:{0}".format(course_num), - "run:{0}".format(run)] + tags=[u"org:{0}".format(org), + u"course:{0}".format(course_num), + u"run:{0}".format(run)] ) CourseEnrollment.enroll(user, course.id, mode=current_mode.slug) diff --git a/common/lib/capa/capa/capa_problem.py b/common/lib/capa/capa/capa_problem.py index f011b3813e22..d14af5b0d8fa 100644 --- a/common/lib/capa/capa/capa_problem.py +++ b/common/lib/capa/capa/capa_problem.py @@ -372,7 +372,7 @@ def _grade_answers(self, student_answers): # TODO: figure out where to get file submissions when rescoring. if 'filesubmission' in responder.allowed_inputfields and student_answers is None: _ = self.capa_system.i18n.ugettext - raise Exception(_("Cannot rescore problems with possible file submissions")) + raise Exception(_(u"Cannot rescore problems with possible file submissions")) # use 'student_answers' only if it is provided, and if it might contain a file # submission that would not exist in the persisted "student_answers". diff --git a/common/lib/capa/capa/correctmap.py b/common/lib/capa/capa/correctmap.py index 2ea4a35c024d..df7efee343c6 100644 --- a/common/lib/capa/capa/correctmap.py +++ b/common/lib/capa/capa/correctmap.py @@ -50,7 +50,7 @@ def set( ): if answer_id is not None: - self.cmap[str(answer_id)] = { + self.cmap[answer_id] = { 'correctness': correctness, 'npoints': npoints, 'msg': msg, diff --git a/common/lib/capa/capa/xqueue_interface.py b/common/lib/capa/capa/xqueue_interface.py index 270b696f9f40..78b9fcd008f3 100644 --- a/common/lib/capa/capa/xqueue_interface.py +++ b/common/lib/capa/capa/xqueue_interface.py @@ -62,7 +62,7 @@ class XQueueInterface(object): """ def __init__(self, url, django_auth, requests_auth=None): - self.url = url + self.url = unicode(url) self.auth = django_auth self.session = requests.Session() self.session.auth = requests_auth diff --git a/common/lib/xmodule/xmodule/contentstore/content.py b/common/lib/xmodule/xmodule/contentstore/content.py index 61ff0bc1927a..50e7f5d84842 100644 --- a/common/lib/xmodule/xmodule/contentstore/content.py +++ b/common/lib/xmodule/xmodule/contentstore/content.py @@ -34,7 +34,9 @@ def is_thumbnail(self): @staticmethod def generate_thumbnail_name(original_name): - return ('{0}' + XASSET_THUMBNAIL_TAIL_NAME).format(os.path.splitext(original_name)[0]) + return u"{name_root}{extension}".format( + name_root=os.path.splitext(original_name)[0], + extension=XASSET_THUMBNAIL_TAIL_NAME,) @staticmethod def compute_location(org, course, name, revision=None, is_thumbnail=False): @@ -64,7 +66,7 @@ def is_c4x_path(path_string): """ Returns a boolean if a path is believed to be a c4x link based on the leading element """ - return path_string.startswith('/{0}/'.format(XASSET_LOCATION_TAG)) + return path_string.startswith(u'/{0}/'.format(XASSET_LOCATION_TAG)) @staticmethod def renamespace_c4x_path(path_string, target_location): @@ -86,14 +88,14 @@ def get_static_path_from_location(location): the actual /c4x/... path which the client needs to reference static content """ if location is not None: - return "/static/{name}".format(**location.dict()) + return u"/static/{name}".format(**location.dict()) else: return None @staticmethod def get_base_url_path_for_course_assets(loc): if loc is not None: - return "/c4x/{org}/{course}/asset".format(**loc.dict()) + return u"/c4x/{org}/{course}/asset".format(**loc.dict()) @staticmethod def get_id_from_location(location): @@ -237,6 +239,6 @@ def generate_thumbnail(self, content, tempfile_path=None): except Exception, e: # log and continue as thumbnails are generally considered as optional - logging.exception("Failed to generate thumbnail for {0}. Exception: {1}".format(content.location, str(e))) + logging.exception(u"Failed to generate thumbnail for {0}. Exception: {1}".format(content.location, str(e))) return thumbnail_content, thumbnail_file_location diff --git a/common/lib/xmodule/xmodule/modulestore/__init__.py b/common/lib/xmodule/xmodule/modulestore/__init__.py index 89b8e80d15b9..5d241731a7e4 100644 --- a/common/lib/xmodule/xmodule/modulestore/__init__.py +++ b/common/lib/xmodule/xmodule/modulestore/__init__.py @@ -30,12 +30,12 @@ # TODO (cpennington): We should decide whether we want to expand the # list of valid characters in a location -INVALID_CHARS = re.compile(r"[^\w.-]") +INVALID_CHARS = re.compile(r"[^\w.%-]", re.UNICODE) # Names are allowed to have colons. -INVALID_CHARS_NAME = re.compile(r"[^\w.:-]") +INVALID_CHARS_NAME = re.compile(r"[^\w.:%-]", re.UNICODE) # html ids can contain word chars and dashes -INVALID_HTML_CHARS = re.compile(r"[^\w-]") +INVALID_HTML_CHARS = re.compile(r"[^\w-]", re.UNICODE) _LocationBase = namedtuple('LocationBase', 'tag org course category name revision') @@ -186,14 +186,14 @@ def check_list(list_): elif isinstance(location, basestring): match = URL_RE.match(location) if match is None: - log.debug("location %r doesn't match URL", location) + log.debug(u"location %r doesn't match URL", location) raise InvalidLocationError(location) groups = match.groupdict() check_dict(groups) return _LocationBase.__new__(_cls, **groups) elif isinstance(location, (list, tuple)): if len(location) not in (5, 6): - log.debug('location has wrong length') + log.debug(u'location has wrong length') raise InvalidLocationError(location) if len(location) == 5: @@ -216,9 +216,9 @@ def url(self): """ Return a string containing the URL for this location """ - url = "{0.tag}://{0.org}/{0.course}/{0.category}/{0.name}".format(self) + url = u"{0.tag}://{0.org}/{0.course}/{0.category}/{0.name}".format(self) if self.revision: - url += "@" + self.revision + url += u"@{rev}".format(rev=self.revision) # pylint: disable=E1101 return url def html_id(self): @@ -226,7 +226,7 @@ def html_id(self): Return a string with a version of the location that is safe for use in html id attributes """ - id_string = "-".join(str(v) for v in self.list() if v is not None) + id_string = u"-".join(v for v in self.list() if v is not None) return Location.clean_for_html(id_string) def dict(self): @@ -240,6 +240,9 @@ def list(self): return list(self) def __str__(self): + return str(self.url().encode("utf-8")) + + def __unicode__(self): return self.url() def __repr__(self): @@ -254,7 +257,7 @@ def course_id(self): Throws an InvalidLocationError is this location does not represent a course. """ if self.category != 'course': - raise InvalidLocationError('Cannot call course_id for {0} because it is not of category course'.format(self)) + raise InvalidLocationError(u'Cannot call course_id for {0} because it is not of category course'.format(self)) return "/".join([self.org, self.course, self.name]) diff --git a/common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py b/common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py index 7e00abfdace2..37853d07896a 100644 --- a/common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py +++ b/common/lib/xmodule/xmodule/modulestore/loc_mapper_store.py @@ -88,9 +88,9 @@ def create_map_entry(self, course_location, package_id=None, draft_branch='draft """ if package_id is None: if course_location.category == 'course': - package_id = "{0.org}.{0.course}.{0.name}".format(course_location) + package_id = u"{0.org}.{0.course}.{0.name}".format(course_location) else: - package_id = "{0.org}.{0.course}".format(course_location) + package_id = u"{0.org}.{0.course}".format(course_location) # very like _interpret_location_id but w/o the _id location_id = self._construct_location_son( course_location.org, course_location.course, @@ -185,7 +185,6 @@ def translate_location(self, old_style_course_id, location, published=True, add_ self._cache_location_map_entry(old_style_course_id, location, published_usage, draft_usage) return result - def translate_locator_to_location(self, locator, get_course=False): """ Returns an old style Location for the given Locator if there's an appropriate entry in the @@ -331,12 +330,12 @@ def _generate_location_course_id(self, entry_id): # strip id envelope if any entry_id = entry_id.get('_id', entry_id) if entry_id.get('name', False): - return '{0[org]}/{0[course]}/{0[name]}'.format(entry_id) + return u'{0[org]}/{0[course]}/{0[name]}'.format(entry_id) elif entry_id.get('_id.org', False): # the odd format one - return '{0[_id.org]}/{0[_id.course]}'.format(entry_id) + return u'{0[_id.org]}/{0[_id.course]}'.format(entry_id) else: - return '{0[org]}/{0[course]}'.format(entry_id) + return u'{0[org]}/{0[course]}'.format(entry_id) def _construct_location_son(self, org, course, name=None): """ @@ -392,7 +391,7 @@ def _get_locator_from_cache(self, old_course_id, location, published): """ See if the location x published pair is in the cache. If so, return the mapped locator. """ - entry = self.cache.get('{}+{}'.format(old_course_id, location.url())) + entry = self.cache.get(u'{}+{}'.format(old_course_id, location.url())) if entry is not None: if published: return entry[0] @@ -424,7 +423,7 @@ def _get_course_location_from_cache(self, locator_package_id): See if the package_id is in the cache. If so, return the mapped location to the course root. """ - return self.cache.get('courseId+{}'.format(locator_package_id)) + return self.cache.get(u'courseId+{}'.format(locator_package_id)) def _cache_course_locator(self, old_course_id, published_course_locator, draft_course_locator): """ @@ -442,9 +441,9 @@ def _cache_location_map_entry(self, old_course_id, location, published_usage, dr """ setmany = {} if location.category == 'course': - setmany['courseId+{}'.format(published_usage.package_id)] = location + setmany[u'courseId+{}'.format(published_usage.package_id)] = location setmany[unicode(published_usage)] = location setmany[unicode(draft_usage)] = location - setmany['{}+{}'.format(old_course_id, location.url())] = (published_usage, draft_usage) + setmany[u'{}+{}'.format(old_course_id, location.url())] = (published_usage, draft_usage) setmany[old_course_id] = (published_usage, draft_usage) self.cache.set_many(setmany) diff --git a/common/lib/xmodule/xmodule/modulestore/locator.py b/common/lib/xmodule/xmodule/modulestore/locator.py index bde6cee83892..2b58797532bf 100644 --- a/common/lib/xmodule/xmodule/modulestore/locator.py +++ b/common/lib/xmodule/xmodule/modulestore/locator.py @@ -64,13 +64,13 @@ def __str__(self): ''' str(self) returns something like this: "mit.eecs.6002x" ''' - return unicode(self).encode('utf8') + return unicode(self).encode('utf-8') def __unicode__(self): ''' unicode(self) returns something like this: "mit.eecs.6002x" ''' - return self.url() + return unicode(self).encode('utf-8') @abstractmethod def version(self): @@ -199,12 +199,12 @@ def __unicode__(self): Return a string representing this location. """ if self.package_id: - result = self.package_id + result = unicode(self.package_id) if self.branch: result += '/' + BRANCH_PREFIX + self.branch return result elif self.version_guid: - return VERSION_PREFIX + str(self.version_guid) + return u"{prefix}{guid}".format(prefix=VERSION_PREFIX, guid=self.version_guid) else: # raise InsufficientSpecificationError("missing package_id or version_guid") return '' @@ -213,7 +213,7 @@ def url(self): """ Return a string containing the URL for this location. """ - return 'edx://' + unicode(self) + return u'edx://' + unicode(self) def _validate_args(self, url, version_guid, package_id): """ @@ -526,7 +526,7 @@ def url(self): Return a string containing the URL for this location. url(self) returns something like this: 'defx://version/519665f6223ebd6980884f2b' """ - return 'defx://' + unicode(self) + return u'defx://' + unicode(self) def version(self): """ diff --git a/common/lib/xmodule/xmodule/modulestore/parsers.py b/common/lib/xmodule/xmodule/modulestore/parsers.py index f1f49febb4c7..9d046effdb67 100644 --- a/common/lib/xmodule/xmodule/modulestore/parsers.py +++ b/common/lib/xmodule/xmodule/modulestore/parsers.py @@ -7,7 +7,8 @@ # Prefix for the version portion of a locator URL, when it is preceded by a course ID VERSION_PREFIX = r"version/" -ALLOWED_ID_CHARS = r'[a-zA-Z0-9_\-~.:]' +ALLOWED_ID_CHARS = r'[\w\-~.:]' + URL_RE_SOURCE = r""" (?Pedx://)? @@ -20,7 +21,7 @@ VERSION_PREFIX=VERSION_PREFIX, BLOCK_PREFIX=BLOCK_PREFIX ) -URL_RE = re.compile('^' + URL_RE_SOURCE + '$', re.IGNORECASE | re.VERBOSE) +URL_RE = re.compile('^' + URL_RE_SOURCE + '$', re.IGNORECASE | re.VERBOSE | re.UNICODE) def parse_url(string, tag_optional=False): @@ -54,7 +55,7 @@ def parse_url(string, tag_optional=False): return matched_dict -BLOCK_RE = re.compile(r'^' + ALLOWED_ID_CHARS + r'+$', re.IGNORECASE) +BLOCK_RE = re.compile(r'^' + ALLOWED_ID_CHARS + r'+$', re.IGNORECASE | re.UNICODE) def parse_block_ref(string): diff --git a/common/lib/xmodule/xmodule/modulestore/store_utilities.py b/common/lib/xmodule/xmodule/modulestore/store_utilities.py index a01eb5e5f1db..9408dc14fd91 100644 --- a/common/lib/xmodule/xmodule/modulestore/store_utilities.py +++ b/common/lib/xmodule/xmodule/modulestore/store_utilities.py @@ -73,13 +73,13 @@ def generic_courseware_link_substitution(match): # NOTE: ultimately link updating is not a hard requirement, so if something blows up with # the regex subsitution, log the error and continue try: - c4x_link_base = '{0}/'.format(StaticContent.get_base_url_path_for_course_assets(course_location)) + c4x_link_base = u'{0}/'.format(StaticContent.get_base_url_path_for_course_assets(course_location)) text = re.sub(_prefix_only_url_replace_regex(c4x_link_base), portable_asset_link_subtitution, text) except Exception, e: logging.warning("Error going regex subtituion %r on text = %r.\n\nError msg = %s", c4x_link_base, text, str(e)) try: - jump_to_link_base = '/courses/{org}/{course}/{run}/jump_to/i4x://{org}/{course}/'.format( + jump_to_link_base = u'/courses/{org}/{course}/{run}/jump_to/i4x://{org}/{course}/'.format( org=org, course=course, run=run ) text = re.sub(_prefix_and_category_url_replace_regex(jump_to_link_base), portable_jump_to_link_substitution, text) @@ -94,7 +94,7 @@ def generic_courseware_link_substitution(match): # if source_course_id != dest_course_id: try: - generic_courseware_link_base = '/courses/{org}/{course}/{run}/'.format( + generic_courseware_link_base = u'/courses/{org}/{course}/{run}/'.format( org=org, course=course, run=run ) text = re.sub(_prefix_only_url_replace_regex(generic_courseware_link_base), portable_asset_link_subtitution, text) diff --git a/common/lib/xmodule/xmodule/tests/test_conditional.py b/common/lib/xmodule/xmodule/tests/test_conditional.py index 74aa83073ffc..0487194dbc7d 100644 --- a/common/lib/xmodule/xmodule/tests/test_conditional.py +++ b/common/lib/xmodule/xmodule/tests/test_conditional.py @@ -129,9 +129,9 @@ def test_get_html(self): html = modules['cond_module'].render('student_view').content expected = modules['cond_module'].xmodule_runtime.render_template('conditional_ajax.html', { 'ajax_url': modules['cond_module'].xmodule_runtime.ajax_url, - 'element_id': 'i4x-edX-conditional_test-conditional-SampleConditional', - 'id': 'i4x://edX/conditional_test/conditional/SampleConditional', - 'depends': 'i4x-edX-conditional_test-problem-SampleProblem', + 'element_id': u'i4x-edX-conditional_test-conditional-SampleConditional', + 'id': u'i4x://edX/conditional_test/conditional/SampleConditional', + 'depends': u'i4x-edX-conditional_test-problem-SampleProblem', }) self.assertEquals(expected, html) @@ -225,9 +225,9 @@ def replace_urls(text, staticfiles_prefix=None, replace_prefix='/static/', cours { # Test ajax url is just usage-id / handler_name 'ajax_url': 'i4x://HarvardX/ER22x/conditional/condone/xmodule_handler', - 'element_id': 'i4x-HarvardX-ER22x-conditional-condone', - 'id': 'i4x://HarvardX/ER22x/conditional/condone', - 'depends': 'i4x-HarvardX-ER22x-problem-choiceprob' + 'element_id': u'i4x-HarvardX-ER22x-conditional-condone', + 'id': u'i4x://HarvardX/ER22x/conditional/condone', + 'depends': u'i4x-HarvardX-ER22x-problem-choiceprob' } ) self.assertEqual(html, html_expect) diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py index 51d077c68607..9fe208fd0474 100644 --- a/common/lib/xmodule/xmodule/x_module.py +++ b/common/lib/xmodule/xmodule/x_module.py @@ -223,7 +223,7 @@ def get_children(self): try: child = self.runtime.get_block(child_loc) except ItemNotFoundError: - log.exception('Unable to load item {loc}, skipping'.format(loc=child_loc)) + log.exception(u'Unable to load item {loc}, skipping'.format(loc=child_loc)) continue self._child_instances.append(child) @@ -538,7 +538,6 @@ def templates(cls): template = yaml.safe_load(template_content) template['template_id'] = template_file templates.append(template) - return templates @classmethod @@ -546,7 +545,7 @@ def get_template_dir(cls): if getattr(cls, 'template_dir_name', None): dirname = os.path.join('templates', cls.template_dir_name) if not resource_isdir(__name__, dirname): - log.warning("No resource directory {dir} found when loading {cls_name} templates".format( + log.warning(u"No resource directory {dir} found when loading {cls_name} templates".format( dir=dirname, cls_name=cls.__name__, )) diff --git a/lms/djangoapps/bulk_email/tasks.py b/lms/djangoapps/bulk_email/tasks.py index d02045a8be23..5b07f49fa538 100644 --- a/lms/djangoapps/bulk_email/tasks.py +++ b/lms/djangoapps/bulk_email/tasks.py @@ -677,5 +677,5 @@ def _statsd_tag(course_title): """ Calculate the tag we will use for DataDog. """ - tag = "course_email:{0}".format(course_title) + tag = u"course_email:{0}".format(course_title) return tag[:200] diff --git a/lms/djangoapps/courseware/access.py b/lms/djangoapps/courseware/access.py index e5cfc85038dd..8f789915725c 100644 --- a/lms/djangoapps/courseware/access.py +++ b/lms/djangoapps/courseware/access.py @@ -343,7 +343,7 @@ def _dispatch(table, action, user, obj): action) return result - raise ValueError("Unknown action for object type '{0}': '{1}'".format( + raise ValueError(u"Unknown action for object type '{0}': '{1}'".format( type(obj), action)) diff --git a/lms/djangoapps/courseware/module_render.py b/lms/djangoapps/courseware/module_render.py index 51f236adc70f..207e46f63897 100644 --- a/lms/djangoapps/courseware/module_render.py +++ b/lms/djangoapps/courseware/module_render.py @@ -321,10 +321,10 @@ def publish(block, event, custom_user=None): org, course_num, run = course_id.split("/") tags = [ - "org:{0}".format(org), - "course:{0}".format(course_num), - "run:{0}".format(run), - "score_bucket:{0}".format(score_bucket) + u"org:{0}".format(org), + u"course:{0}".format(course_num), + u"run:{0}".format(run), + u"score_bucket:{0}".format(score_bucket) ] if grade_bucket_type is not None: @@ -443,7 +443,7 @@ def publish(block, event, custom_user=None): make_psychometrics_data_update_handler(course_id, user, descriptor.location.url()) ) - system.set('user_is_staff', has_access(user, descriptor.location, 'staff', course_id)) + system.set(u'user_is_staff', has_access(user, descriptor.location, u'staff', course_id)) # make an ErrorDescriptor -- assuming that the descriptor's system is ok if has_access(user, descriptor.location, 'staff', course_id): diff --git a/lms/djangoapps/courseware/views.py b/lms/djangoapps/courseware/views.py index e60b6c5394fc..4e0e97c2bcd9 100644 --- a/lms/djangoapps/courseware/views.py +++ b/lms/djangoapps/courseware/views.py @@ -238,7 +238,7 @@ def index(request, course_id, chapter=None, section=None, registered = registered_for_course(course, user) if not registered: # TODO (vshnayder): do course instructors need to be registered to see course? - log.debug('User %s tried to view course %s but is not enrolled' % (user, course.location.url())) + log.debug(u'User {0} tried to view course {1} but is not enrolled'.format(user, course.location.url())) return redirect(reverse('about_course', args=[course.id])) masq = setup_masquerade(request, staff_access) @@ -249,8 +249,8 @@ def index(request, course_id, chapter=None, section=None, course_module = get_module_for_descriptor(user, request, course, field_data_cache, course.id) if course_module is None: - log.warning('If you see this, something went wrong: if we got this' - ' far, should have gotten a course module for this user') + log.warning(u'If you see this, something went wrong: if we got this' + u' far, should have gotten a course module for this user') return redirect(reverse('about_course', args=[course.id])) if chapter is None: @@ -424,9 +424,9 @@ def jump_to(request, course_id, location): try: (course_id, chapter, section, position) = path_to_location(modulestore(), course_id, location) except ItemNotFoundError: - raise Http404("No data at this location: {0}".format(location)) + raise Http404(u"No data at this location: {0}".format(location)) except NoPathToItem: - raise Http404("This location is not in any class: {0}".format(location)) + raise Http404(u"This location is not in any class: {0}".format(location)) # choose the appropriate view (and provide the necessary args) based on the # args provided by the redirect. diff --git a/lms/djangoapps/django_comment_client/permissions.py b/lms/djangoapps/django_comment_client/permissions.py index 3c83556a7e75..4003dfb460c5 100644 --- a/lms/djangoapps/django_comment_client/permissions.py +++ b/lms/djangoapps/django_comment_client/permissions.py @@ -15,7 +15,8 @@ def cached_has_permission(user, permission, course_id=None): Call has_permission if it's not cached. A change in a user's role or a role's permissions will only become effective after CACHE_LIFESPAN seconds. """ - key = "permission_%d_%s_%s" % (user.id, str(course_id), permission) + key = u"permission_{user_id:d}_{course_id}_{permission}".format( + user_id=user.id, course_id=course_id, permission=permission) val = CACHE.get(key, None) if val not in [True, False]: val = has_permission(user, permission, course_id=course_id) diff --git a/lms/djangoapps/instructor/views/legacy.py b/lms/djangoapps/instructor/views/legacy.py index ae740ad319a0..c671b2892251 100644 --- a/lms/djangoapps/instructor/views/legacy.py +++ b/lms/djangoapps/instructor/views/legacy.py @@ -173,7 +173,7 @@ def get_module_url(urlname): # complete the url using information about the current course: (org, course_name, _) = course_id.split("/") - return "i4x://" + org + "/" + course_name + "/" + urlname + return u"i4x://{org}/{name}/{url}".format(org=org, name=course_name, url=urlname) def get_student_from_identifier(unique_student_identifier): """Gets a student object using either an email address or username""" @@ -782,7 +782,7 @@ def get_analytics_result(analytics_name): logs and swallows errors. """ url = settings.ANALYTICS_SERVER_URL + \ - "get?aname={}&course_id={}&apikey={}".format(analytics_name, + u"get?aname={}&course_id={}&apikey={}".format(analytics_name, course_id, settings.ANALYTICS_API_KEY) try: diff --git a/lms/djangoapps/open_ended_grading/open_ended_notifications.py b/lms/djangoapps/open_ended_grading/open_ended_notifications.py index e99f51283c78..9398a119578b 100644 --- a/lms/djangoapps/open_ended_grading/open_ended_notifications.py +++ b/lms/djangoapps/open_ended_grading/open_ended_notifications.py @@ -66,7 +66,7 @@ def staff_grading_notifications(course, user): def peer_grading_notifications(course, user): system = LmsModuleSystem( track_function=None, - get_module = None, + get_module=None, render_template=render_to_string, replace_urls=None, ) @@ -115,7 +115,7 @@ def combined_notifications(course, user): #Set up return values so that we can return them for error cases pending_grading = False img_path = "" - notifications={} + notifications = {} notification_dict = {'pending_grading': pending_grading, 'img_path': img_path, 'response': notifications} #We don't want to show anonymous users anything. @@ -126,7 +126,7 @@ def combined_notifications(course, user): system = LmsModuleSystem( static_url="/static", track_function=None, - get_module = None, + get_module=None, render_template=render_to_string, replace_urls=None, ) @@ -159,7 +159,7 @@ def combined_notifications(course, user): #Non catastrophic error, so no real action #This is a dev_facing_error log.exception( - "Problem with getting notifications from controller query service for course {0} user {1}.".format( + u"Problem with getting notifications from controller query service for course {0} user {1}.".format( course_id, student_id)) if pending_grading: @@ -185,7 +185,7 @@ def set_value_in_cache(student_id, course_id, notification_type, value): def create_key_name(student_id, course_id, notification_type): - key_name = "{prefix}{type}_{course}_{student}".format(prefix=KEY_PREFIX, type=notification_type, course=course_id, + key_name = u"{prefix}{type}_{course}_{student}".format(prefix=KEY_PREFIX, type=notification_type, course=course_id, student=student_id) return key_name diff --git a/lms/djangoapps/open_ended_grading/staff_grading_service.py b/lms/djangoapps/open_ended_grading/staff_grading_service.py index 090b36d13c32..81a2eb401c53 100644 --- a/lms/djangoapps/open_ended_grading/staff_grading_service.py +++ b/lms/djangoapps/open_ended_grading/staff_grading_service.py @@ -66,7 +66,6 @@ def get_problem_list(self, course_id, grader_id): 'min_for_ml': 10}) ]}) - def save_grade(self, course_id, grader_id, submission_id, score, feedback, skipped, rubric_scores, submission_flagged): return self.get_next(course_id, 'fake location', grader_id) @@ -81,7 +80,7 @@ def __init__(self, config): config['system'] = LmsModuleSystem( static_url='/static', track_function=None, - get_module = None, + get_module=None, render_template=render_to_string, replace_urls=None, ) @@ -93,7 +92,6 @@ def __init__(self, config): self.get_problem_list_url = self.url + '/get_problem_list/' self.get_notifications_url = self.url + "/get_notifications/" - def get_problem_list(self, course_id, grader_id): """ Get the list of problems for a given course. @@ -113,7 +111,6 @@ def get_problem_list(self, course_id, grader_id): params = {'course_id': course_id, 'grader_id': grader_id} return self.get(self.get_problem_list_url, params) - def get_next(self, course_id, location, grader_id): """ Get the next thing to grade. @@ -137,7 +134,6 @@ def get_next(self, course_id, location, grader_id): 'grader_id': grader_id}) return json.dumps(self._render_rubric(response)) - def save_grade(self, course_id, grader_id, submission_id, score, feedback, skipped, rubric_scores, submission_flagged): """ diff --git a/lms/lib/xblock/runtime.py b/lms/lib/xblock/runtime.py index cb2c0330251b..74066a6af13d 100644 --- a/lms/lib/xblock/runtime.py +++ b/lms/lib/xblock/runtime.py @@ -35,7 +35,7 @@ def quote_slashes(text): ';;'. By making the escape sequence fixed length, and escaping identifier character ';', we are able to reverse the escaping. """ - return re.sub(r'[;/]', _quote_slashes, text) + return re.sub(ur'[;/]', _quote_slashes, text) def _unquote_slashes(match): @@ -84,7 +84,7 @@ def handler_url(course_id, block, handler, suffix='', query='', thirdparty=False url = reverse(view_name, kwargs={ 'course_id': course_id, - 'usage_id': quote_slashes(str(block.scope_ids.usage_id)), + 'usage_id': quote_slashes(unicode(block.scope_ids.usage_id).encode('utf-8')), 'handler': handler, 'suffix': suffix, })