fix unicode strings in cms/
This commit is contained in:
@@ -80,7 +80,7 @@ def image_is_jpeg_or_png(value):
|
||||
content_type = value.content_type
|
||||
if content_type not in IMAGE_TYPES.keys():
|
||||
raise serializers.ValidationError(
|
||||
'Only JPEG and PNG image types are supported. {} is not valid'.format(content_type))
|
||||
u'Only JPEG and PNG image types are supported. {} is not valid'.format(content_type))
|
||||
|
||||
|
||||
class CourseRunImageField(serializers.ImageField):
|
||||
@@ -169,7 +169,7 @@ class CourseRunRerunSerializer(CourseRunSerializerCommonFieldsMixin, CourseRunTe
|
||||
with store.default_store('split'):
|
||||
new_course_run_key = store.make_course_key(course_run_key.org, course_run_key.course, value)
|
||||
if store.has_course(new_course_run_key, ignore_case=True):
|
||||
raise serializers.ValidationError('Course run {key} already exists'.format(key=new_course_run_key))
|
||||
raise serializers.ValidationError(u'Course run {key} already exists'.format(key=new_course_run_key))
|
||||
return value
|
||||
|
||||
def update(self, instance, validated_data):
|
||||
|
||||
@@ -361,4 +361,4 @@ class CourseRunViewSetTests(ModuleStoreTestCase):
|
||||
}
|
||||
response = self.client.post(url, data, format='json')
|
||||
assert response.status_code == 400
|
||||
assert response.data == {'run': ['Course run {key} already exists'.format(key=course_run.id)]}
|
||||
assert response.data == {'run': [u'Course run {key} already exists'.format(key=course_run.id)]}
|
||||
|
||||
@@ -27,8 +27,8 @@ class CourseRunViewSet(viewsets.GenericViewSet):
|
||||
lookup_url_kwarg = self.lookup_url_kwarg or self.lookup_field
|
||||
|
||||
assert lookup_url_kwarg in self.kwargs, (
|
||||
'Expected view %s to be called with a URL keyword argument '
|
||||
'named "%s". Fix your URL conf, or set the `.lookup_field` '
|
||||
u'Expected view %s to be called with a URL keyword argument '
|
||||
u'named "%s". Fix your URL conf, or set the `.lookup_field` '
|
||||
'attribute on the view correctly.' %
|
||||
(self.__class__.__name__, lookup_url_kwarg)
|
||||
)
|
||||
|
||||
@@ -42,10 +42,10 @@ def send_task_complete_email(self, task_name, task_state_text, dest_addr, detail
|
||||
|
||||
try:
|
||||
mail.send_mail(subject, message, from_address, [dest_addr], fail_silently=False)
|
||||
LOGGER.info("Task complete email has been sent to User %s", dest_addr)
|
||||
LOGGER.info(u"Task complete email has been sent to User %s", dest_addr)
|
||||
except NoAuthHandlerFound:
|
||||
LOGGER.info(
|
||||
'Retrying sending email to user %s, attempt # %s of %s',
|
||||
u'Retrying sending email to user %s, attempt # %s of %s',
|
||||
dest_addr,
|
||||
retries,
|
||||
TASK_COMPLETE_EMAIL_MAX_RETRIES
|
||||
@@ -54,14 +54,14 @@ def send_task_complete_email(self, task_name, task_state_text, dest_addr, detail
|
||||
self.retry(countdown=TASK_COMPLETE_EMAIL_TIMEOUT, max_retries=TASK_COMPLETE_EMAIL_MAX_RETRIES)
|
||||
except MaxRetriesExceededError:
|
||||
LOGGER.error(
|
||||
'Unable to send task completion email to user from "%s" to "%s"',
|
||||
u'Unable to send task completion email to user from "%s" to "%s"',
|
||||
from_address,
|
||||
dest_addr,
|
||||
exc_info=True
|
||||
)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
LOGGER.exception(
|
||||
'Unable to send task completion email to user from "%s" to "%s"',
|
||||
u'Unable to send task completion email to user from "%s" to "%s"',
|
||||
from_address,
|
||||
dest_addr,
|
||||
exc_info=True
|
||||
|
||||
@@ -134,12 +134,12 @@ class CourseImportView(CourseImportExportViewMixin, GenericAPIView):
|
||||
if not course_dir.isdir():
|
||||
os.mkdir(course_dir)
|
||||
|
||||
log.debug('importing course to {0}'.format(temp_filepath))
|
||||
log.debug(u'importing course to {0}'.format(temp_filepath))
|
||||
with open(temp_filepath, "wb+") as temp_file:
|
||||
for chunk in request.FILES['course_data'].chunks():
|
||||
temp_file.write(chunk)
|
||||
|
||||
log.info("Course import %s: Upload complete", course_key)
|
||||
log.info(u"Course import %s: Upload complete", course_key)
|
||||
with open(temp_filepath, 'rb') as local_file:
|
||||
django_file = File(local_file)
|
||||
storage_path = course_import_export_storage.save(u'olx_import/' + filename, django_file)
|
||||
|
||||
@@ -90,7 +90,7 @@ class CourseQualityView(DeveloperErrorViewMixin, GenericAPIView):
|
||||
if log_time:
|
||||
start_time = time.time()
|
||||
output = func(*args)
|
||||
log.info('[%s] completed in [%f]', func.__name__, (time.time() - start_time))
|
||||
log.info(u'[%s] completed in [%f]', func.__name__, (time.time() - start_time))
|
||||
else:
|
||||
output = func(*args)
|
||||
return output
|
||||
|
||||
@@ -194,7 +194,7 @@ class GroupConfiguration(object):
|
||||
for split_test in split_tests:
|
||||
unit = split_test.get_parent()
|
||||
if not unit:
|
||||
log.warning("Unable to find parent for split_test %s", split_test.location)
|
||||
log.warning(u"Unable to find parent for split_test %s", split_test.location)
|
||||
# Make sure that this user_partition appears in the output even though it has no content
|
||||
usage_info[split_test.user_partition_id] = []
|
||||
continue
|
||||
@@ -234,7 +234,7 @@ class GroupConfiguration(object):
|
||||
for item, partition_id, group_id in GroupConfiguration._iterate_items_and_group_ids(course, items):
|
||||
unit = item.get_parent()
|
||||
if not unit:
|
||||
log.warning("Unable to find parent for component %s", item.location)
|
||||
log.warning(u"Unable to find parent for component %s", item.location)
|
||||
continue
|
||||
|
||||
usage_info[partition_id][group_id].append(GroupConfiguration._get_usage_dict(
|
||||
|
||||
@@ -245,8 +245,8 @@ class SearchIndexerBase(object):
|
||||
return item_content_groups
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
# broad exception so that index operation does not fail on one item of many
|
||||
log.warning('Could not index item: %s - %r', item.location, err)
|
||||
error_list.append(_('Could not index item: {}').format(item.location))
|
||||
log.warning(u'Could not index item: %s - %r', item.location, err)
|
||||
error_list.append(_(u'Could not index item: {}').format(item.location))
|
||||
|
||||
try:
|
||||
with modulestore.branch_setting(ModuleStoreEnum.RevisionOption.published_only):
|
||||
@@ -264,7 +264,7 @@ class SearchIndexerBase(object):
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
# broad exception so that index operation does not prevent the rest of the application from working
|
||||
log.exception(
|
||||
"Indexing error encountered, courseware index may be out of date %s - %r",
|
||||
u"Indexing error encountered, courseware index may be out of date %s - %r",
|
||||
structure_key,
|
||||
err
|
||||
)
|
||||
@@ -612,7 +612,7 @@ class CourseAboutSearchIndexer(object):
|
||||
except: # pylint: disable=bare-except
|
||||
section_content = None
|
||||
log.warning(
|
||||
"Course discovery could not collect property %s for course %s",
|
||||
u"Course discovery could not collect property %s for course %s",
|
||||
about_information.property_name,
|
||||
course_id,
|
||||
exc_info=True,
|
||||
@@ -632,13 +632,13 @@ class CourseAboutSearchIndexer(object):
|
||||
searcher.index(cls.DISCOVERY_DOCUMENT_TYPE, [course_info])
|
||||
except:
|
||||
log.exception(
|
||||
"Course discovery indexing error encountered, course discovery index may be out of date %s",
|
||||
u"Course discovery indexing error encountered, course discovery index may be out of date %s",
|
||||
course_id,
|
||||
)
|
||||
raise
|
||||
|
||||
log.debug(
|
||||
"Successfully added %s course to the course discovery index",
|
||||
u"Successfully added %s course to the course discovery index",
|
||||
course_id
|
||||
)
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ def i_press_the_category_delete_icon(_step, category):
|
||||
elif category == 'subsection':
|
||||
css = 'a.action.delete-subsection-button'
|
||||
else:
|
||||
assert False, 'Invalid category: %s' % category
|
||||
assert False, u'Invalid category: %s' % category
|
||||
world.css_click(css)
|
||||
|
||||
|
||||
@@ -93,7 +93,7 @@ def press_the_notification_button(_step, name):
|
||||
# the "Save" button at the UI level.
|
||||
# Instead, we use JavaScript to reliably click
|
||||
# the button.
|
||||
btn_css = 'div#page-notification button.action-%s' % name.lower()
|
||||
btn_css = u'div#page-notification button.action-%s' % name.lower()
|
||||
world.trigger_event(btn_css, event='focus')
|
||||
world.browser.execute_script("$('{}').click()".format(btn_css))
|
||||
world.wait_for_ajax_complete()
|
||||
@@ -299,7 +299,7 @@ def _do_studio_prompt_action(intent, action):
|
||||
|
||||
world.wait_for_present('div.wrapper-prompt.is-shown#prompt-{}'.format(intent))
|
||||
|
||||
action_css = 'li.nav-item > button.action-{}'.format(action)
|
||||
action_css = u'li.nav-item > button.action-{}'.format(action)
|
||||
world.trigger_event(action_css, event='focus')
|
||||
world.browser.execute_script("$('{}').click()".format(action_css))
|
||||
|
||||
@@ -334,7 +334,7 @@ def type_in_codemirror(index, text, find_prefix="$"):
|
||||
|
||||
def get_codemirror_value(index=0, find_prefix="$"):
|
||||
return world.browser.driver.execute_script(
|
||||
"""
|
||||
u"""
|
||||
return {find_prefix}('div.CodeMirror:eq({index})').get(0).CodeMirror.getValue();
|
||||
""".format(index=index, find_prefix=find_prefix)
|
||||
)
|
||||
@@ -351,7 +351,7 @@ def upload_file(filename, sub_path=''):
|
||||
# The file upload dialog is a faux modal, a div that takes over the display
|
||||
attach_file(filename, sub_path)
|
||||
modal_css = 'div.wrapper-modal-window-assetupload'
|
||||
button_css = '{} .action-upload'.format(modal_css)
|
||||
button_css = u'{} .action-upload'.format(modal_css)
|
||||
world.css_click(button_css)
|
||||
|
||||
# Clicking the Upload button triggers an AJAX POST.
|
||||
|
||||
@@ -31,7 +31,7 @@ def see_a_single_step_component(step):
|
||||
assert_in(component, ['Discussion', 'Video'])
|
||||
component_css = '.xmodule_{}Module'.format(component)
|
||||
assert_true(world.is_css_present(component_css),
|
||||
"{} couldn't be found".format(component))
|
||||
u"{} couldn't be found".format(component))
|
||||
|
||||
|
||||
@step(u'I add this type of( Advanced)? (HTML|Problem) component:$')
|
||||
@@ -86,7 +86,7 @@ def see_a_problem_component(step, category):
|
||||
@step(u'I add a "([^"]*)" "([^"]*)" component$')
|
||||
def add_component_category(step, component, category):
|
||||
assert category in ('single step', 'HTML', 'Problem', 'Advanced Problem')
|
||||
given_string = 'I add this type of {} component:'.format(category)
|
||||
given_string = u'I add this type of {} component:'.format(category)
|
||||
step.given('{}\n{}\n{}'.format(given_string, '|Component|', '|{}|'.format(component)))
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ def delete_components(step, number):
|
||||
world.wait_for_xmodule()
|
||||
delete_btn_css = '.delete-button'
|
||||
prompt_css = '#prompt-warning'
|
||||
btn_css = '{} .action-primary'.format(prompt_css)
|
||||
btn_css = u'{} .action-primary'.format(prompt_css)
|
||||
saving_mini_css = '#page-notification .wrapper-notification-mini'
|
||||
for _ in range(int(number)):
|
||||
world.css_click(delete_btn_css)
|
||||
|
||||
@@ -77,7 +77,7 @@ def _find_matching_button(category, component_type):
|
||||
"""
|
||||
|
||||
# The tab shows buttons for the given category
|
||||
buttons = world.css_find('div.new-component-{} button'.format(category))
|
||||
buttons = world.css_find(u'div.new-component-{} button'.format(category))
|
||||
|
||||
# Find the button whose text matches what you're looking for
|
||||
matched_buttons = [btn for btn in buttons if btn.text == component_type]
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
from lettuce import step, world
|
||||
from openedx.core.lib.tests.tools import assert_equal, assert_in # pylint: disable=no-name-in-module
|
||||
|
||||
CSS_FOR_TAB_ELEMENT = "li[data-tab-id='{0}'] input.toggle-checkbox"
|
||||
CSS_FOR_TAB_ELEMENT = u"li[data-tab-id='{0}'] input.toggle-checkbox"
|
||||
|
||||
|
||||
@step(u'I go to the pages page$')
|
||||
|
||||
@@ -34,7 +34,7 @@ class GitExportError(Exception):
|
||||
# Force the lazy i18n values to turn into actual unicode objects
|
||||
super(GitExportError, self).__init__(unicode(message))
|
||||
|
||||
NO_EXPORT_DIR = _("GIT_REPO_EXPORT_DIR not set or path {0} doesn't exist, "
|
||||
NO_EXPORT_DIR = _(u"GIT_REPO_EXPORT_DIR not set or path {0} doesn't exist, "
|
||||
"please create it, or configure a different path with "
|
||||
"GIT_REPO_EXPORT_DIR").format(GIT_REPO_EXPORT_DIR)
|
||||
URL_BAD = _('Non writable git url provided. Expecting something like:'
|
||||
@@ -61,9 +61,9 @@ def cmd_log(cmd, cwd):
|
||||
command doesn't return 0, and returns the command's output.
|
||||
"""
|
||||
output = subprocess.check_output(cmd, cwd=cwd, stderr=subprocess.STDOUT)
|
||||
log.debug('Command was: {0!r}. '
|
||||
'Working directory was: {1!r}'.format(' '.join(cmd), cwd))
|
||||
log.debug('Command output was: {0!r}'.format(output))
|
||||
log.debug(u'Command was: {0!r}. '
|
||||
u'Working directory was: {1!r}'.format(' '.join(cmd), cwd))
|
||||
log.debug(u'Command output was: {0!r}'.format(output))
|
||||
return output
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ def export_to_git(course_id, repo, user='', rdir=None):
|
||||
else:
|
||||
rdir = repo.rsplit('/', 1)[-1].rsplit('.git', 1)[0]
|
||||
|
||||
log.debug("rdir = %s", rdir)
|
||||
log.debug(u"rdir = %s", rdir)
|
||||
|
||||
# Pull or clone repo before exporting to xml
|
||||
# and update url in case origin changed.
|
||||
@@ -107,7 +107,7 @@ def export_to_git(course_id, repo, user='', rdir=None):
|
||||
try:
|
||||
branch = cmd_log(cmd, cwd).strip('\n')
|
||||
except subprocess.CalledProcessError as ex:
|
||||
log.exception('Failed to get branch: %r', ex.output)
|
||||
log.exception(u'Failed to get branch: %r', ex.output)
|
||||
raise GitExportError(GitExportError.DETACHED_HEAD)
|
||||
|
||||
cmds = [
|
||||
@@ -126,7 +126,7 @@ def export_to_git(course_id, repo, user='', rdir=None):
|
||||
try:
|
||||
cmd_log(cmd, cwd)
|
||||
except subprocess.CalledProcessError as ex:
|
||||
log.exception('Failed to pull git repository: %r', ex.output)
|
||||
log.exception(u'Failed to pull git repository: %r', ex.output)
|
||||
raise GitExportError(GitExportError.CANNOT_PULL)
|
||||
|
||||
# export course as xml before commiting and pushing
|
||||
@@ -145,7 +145,7 @@ def export_to_git(course_id, repo, user='', rdir=None):
|
||||
try:
|
||||
branch = cmd_log(cmd, os.path.abspath(rdirp)).strip('\n')
|
||||
except subprocess.CalledProcessError as ex:
|
||||
log.exception('Failed to get branch from freshly cloned repo: %r',
|
||||
log.exception(u'Failed to get branch from freshly cloned repo: %r',
|
||||
ex.output)
|
||||
raise GitExportError(GitExportError.MISSING_BRANCH)
|
||||
|
||||
@@ -161,23 +161,23 @@ def export_to_git(course_id, repo, user='', rdir=None):
|
||||
ident = GIT_EXPORT_DEFAULT_IDENT
|
||||
time_stamp = timezone.now()
|
||||
cwd = os.path.abspath(rdirp)
|
||||
commit_msg = "Export from Studio at {time_stamp}".format(
|
||||
commit_msg = u"Export from Studio at {time_stamp}".format(
|
||||
time_stamp=time_stamp,
|
||||
)
|
||||
try:
|
||||
cmd_log(['git', 'config', 'user.email', ident['email']], cwd)
|
||||
cmd_log(['git', 'config', 'user.name', ident['name']], cwd)
|
||||
except subprocess.CalledProcessError as ex:
|
||||
log.exception('Error running git configure commands: %r', ex.output)
|
||||
log.exception(u'Error running git configure commands: %r', ex.output)
|
||||
raise GitExportError(GitExportError.CONFIG_ERROR)
|
||||
try:
|
||||
cmd_log(['git', 'add', '.'], cwd)
|
||||
cmd_log(['git', 'commit', '-a', '-m', commit_msg], cwd)
|
||||
except subprocess.CalledProcessError as ex:
|
||||
log.exception('Unable to commit changes: %r', ex.output)
|
||||
log.exception(u'Unable to commit changes: %r', ex.output)
|
||||
raise GitExportError(GitExportError.CANNOT_COMMIT)
|
||||
try:
|
||||
cmd_log(['git', 'push', '-q', 'origin', branch], cwd)
|
||||
except subprocess.CalledProcessError as ex:
|
||||
log.exception('Error running git push command: %r', ex.output)
|
||||
log.exception(u'Error running git push command: %r', ex.output)
|
||||
raise GitExportError(GitExportError.CANNOT_PUSH)
|
||||
|
||||
@@ -155,8 +155,8 @@ class Command(BaseCommand):
|
||||
max(len(text_type(result[col])) for result in results + [headers])
|
||||
for col in range(len(results[0]))
|
||||
]
|
||||
id_format = "{{:>{}}} |".format(len(text_type(len(results))))
|
||||
col_format = "| {{:>{}}} |"
|
||||
id_format = u"{{:>{}}} |".format(len(text_type(len(results))))
|
||||
col_format = u"| {{:>{}}} |"
|
||||
|
||||
self.stdout.write(id_format.format(""), ending='')
|
||||
for header, width in zip(headers, col_widths):
|
||||
|
||||
@@ -37,4 +37,4 @@ class Command(BaseCommand):
|
||||
|
||||
if success:
|
||||
log.info("=" * 80)
|
||||
log.info("Total number of assets deleted: {0}".format(assets_deleted))
|
||||
log.info(u"Total number of assets deleted: {0}".format(assets_deleted))
|
||||
|
||||
@@ -22,12 +22,12 @@ class Command(BaseCommand):
|
||||
"""
|
||||
|
||||
# can this query modulestore for the list of write accessible stores or does that violate command pattern?
|
||||
help = "Create a course in one of {}".format([ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split])
|
||||
help = u"Create a course in one of {}".format([ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split])
|
||||
|
||||
def add_arguments(self, parser):
|
||||
parser.add_argument('modulestore',
|
||||
choices=MODULESTORE_CHOICES,
|
||||
help="Modulestore must be one of {}".format(MODULESTORE_CHOICES))
|
||||
help=u"Modulestore must be one of {}".format(MODULESTORE_CHOICES))
|
||||
parser.add_argument('user',
|
||||
help="The instructor's email address or integer ID.")
|
||||
parser.add_argument('org',
|
||||
@@ -52,7 +52,7 @@ class Command(BaseCommand):
|
||||
try:
|
||||
user_object = user_from_str(user)
|
||||
except User.DoesNotExist:
|
||||
raise CommandError("No user {user} found.".format(user=user))
|
||||
raise CommandError(u"No user {user} found.".format(user=user))
|
||||
return user_object
|
||||
|
||||
def handle(self, *args, **options):
|
||||
|
||||
@@ -64,19 +64,19 @@ class Command(BaseCommand):
|
||||
course_key = text_type(options['course_key'])
|
||||
course_key = CourseKey.from_string(course_key)
|
||||
except InvalidKeyError:
|
||||
raise CommandError('Invalid course_key: {}'.format(options['course_key']))
|
||||
raise CommandError(u'Invalid course_key: {}'.format(options['course_key']))
|
||||
|
||||
if not modulestore().get_course(course_key):
|
||||
raise CommandError('Course not found: {}'.format(options['course_key']))
|
||||
raise CommandError(u'Course not found: {}'.format(options['course_key']))
|
||||
|
||||
print('Preparing to delete course %s from module store....' % options['course_key'])
|
||||
print(u'Preparing to delete course %s from module store....' % options['course_key'])
|
||||
|
||||
if query_yes_no('Are you sure you want to delete course {}?'.format(course_key), default='no'):
|
||||
if query_yes_no('Are you sure? This action cannot be undone!', default='no'):
|
||||
if query_yes_no(u'Are you sure you want to delete course {}?'.format(course_key), default='no'):
|
||||
if query_yes_no(u'Are you sure? This action cannot be undone!', default='no'):
|
||||
delete_course(course_key, ModuleStoreEnum.UserID.mgmt_command, options['keep_instructors'])
|
||||
|
||||
if options['remove_assets']:
|
||||
contentstore().delete_all_course_assets(course_key)
|
||||
print('Deleted assets for course'.format(course_key))
|
||||
print(u'Deleted assets for course'.format(course_key))
|
||||
|
||||
print('Deleted course {}'.format(course_key))
|
||||
print(u'Deleted course {}'.format(course_key))
|
||||
|
||||
@@ -85,7 +85,7 @@ command again, adding --insert or --delete to edit the list.
|
||||
if num < 3:
|
||||
raise CommandError("Tabs 1 and 2 cannot be changed.")
|
||||
|
||||
if query_yes_no('Deleting tab {0} Confirm?'.format(num), default='no'):
|
||||
if query_yes_no(u'Deleting tab {0} Confirm?'.format(num), default='no'):
|
||||
tabs.primitive_delete(course, num - 1) # -1 for 0-based indexing
|
||||
elif options['insert']:
|
||||
num, tab_type, name = options['insert']
|
||||
@@ -93,7 +93,7 @@ command again, adding --insert or --delete to edit the list.
|
||||
if num < 3:
|
||||
raise CommandError("Tabs 1 and 2 cannot be changed.")
|
||||
|
||||
if query_yes_no('Inserting tab {0} "{1}" "{2}" Confirm?'.format(num, tab_type, name), default='no'):
|
||||
if query_yes_no(u'Inserting tab {0} "{1}" "{2}" Confirm?'.format(num, tab_type, name), default='no'):
|
||||
tabs.primitive_insert(course, num - 1, tab_type, name) # -1 as above
|
||||
except ValueError as e:
|
||||
# Cute: translate to CommandError so the CLI error prints nicely.
|
||||
|
||||
@@ -21,5 +21,5 @@ class Command(BaseCommand):
|
||||
else:
|
||||
course_ids = [course.id for course in modulestore().get_courses()]
|
||||
|
||||
if query_yes_no("Emptying {} trashcan(s). Confirm?".format(len(course_ids)), default="no"):
|
||||
if query_yes_no(u"Emptying {} trashcan(s). Confirm?".format(len(course_ids)), default="no"):
|
||||
empty_asset_trashcan(course_ids)
|
||||
|
||||
@@ -31,14 +31,14 @@ class Command(BaseCommand):
|
||||
try:
|
||||
course_key = CourseKey.from_string(options['course_id'])
|
||||
except InvalidKeyError:
|
||||
raise CommandError("Invalid course_key: '%s'." % options['course_id'])
|
||||
raise CommandError(u"Invalid course_key: '%s'." % options['course_id'])
|
||||
|
||||
if not modulestore().get_course(course_key):
|
||||
raise CommandError("Course with %s key not found." % options['course_id'])
|
||||
raise CommandError(u"Course with %s key not found." % options['course_id'])
|
||||
|
||||
output_path = options['output_path']
|
||||
|
||||
print("Exporting course id = {0} to {1}".format(course_key, output_path))
|
||||
print(u"Exporting course id = {0} to {1}".format(course_key, output_path))
|
||||
|
||||
if not output_path.endswith('/'):
|
||||
output_path += '/'
|
||||
|
||||
@@ -28,8 +28,8 @@ class Command(BaseCommand):
|
||||
|
||||
print("=" * 80)
|
||||
print("=" * 30 + "> Export summary")
|
||||
print("Total number of courses to export: {0}".format(len(courses)))
|
||||
print("Total number of courses which failed to export: {0}".format(len(failed_export_courses)))
|
||||
print(u"Total number of courses to export: {0}".format(len(courses)))
|
||||
print(u"Total number of courses which failed to export: {0}".format(len(failed_export_courses)))
|
||||
print("List of export failed courses ids:")
|
||||
print("\n".join(failed_export_courses))
|
||||
print("=" * 80)
|
||||
@@ -49,13 +49,13 @@ def export_courses_to_output_path(output_path):
|
||||
|
||||
for course_id in course_ids:
|
||||
print("-" * 80)
|
||||
print("Exporting course id = {0} to {1}".format(course_id, output_path))
|
||||
print(u"Exporting course id = {0} to {1}".format(course_id, output_path))
|
||||
try:
|
||||
course_dir = text_type(course_id).replace('/', '...')
|
||||
export_course_to_xml(module_store, content_store, course_id, root_dir, course_dir)
|
||||
except Exception as err: # pylint: disable=broad-except
|
||||
failed_export_courses.append(text_type(course_id))
|
||||
print("=" * 30 + "> Oops, failed to export {0}".format(course_id))
|
||||
print(u"=" * 30 + u"> Oops, failed to export {0}".format(course_id))
|
||||
print("Error:")
|
||||
print(err)
|
||||
|
||||
|
||||
@@ -45,10 +45,10 @@ class Command(BaseCommand):
|
||||
owning_store = modulestore()._get_modulestore_for_courselike(course_key) # pylint: disable=protected-access
|
||||
if hasattr(owning_store, 'force_publish_course'):
|
||||
versions = get_course_versions(options['course_key'])
|
||||
print("Course versions : {0}".format(versions))
|
||||
print(u"Course versions : {0}".format(versions))
|
||||
|
||||
if options['commit']:
|
||||
if query_yes_no("Are you sure to publish the {0} course forcefully?".format(course_key), default="no"):
|
||||
if query_yes_no(u"Are you sure to publish the {0} course forcefully?".format(course_key), default="no"):
|
||||
# publish course forcefully
|
||||
updated_versions = owning_store.force_publish_course(
|
||||
course_key, ModuleStoreEnum.UserID.mgmt_command, options['commit']
|
||||
@@ -56,20 +56,20 @@ class Command(BaseCommand):
|
||||
if updated_versions:
|
||||
# if publish and draft were different
|
||||
if versions['published-branch'] != versions['draft-branch']:
|
||||
print("Success! Published the course '{0}' forcefully.".format(course_key))
|
||||
print("Updated course versions : \n{0}".format(updated_versions))
|
||||
print(u"Success! Published the course '{0}' forcefully.".format(course_key))
|
||||
print(u"Updated course versions : \n{0}".format(updated_versions))
|
||||
else:
|
||||
print("Course '{0}' is already in published state.".format(course_key))
|
||||
print(u"Course '{0}' is already in published state.".format(course_key))
|
||||
else:
|
||||
print("Error! Could not publish course {0}.".format(course_key))
|
||||
print(u"Error! Could not publish course {0}.".format(course_key))
|
||||
else:
|
||||
# if publish and draft were different
|
||||
if versions['published-branch'] != versions['draft-branch']:
|
||||
print("Dry run. Following would have been changed : ")
|
||||
print("Published branch version {0} changed to draft branch version {1}".format(
|
||||
print(u"Published branch version {0} changed to draft branch version {1}".format(
|
||||
versions['published-branch'], versions['draft-branch'])
|
||||
)
|
||||
else:
|
||||
print("Dry run. Course '{0}' is already in published state.".format(course_key))
|
||||
print(u"Dry run. Course '{0}' is already in published state.".format(course_key))
|
||||
else:
|
||||
raise CommandError("The owning modulestore does not support this command.")
|
||||
|
||||
@@ -58,9 +58,9 @@ class Command(BaseCommand):
|
||||
# Create the course
|
||||
try:
|
||||
new_course = create_new_course_in_store("split", user, org, num, run, fields)
|
||||
logger.info("Created {}".format(text_type(new_course.id)))
|
||||
logger.info(u"Created {}".format(text_type(new_course.id)))
|
||||
except DuplicateCourseError:
|
||||
logger.warning("Course already exists for %s, %s, %s", org, num, run)
|
||||
logger.warning(u"Course already exists for %s, %s, %s", org, num, run)
|
||||
|
||||
# Configure credit provider
|
||||
if ("enrollment" in course_settings) and ("credit_provider" in course_settings["enrollment"]):
|
||||
|
||||
@@ -47,10 +47,10 @@ class Command(BaseCommand):
|
||||
python_lib_filename = options.get('python_lib_filename')
|
||||
|
||||
output = (
|
||||
"Importing...\n"
|
||||
" data_dir={data}, source_dirs={courses}\n"
|
||||
" Importing static content? {import_static}\n"
|
||||
" Importing python lib? {import_python_lib}"
|
||||
u"Importing...\n"
|
||||
u" data_dir={data}, source_dirs={courses}\n"
|
||||
u" Importing static content? {import_static}\n"
|
||||
u" Importing python lib? {import_python_lib}"
|
||||
).format(
|
||||
data=data_dir,
|
||||
courses=source_dirs,
|
||||
@@ -71,5 +71,5 @@ class Command(BaseCommand):
|
||||
for course in course_items:
|
||||
course_id = course.id
|
||||
if not are_permissions_roles_seeded(course_id):
|
||||
self.stdout.write('Seeding forum roles for course {0}\n'.format(course_id))
|
||||
self.stdout.write(u'Seeding forum roles for course {0}\n'.format(course_id))
|
||||
seed_permissions_roles(course_id)
|
||||
|
||||
@@ -40,7 +40,7 @@ class Command(BaseCommand):
|
||||
try:
|
||||
user = user_from_str(options['email'])
|
||||
except User.DoesNotExist:
|
||||
raise CommandError("No user found identified by {}".format(options['email']))
|
||||
raise CommandError(u"No user found identified by {}".format(options['email']))
|
||||
|
||||
return course_key, user.id, options['org'], options['course'], options['run']
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ class Command(BaseCommand):
|
||||
try:
|
||||
result = CourseKey.from_string(raw_value)
|
||||
except InvalidKeyError:
|
||||
raise CommandError("Invalid course_key: '%s'." % raw_value)
|
||||
raise CommandError(u"Invalid course_key: '%s'." % raw_value)
|
||||
|
||||
if not isinstance(result, CourseLocator):
|
||||
raise CommandError(u"Argument {0} is not a course key".format(raw_value))
|
||||
@@ -110,9 +110,9 @@ class Command(BaseCommand):
|
||||
course_keys = non_migrated_courses[:migration_settings.batch_size]
|
||||
|
||||
log.info(
|
||||
('[Transcript Migration] Courses(total): %s, '
|
||||
'Courses(migrated): %s, Courses(non-migrated): %s, '
|
||||
'Courses(migration-in-process): %s'),
|
||||
(u'[Transcript Migration] Courses(total): %s, '
|
||||
u'Courses(migrated): %s, Courses(non-migrated): %s, '
|
||||
u'Courses(migration-in-process): %s'),
|
||||
len(all_courses),
|
||||
len(migrated_courses),
|
||||
len(non_migrated_courses),
|
||||
|
||||
@@ -25,7 +25,7 @@ def query_yes_no(question, default="yes"):
|
||||
elif default == "no":
|
||||
prompt = " [y/N] "
|
||||
else:
|
||||
raise ValueError("invalid default answer: '%s'" % default)
|
||||
raise ValueError(u"invalid default answer: '%s'" % default)
|
||||
|
||||
while True:
|
||||
sys.stdout.write(question + prompt)
|
||||
|
||||
@@ -44,7 +44,7 @@ class Command(BaseCommand):
|
||||
try:
|
||||
result = CourseKey.from_string(raw_value)
|
||||
except InvalidKeyError:
|
||||
raise CommandError("Invalid course_key: '%s'." % raw_value)
|
||||
raise CommandError(u"Invalid course_key: '%s'." % raw_value)
|
||||
|
||||
if not isinstance(result, CourseLocator):
|
||||
raise CommandError(u"Argument {0} is not a course key".format(raw_value))
|
||||
@@ -75,7 +75,7 @@ class Command(BaseCommand):
|
||||
# try getting the ElasticSearch engine
|
||||
searcher = SearchEngine.get_search_engine(index_name)
|
||||
except exceptions.ElasticsearchException as exc:
|
||||
logging.exception('Search Engine error - %s', exc)
|
||||
logging.exception(u'Search Engine error - %s', exc)
|
||||
return
|
||||
|
||||
index_exists = searcher._es.indices.exists(index=index_name) # pylint: disable=protected-access
|
||||
|
||||
@@ -61,5 +61,5 @@ class Command(BaseCommand):
|
||||
library_keys = map(self._parse_library_key, options['library_ids'])
|
||||
|
||||
for library_key in library_keys:
|
||||
print("Indexing library {}".format(library_key))
|
||||
print(u"Indexing library {}".format(library_key))
|
||||
LibrarySearchIndexer.do_library_reindex(store, library_key)
|
||||
|
||||
@@ -55,7 +55,7 @@ class TestCreateCourse(ModuleStoreTestCase):
|
||||
new_key = modulestore().make_course_key("org", "course", "run")
|
||||
self.assertTrue(
|
||||
modulestore().has_course(new_key),
|
||||
"Could not find course in {}".format(store)
|
||||
u"Could not find course in {}".format(store)
|
||||
)
|
||||
# pylint: disable=protected-access
|
||||
self.assertEqual(store, modulestore()._get_modulestore_for_courselike(new_key).get_modulestore_type())
|
||||
|
||||
@@ -51,7 +51,7 @@ class TestCourseExport(ModuleStoreTestCase):
|
||||
course_id = unicode(course.id)
|
||||
self.assertTrue(
|
||||
modulestore().has_course(course.id),
|
||||
"Could not find course in {}".format(store)
|
||||
u"Could not find course in {}".format(store)
|
||||
)
|
||||
# Test `export` management command with invalid course_id
|
||||
errstring = "Invalid course_key: 'InvalidCourseID'."
|
||||
|
||||
@@ -58,7 +58,7 @@ class TestCourseExportOlx(ModuleStoreTestCase):
|
||||
course = CourseFactory.create(default_store=store_type)
|
||||
self.assertTrue(
|
||||
modulestore().has_course(course.id),
|
||||
"Could not find course in {}".format(store_type)
|
||||
u"Could not find course in {}".format(store_type)
|
||||
)
|
||||
return course.id
|
||||
|
||||
|
||||
@@ -24,8 +24,7 @@ class TestImport(ModuleStoreTestCase):
|
||||
directory = tempfile.mkdtemp(dir=content_dir)
|
||||
os.makedirs(os.path.join(directory, "course"))
|
||||
with open(os.path.join(directory, "course.xml"), "w+") as f:
|
||||
f.write('<course url_name="{0.run}" org="{0.org}" '
|
||||
'course="{0.course}"/>'.format(course_id))
|
||||
f.write(u'<course url_name="{0.run}" org="{0.org}" course="{0.course}"/>'.format(course_id))
|
||||
|
||||
with open(os.path.join(directory, "course", "{0.run}.xml".format(course_id)), "w+") as f:
|
||||
f.write('<course><chapter name="Test Chapter"></chapter></course>')
|
||||
|
||||
@@ -320,8 +320,8 @@ class TestMigrateTranscripts(ModuleStoreTestCase):
|
||||
|
||||
if all_courses:
|
||||
mock_logger.info.assert_called_with(
|
||||
('[Transcript Migration] Courses(total): %s, Courses(migrated): %s, '
|
||||
'Courses(non-migrated): %s, Courses(migration-in-process): %s'),
|
||||
(u'[Transcript Migration] Courses(total): %s, Courses(migrated): %s, '
|
||||
u'Courses(non-migrated): %s, Courses(migration-in-process): %s'),
|
||||
2, 0, 2, batch_size
|
||||
)
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ class TestReindexCourse(ModuleStoreTestCase):
|
||||
@ddt.data('qwerty', 'invalid_key', 'xblockv1:qwerty')
|
||||
def test_given_invalid_course_key_raises_not_found(self, invalid_key):
|
||||
""" Test that raises InvalidKeyError for invalid keys """
|
||||
err_string = "Invalid course_key: '{0}'".format(invalid_key)
|
||||
err_string = u"Invalid course_key: '{0}'".format(invalid_key)
|
||||
with self.assertRaisesRegexp(CommandError, err_string):
|
||||
call_command('reindex_course', invalid_key)
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ class TestVideoThumbnails(ModuleStoreTestCase):
|
||||
),
|
||||
(
|
||||
LOGGER_NAME, 'INFO',
|
||||
'[video thumbnails] selected course videos: {course_videos} '.format(
|
||||
u'[video thumbnails] selected course videos: {course_videos} '.format(
|
||||
course_videos=text_type(course_videos)
|
||||
)
|
||||
)
|
||||
@@ -122,12 +122,12 @@ class TestVideoThumbnails(ModuleStoreTestCase):
|
||||
logger.check(
|
||||
(
|
||||
tasks_logger, 'ERROR',
|
||||
("[video thumbnails] [run=1] [video-thumbnails-scraping-failed-with-unknown-exc] "
|
||||
"[edx_video_id=super-soaker] [youtube_id=OscRe3pSP80] [course={}]".format(self.course.id))
|
||||
(u"[video thumbnails] [run=1] [video-thumbnails-scraping-failed-with-unknown-exc] "
|
||||
u"[edx_video_id=super-soaker] [youtube_id=OscRe3pSP80] [course={}]".format(self.course.id))
|
||||
),
|
||||
(
|
||||
tasks_logger, 'ERROR',
|
||||
("[video thumbnails] [run=1] [video-thumbnails-scraping-failed-with-unknown-exc] "
|
||||
"[edx_video_id=medium-soaker] [youtube_id=OscRe3pSP81] [course={}]".format(self.course_2.id))
|
||||
(u"[video thumbnails] [run=1] [video-thumbnails-scraping-failed-with-unknown-exc] "
|
||||
u"[edx_video_id=medium-soaker] [youtube_id=OscRe3pSP81] [course={}]".format(self.course_2.id))
|
||||
)
|
||||
)
|
||||
|
||||
@@ -34,7 +34,7 @@ class Command(BaseCommand):
|
||||
offset=command_settings.offset, limit=command_settings.batch_size
|
||||
)
|
||||
log.info(
|
||||
'[Video Thumbnails] Videos(updated): %s, Videos(update-in-process): %s',
|
||||
u'[Video Thumbnails] Videos(updated): %s, Videos(update-in-process): %s',
|
||||
command_settings.offset, len(course_videos),
|
||||
)
|
||||
else:
|
||||
@@ -52,7 +52,7 @@ class Command(BaseCommand):
|
||||
CourseKey.from_string(course_id)
|
||||
return course_ids
|
||||
except InvalidKeyError as error:
|
||||
raise CommandError('Invalid key specified: {}'.format(text_type(error)))
|
||||
raise CommandError(u'Invalid key specified: {}'.format(text_type(error)))
|
||||
|
||||
def _latest_settings(self):
|
||||
"""
|
||||
@@ -79,6 +79,6 @@ class Command(BaseCommand):
|
||||
if video_thumbnail_settings.all_course_videos:
|
||||
video_thumbnail_settings.update_offset()
|
||||
else:
|
||||
log.info('[video thumbnails] selected course videos: {course_videos} '.format(
|
||||
log.info(u'[video thumbnails] selected course videos: {course_videos} '.format(
|
||||
course_videos=text_type(course_videos)
|
||||
))
|
||||
|
||||
@@ -26,7 +26,7 @@ class Command(BaseCommand):
|
||||
data_dir = options['data_dir']
|
||||
source_dirs = options['source_dirs']
|
||||
|
||||
print("Importing. Data_dir={data}, source_dirs={courses}".format(
|
||||
print(u"Importing. Data_dir={data}, source_dirs={courses}".format(
|
||||
data=data_dir,
|
||||
courses=source_dirs))
|
||||
|
||||
|
||||
@@ -36,7 +36,7 @@ def register_special_exams(course_key):
|
||||
|
||||
course = modulestore().get_course(course_key)
|
||||
if course is None:
|
||||
raise ItemNotFoundError("Course {} does not exist", unicode(course_key))
|
||||
raise ItemNotFoundError(u"Course {} does not exist", unicode(course_key))
|
||||
|
||||
if not course.enable_proctored_exams and not course.enable_timed_exams:
|
||||
# likewise if course does not have these features turned on
|
||||
@@ -65,7 +65,7 @@ def register_special_exams(course_key):
|
||||
# add/update any exam entries in edx-proctoring
|
||||
for timed_exam in timed_exams:
|
||||
msg = (
|
||||
'Found {location} as a timed-exam in course structure. Inspecting...'.format(
|
||||
u'Found {location} as a timed-exam in course structure. Inspecting...'.format(
|
||||
location=unicode(timed_exam.location)
|
||||
)
|
||||
)
|
||||
@@ -88,7 +88,7 @@ def register_special_exams(course_key):
|
||||
exam_metadata['exam_id'] = exam['id']
|
||||
|
||||
exam_id = update_exam(**exam_metadata)
|
||||
msg = 'Updated timed exam {exam_id}'.format(exam_id=exam['id'])
|
||||
msg = u'Updated timed exam {exam_id}'.format(exam_id=exam['id'])
|
||||
log.info(msg)
|
||||
|
||||
except ProctoredExamNotFoundException:
|
||||
@@ -96,7 +96,7 @@ def register_special_exams(course_key):
|
||||
exam_metadata['content_id'] = unicode(timed_exam.location)
|
||||
|
||||
exam_id = create_exam(**exam_metadata)
|
||||
msg = 'Created new timed exam {exam_id}'.format(exam_id=exam_id)
|
||||
msg = u'Created new timed exam {exam_id}'.format(exam_id=exam_id)
|
||||
log.info(msg)
|
||||
|
||||
exam_review_policy_metadata = {
|
||||
@@ -112,7 +112,7 @@ def register_special_exams(course_key):
|
||||
except ProctoredExamReviewPolicyNotFoundException:
|
||||
if timed_exam.exam_review_rules: # won't save an empty rule.
|
||||
create_exam_review_policy(**exam_review_policy_metadata)
|
||||
msg = 'Created new exam review policy with exam_id {exam_id}'.format(exam_id=exam_id)
|
||||
msg = u'Created new exam review policy with exam_id {exam_id}'.format(exam_id=exam_id)
|
||||
log.info(msg)
|
||||
else:
|
||||
try:
|
||||
@@ -136,7 +136,7 @@ def register_special_exams(course_key):
|
||||
if not search:
|
||||
# This means it was turned off in Studio, we need to mark
|
||||
# the exam as inactive (we don't delete!)
|
||||
msg = 'Disabling timed exam {exam_id}'.format(exam_id=exam['id'])
|
||||
msg = u'Disabling timed exam {exam_id}'.format(exam_id=exam['id'])
|
||||
log.info(msg)
|
||||
update_exam(
|
||||
exam_id=exam['id'],
|
||||
|
||||
@@ -30,7 +30,7 @@ def locked(expiry_seconds, key):
|
||||
def wrapper(*args, **kwargs):
|
||||
cache_key = '{}-{}'.format(func.__name__, kwargs[key])
|
||||
if cache.add(cache_key, "true", expiry_seconds):
|
||||
log.info('Locking task in cache with key: %s for %s seconds', cache_key, expiry_seconds)
|
||||
log.info(u'Locking task in cache with key: %s for %s seconds', cache_key, expiry_seconds)
|
||||
return func(*args, **kwargs)
|
||||
return wrapper
|
||||
return task_decorator
|
||||
@@ -119,7 +119,7 @@ def handle_grading_policy_changed(sender, **kwargs):
|
||||
'event_transaction_type': unicode(get_event_transaction_type()),
|
||||
}
|
||||
result = compute_all_grades_for_course.apply_async(kwargs=kwargs, countdown=GRADING_POLICY_COUNTDOWN_SECONDS)
|
||||
log.info("Grades: Created {task_name}[{task_id}] with arguments {kwargs}".format(
|
||||
log.info(u"Grades: Created {task_name}[{task_id}] with arguments {kwargs}".format(
|
||||
task_name=compute_all_grades_for_course.name,
|
||||
task_id=result.task_id,
|
||||
kwargs=kwargs,
|
||||
|
||||
@@ -126,8 +126,8 @@ def task_scrape_youtube_thumbnail_callback(self, results, run, # pylint: disabl
|
||||
"""
|
||||
yt_thumbnails_scraping_tasks_count = len(list(results()))
|
||||
LOGGER.info(
|
||||
("[video thumbnails] [run=%s] [video-thumbnails-scraping-complete-for-a-batch] [tasks_count=%s] "
|
||||
"[batch_size=%s] [videos_per_task=%s]"),
|
||||
(u"[video thumbnails] [run=%s] [video-thumbnails-scraping-complete-for-a-batch] [tasks_count=%s] "
|
||||
u"[batch_size=%s] [videos_per_task=%s]"),
|
||||
run, yt_thumbnails_scraping_tasks_count, batch_size, videos_per_task
|
||||
)
|
||||
|
||||
@@ -153,8 +153,8 @@ def task_scrape_youtube_thumbnail(self, course_videos, run): # pylint: disable
|
||||
scrape_youtube_thumbnail(course_id, edx_video_id, youtube_id)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
LOGGER.exception(
|
||||
("[video thumbnails] [run=%s] [video-thumbnails-scraping-failed-with-unknown-exc] "
|
||||
"[edx_video_id=%s] [youtube_id=%s] [course=%s]"),
|
||||
(u"[video thumbnails] [run=%s] [video-thumbnails-scraping-failed-with-unknown-exc] "
|
||||
u"[edx_video_id=%s] [youtube_id=%s] [course=%s]"),
|
||||
run,
|
||||
edx_video_id,
|
||||
youtube_id,
|
||||
@@ -172,8 +172,8 @@ def task_status_callback(self, results, revision, # pylint: disable=unused-argu
|
||||
transcript_tasks_count = len(list(results()))
|
||||
|
||||
LOGGER.info(
|
||||
("[%s] [run=%s] [video-transcripts-migration-complete-for-a-video] [tasks_count=%s] [course_id=%s] "
|
||||
"[revision=%s] [video=%s]"),
|
||||
(u"[%s] [run=%s] [video-transcripts-migration-complete-for-a-video] [tasks_count=%s] [course_id=%s] "
|
||||
u"[revision=%s] [video=%s]"),
|
||||
MIGRATION_LOGS_PREFIX, command_run, transcript_tasks_count, course_id, revision, video_location
|
||||
)
|
||||
|
||||
@@ -248,7 +248,7 @@ def async_migrate_transcript(self, course_key, **kwargs): # pylint: disable=un
|
||||
course_videos = get_course_videos(CourseKey.from_string(course_key))
|
||||
|
||||
LOGGER.info(
|
||||
"[%s] [run=%s] [video-transcripts-migration-process-started-for-course] [course=%s]",
|
||||
u"[%s] [run=%s] [video-transcripts-migration-process-started-for-course] [course=%s]",
|
||||
MIGRATION_LOGS_PREFIX, command_run, course_key
|
||||
)
|
||||
|
||||
@@ -280,13 +280,13 @@ def async_migrate_transcript(self, course_key, **kwargs): # pylint: disable=un
|
||||
chord(sub_tasks)(callback)
|
||||
|
||||
LOGGER.info(
|
||||
("[%s] [run=%s] [transcripts-migration-tasks-submitted] "
|
||||
"[transcripts_count=%s] [course=%s] [revision=%s] [video=%s]"),
|
||||
(u"[%s] [run=%s] [transcripts-migration-tasks-submitted] "
|
||||
u"[transcripts_count=%s] [course=%s] [revision=%s] [video=%s]"),
|
||||
MIGRATION_LOGS_PREFIX, command_run, len(sub_tasks), course_key, revision, video_location
|
||||
)
|
||||
else:
|
||||
LOGGER.info(
|
||||
"[%s] [run=%s] [no-video-transcripts] [course=%s] [revision=%s] [video=%s]",
|
||||
u"[%s] [run=%s] [no-video-transcripts] [course=%s] [revision=%s] [video=%s]",
|
||||
MIGRATION_LOGS_PREFIX, command_run, course_key, revision, video_location
|
||||
)
|
||||
|
||||
@@ -321,7 +321,7 @@ def save_transcript_to_storage(command_run, edx_video_id, language_code, transcr
|
||||
)
|
||||
else:
|
||||
LOGGER.info(
|
||||
"[%s] [run=%s] [do-not-override-existing-transcript] [edx_video_id=%s] [language_code=%s]",
|
||||
u"[%s] [run=%s] [do-not-override-existing-transcript] [edx_video_id=%s] [language_code=%s]",
|
||||
MIGRATION_LOGS_PREFIX, command_run, edx_video_id, language_code
|
||||
)
|
||||
|
||||
@@ -347,15 +347,15 @@ def async_migrate_transcript_subtask(self, *args, **kwargs): # pylint: disable=
|
||||
|
||||
if not kwargs['commit']:
|
||||
LOGGER.info(
|
||||
('[%s] [run=%s] [video-transcript-will-be-migrated] '
|
||||
'[revision=%s] [video=%s] [edx_video_id=%s] [language_code=%s]'),
|
||||
(u'[%s] [run=%s] [video-transcript-will-be-migrated] '
|
||||
u'[revision=%s] [video=%s] [edx_video_id=%s] [language_code=%s]'),
|
||||
MIGRATION_LOGS_PREFIX, command_run, revision, video_location, edx_video_id, language_code
|
||||
)
|
||||
return success
|
||||
|
||||
LOGGER.info(
|
||||
('[%s] [run=%s] [transcripts-migration-process-started-for-video-transcript] [revision=%s] '
|
||||
'[video=%s] [edx_video_id=%s] [language_code=%s]'),
|
||||
(u'[%s] [run=%s] [transcripts-migration-process-started-for-video-transcript] [revision=%s] '
|
||||
u'[video=%s] [edx_video_id=%s] [language_code=%s]'),
|
||||
MIGRATION_LOGS_PREFIX, command_run, revision, video_location, edx_video_id, language_code
|
||||
)
|
||||
|
||||
@@ -383,7 +383,7 @@ def async_migrate_transcript_subtask(self, *args, **kwargs): # pylint: disable=
|
||||
store.update_item(video, ModuleStoreEnum.UserID.mgmt_command)
|
||||
|
||||
LOGGER.info(
|
||||
'[%s] [run=%s] [generated-edx-video-id] [revision=%s] [video=%s] [edx_video_id=%s] [language_code=%s]',
|
||||
u'[%s] [run=%s] [generated-edx-video-id] [revision=%s] [video=%s] [edx_video_id=%s] [language_code=%s]',
|
||||
MIGRATION_LOGS_PREFIX, command_run, revision, video_location, edx_video_id, language_code
|
||||
)
|
||||
|
||||
@@ -397,22 +397,22 @@ def async_migrate_transcript_subtask(self, *args, **kwargs): # pylint: disable=
|
||||
)
|
||||
except (NotFoundError, TranscriptsGenerationException, ValCannotCreateError):
|
||||
LOGGER.exception(
|
||||
('[%s] [run=%s] [video-transcript-migration-failed-with-known-exc] [revision=%s] [video=%s] '
|
||||
'[edx_video_id=%s] [language_code=%s]'),
|
||||
(u'[%s] [run=%s] [video-transcript-migration-failed-with-known-exc] [revision=%s] [video=%s] '
|
||||
u'[edx_video_id=%s] [language_code=%s]'),
|
||||
MIGRATION_LOGS_PREFIX, command_run, revision, video_location, edx_video_id, language_code
|
||||
)
|
||||
return failure
|
||||
except Exception:
|
||||
LOGGER.exception(
|
||||
('[%s] [run=%s] [video-transcript-migration-failed-with-unknown-exc] [revision=%s] '
|
||||
'[video=%s] [edx_video_id=%s] [language_code=%s]'),
|
||||
(u'[%s] [run=%s] [video-transcript-migration-failed-with-unknown-exc] [revision=%s] '
|
||||
u'[video=%s] [edx_video_id=%s] [language_code=%s]'),
|
||||
MIGRATION_LOGS_PREFIX, command_run, revision, video_location, edx_video_id, language_code
|
||||
)
|
||||
raise
|
||||
|
||||
LOGGER.info(
|
||||
('[%s] [run=%s] [video-transcript-migration-succeeded-for-a-video] [revision=%s] '
|
||||
'[video=%s] [edx_video_id=%s] [language_code=%s]'),
|
||||
(u'[%s] [run=%s] [video-transcript-migration-succeeded-for-a-video] [revision=%s] '
|
||||
u'[video=%s] [edx_video_id=%s] [language_code=%s]'),
|
||||
MIGRATION_LOGS_PREFIX, command_run, revision, video_location, edx_video_id, language_code
|
||||
)
|
||||
return success
|
||||
@@ -675,7 +675,7 @@ def create_export_tarball(course_module, course_key, context, status=None):
|
||||
'edit_unit_url': context['edit_unit_url']}))
|
||||
raise
|
||||
except Exception as exc:
|
||||
LOGGER.exception('There was an error exporting %s', course_key, exc_info=True)
|
||||
LOGGER.exception(u'There was an error exporting %s', course_key, exc_info=True)
|
||||
context.update({
|
||||
'in_err': True,
|
||||
'edit_unit_url': None,
|
||||
|
||||
@@ -161,7 +161,7 @@ class ImportRequiredTestCases(ContentStoreTestCase):
|
||||
|
||||
# Test course export does not fail
|
||||
root_dir = path(mkdtemp_clean())
|
||||
print('Exporting to tempdir = {0}'.format(root_dir))
|
||||
print(u'Exporting to tempdir = {0}'.format(root_dir))
|
||||
export_course_to_xml(self.store, content_store, course.id, root_dir, u'test_export')
|
||||
|
||||
filesystem = OSFS(text_type(root_dir / 'test_export/static'))
|
||||
@@ -260,7 +260,7 @@ class ImportRequiredTestCases(ContentStoreTestCase):
|
||||
# now export the course to a tempdir and test that it contains files 'updates.html' and 'updates.items.json'
|
||||
# with same content as in course 'info' directory
|
||||
root_dir = path(mkdtemp_clean())
|
||||
print('Exporting to tempdir = {0}'.format(root_dir))
|
||||
print(u'Exporting to tempdir = {0}'.format(root_dir))
|
||||
export_course_to_xml(self.store, content_store, course.id, root_dir, u'test_export')
|
||||
|
||||
# check that exported course has files 'updates.html' and 'updates.items.json'
|
||||
@@ -318,7 +318,7 @@ class ImportRequiredTestCases(ContentStoreTestCase):
|
||||
course_id = self.import_and_populate_course()
|
||||
|
||||
root_dir = path(mkdtemp_clean())
|
||||
print('Exporting to tempdir = {0}'.format(root_dir))
|
||||
print(u'Exporting to tempdir = {0}'.format(root_dir))
|
||||
|
||||
# export out to a tempdir
|
||||
export_course_to_xml(self.store, content_store, course_id, root_dir, u'test_export')
|
||||
@@ -420,7 +420,7 @@ class ImportRequiredTestCases(ContentStoreTestCase):
|
||||
|
||||
root_dir = path(mkdtemp_clean())
|
||||
|
||||
print('Exporting to tempdir = {0}'.format(root_dir))
|
||||
print(u'Exporting to tempdir = {0}'.format(root_dir))
|
||||
|
||||
# export out to a tempdir
|
||||
export_course_to_xml(self.store, content_store, course_id, root_dir, u'test_export')
|
||||
@@ -446,7 +446,7 @@ class ImportRequiredTestCases(ContentStoreTestCase):
|
||||
|
||||
root_dir = path(mkdtemp_clean())
|
||||
|
||||
print('Exporting to tempdir = {0}'.format(root_dir))
|
||||
print(u'Exporting to tempdir = {0}'.format(root_dir))
|
||||
|
||||
# export out to a tempdir
|
||||
export_course_to_xml(self.store, content_store, course_id, root_dir, u'test_export')
|
||||
@@ -546,7 +546,7 @@ class ImportRequiredTestCases(ContentStoreTestCase):
|
||||
|
||||
root_dir = path(mkdtemp_clean())
|
||||
|
||||
print('Exporting to tempdir = {0}'.format(root_dir))
|
||||
print(u'Exporting to tempdir = {0}'.format(root_dir))
|
||||
export_course_to_xml(self.store, None, course_id, root_dir, u'test_export_no_content_store')
|
||||
|
||||
# Delete the course from module store and reimport it
|
||||
@@ -719,7 +719,7 @@ class MiscCourseTests(ContentStoreTestCase):
|
||||
|
||||
# Now export the course to a tempdir and test that it contains assets. The export should pass
|
||||
root_dir = path(mkdtemp_clean())
|
||||
print('Exporting to tempdir = {0}'.format(root_dir))
|
||||
print(u'Exporting to tempdir = {0}'.format(root_dir))
|
||||
export_course_to_xml(self.store, content_store, self.course.id, root_dir, u'test_export')
|
||||
|
||||
filesystem = OSFS(root_dir / 'test_export/static')
|
||||
@@ -779,7 +779,7 @@ class MiscCourseTests(ContentStoreTestCase):
|
||||
|
||||
# Now export the course to a tempdir and test that it contains assets.
|
||||
root_dir = path(mkdtemp_clean())
|
||||
print('Exporting to tempdir = {0}'.format(root_dir))
|
||||
print(u'Exporting to tempdir = {0}'.format(root_dir))
|
||||
export_course_to_xml(self.store, content_store, self.course.id, root_dir, u'test_export')
|
||||
|
||||
# Verify that asset have been overwritten during export.
|
||||
@@ -1908,7 +1908,7 @@ class RerunCourseTest(ContentStoreTestCase):
|
||||
|
||||
def get_unsucceeded_course_action_elements(self, html, course_key):
|
||||
"""Returns the elements in the unsucceeded course action section that have the given course_key"""
|
||||
return html.cssselect('.courses-processing li[data-course-key="{}"]'.format(text_type(course_key)))
|
||||
return html.cssselect(u'.courses-processing li[data-course-key="{}"]'.format(text_type(course_key)))
|
||||
|
||||
def assertInCourseListing(self, course_key):
|
||||
"""
|
||||
|
||||
@@ -88,10 +88,10 @@ class TestCourseListing(ModuleStoreTestCase):
|
||||
"""
|
||||
Test on empty course listing, studio name is properly displayed
|
||||
"""
|
||||
message = "Are you staff on an existing {studio_name} course?".format(studio_name=settings.STUDIO_SHORT_NAME)
|
||||
message = u"Are you staff on an existing {studio_name} course?".format(studio_name=settings.STUDIO_SHORT_NAME)
|
||||
response = self.client.get('/home')
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertIn(message, response.content)
|
||||
self.assertIn(message, response.content.decode(response.charset))
|
||||
|
||||
def test_get_course_list(self):
|
||||
"""
|
||||
|
||||
@@ -173,7 +173,7 @@ class CourseDetailsViewTest(CourseTestCase, MilestonesTestCaseMixin):
|
||||
dt1 = date.from_json(encoded[field])
|
||||
dt2 = details[field]
|
||||
|
||||
self.assertEqual(dt1, dt2, msg="{} != {} at {}".format(dt1, dt2, context))
|
||||
self.assertEqual(dt1, dt2, msg=u"{} != {} at {}".format(dt1, dt2, context))
|
||||
else:
|
||||
self.fail(field + " missing from encoded but in details at " + context)
|
||||
elif field in encoded and encoded[field] is not None:
|
||||
|
||||
@@ -675,7 +675,7 @@ class TestLargeCourseDeletions(MixedWithOptionsTestCase):
|
||||
self._do_test_large_course_deletion(store, load_factor)
|
||||
except: # pylint: disable=bare-except
|
||||
# Catch any exception here to see when we fail
|
||||
print("Failed with load_factor of {}".format(load_factor))
|
||||
print(u"Failed with load_factor of {}".format(load_factor))
|
||||
|
||||
@skip(("This test is to see how we handle very large courses, to ensure that the delete"
|
||||
"procedure works smoothly - too long to run during the normal course of things"))
|
||||
|
||||
@@ -134,7 +134,7 @@ class ContentStoreImportTest(ModuleStoreTestCase):
|
||||
self.assertIsNotNone(content)
|
||||
|
||||
# make sure course.static_asset_path is correct
|
||||
print("static_asset_path = {0}".format(course.static_asset_path))
|
||||
print(u"static_asset_path = {0}".format(course.static_asset_path))
|
||||
self.assertEqual(course.static_asset_path, 'test_import_course')
|
||||
|
||||
def test_asset_import_nostatic(self):
|
||||
@@ -173,7 +173,7 @@ class ContentStoreImportTest(ModuleStoreTestCase):
|
||||
|
||||
def test_tab_name_imports_correctly(self):
|
||||
_module_store, _content_store, course = self.load_test_import_course()
|
||||
print("course tabs = {0}".format(course.tabs))
|
||||
print(u"course tabs = {0}".format(course.tabs))
|
||||
self.assertEqual(course.tabs[2]['name'], 'Syllabus')
|
||||
|
||||
def test_import_performance_mongo(self):
|
||||
|
||||
@@ -187,7 +187,7 @@ class TestLibraries(LibraryTestCase):
|
||||
# Create many blocks in the library and add them to a course:
|
||||
for num in range(8):
|
||||
ItemFactory.create(
|
||||
data="This is #{}".format(num + 1),
|
||||
data=u"This is #{}".format(num + 1),
|
||||
category="html", parent_location=self.library.location, user_id=self.user.id, publish_item=False
|
||||
)
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ class TestOrphan(TestOrphanBase):
|
||||
HTTP_ACCEPT='application/json'
|
||||
).content
|
||||
)
|
||||
self.assertEqual(len(orphans), 3, "Wrong # {}".format(orphans))
|
||||
self.assertEqual(len(orphans), 3, u"Wrong # {}".format(orphans))
|
||||
location = course.location.replace(category='chapter', name='OrphanChapter')
|
||||
self.assertIn(unicode(location), orphans)
|
||||
location = course.location.replace(category='vertical', name='OrphanVert')
|
||||
@@ -118,7 +118,7 @@ class TestOrphan(TestOrphanBase):
|
||||
orphans = json.loads(
|
||||
self.client.get(orphan_url, HTTP_ACCEPT='application/json').content
|
||||
)
|
||||
self.assertEqual(len(orphans), 0, "Orphans not deleted {}".format(orphans))
|
||||
self.assertEqual(len(orphans), 0, u"Orphans not deleted {}".format(orphans))
|
||||
|
||||
# make sure that any children with one orphan parent and one non-orphan
|
||||
# parent are not deleted
|
||||
|
||||
@@ -124,9 +124,9 @@ class TestCourseAccess(ModuleStoreTestCase):
|
||||
if hasattr(user, '_roles'):
|
||||
del user._roles
|
||||
|
||||
self.assertTrue(auth.has_course_author_access(user, copy_course_key), "{} no copy access".format(user))
|
||||
self.assertTrue(auth.has_course_author_access(user, copy_course_key), u"{} no copy access".format(user))
|
||||
if (role is OrgStaffRole) or (role is OrgInstructorRole):
|
||||
auth.remove_users(self.user, role(self.course_key.org), user)
|
||||
else:
|
||||
auth.remove_users(self.user, role(self.course_key), user)
|
||||
self.assertFalse(auth.has_course_author_access(user, self.course_key), "{} remove didn't work".format(user))
|
||||
self.assertFalse(auth.has_course_author_access(user, self.course_key), u"{} remove didn't work".format(user))
|
||||
|
||||
@@ -18,7 +18,7 @@ class CMSLogTest(TestCase):
|
||||
"""
|
||||
requests = [
|
||||
{"event": "my_event", "event_type": "my_event_type", "page": "my_page"},
|
||||
{"event": "{'json': 'object'}", "event_type": unichr(512), "page": "my_page"}
|
||||
{"event": "{'json': 'object'}", "event_type": unichr(512), "page": "my_page"} # pylint: disable=unicode-format-string
|
||||
]
|
||||
with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_SQL_TRACKING_LOGS': True}):
|
||||
for request_params in requests:
|
||||
@@ -32,7 +32,7 @@ class CMSLogTest(TestCase):
|
||||
"""
|
||||
requests = [
|
||||
{"event": "my_event", "event_type": "my_event_type", "page": "my_page"},
|
||||
{"event": "{'json': 'object'}", "event_type": unichr(512), "page": "my_page"}
|
||||
{"event": "{'json': 'object'}", "event_type": unichr(512), "page": "my_page"} # pylint: disable=unicode-format-string
|
||||
]
|
||||
with mock.patch.dict('django.conf.settings.FEATURES', {'ENABLE_SQL_TRACKING_LOGS': True}):
|
||||
for request_params in requests:
|
||||
|
||||
@@ -300,13 +300,13 @@ class ScrapeVideoThumbnailsTestCase(CourseTestCase):
|
||||
scrape_youtube_thumbnail(course_id, video1_edx_video_id, 'test-yt-id')
|
||||
if is_success:
|
||||
mock_logger.info.assert_called_with(
|
||||
'VIDEOS: Scraping youtube video thumbnail for edx_video_id [%s] in course [%s]',
|
||||
u'VIDEOS: Scraping youtube video thumbnail for edx_video_id [%s] in course [%s]',
|
||||
video1_edx_video_id,
|
||||
course_id
|
||||
)
|
||||
else:
|
||||
mock_logger.info.assert_called_with(
|
||||
'VIDEOS: Scraping youtube video thumbnail failed for edx_video_id [%s] in course [%s] with error: %s',
|
||||
u'VIDEOS: Scraping youtube video thumbnail failed for edx_video_id [%s] in course [%s] with error: %s',
|
||||
video1_edx_video_id,
|
||||
course_id,
|
||||
'This image file must be larger than 2 KB.'
|
||||
@@ -316,21 +316,21 @@ class ScrapeVideoThumbnailsTestCase(CourseTestCase):
|
||||
(
|
||||
None,
|
||||
'image/jpeg',
|
||||
'This image file must be larger than {image_min_size}.'.format(
|
||||
u'This image file must be larger than {image_min_size}.'.format(
|
||||
image_min_size=settings.VIDEO_IMAGE_MIN_FILE_SIZE_KB
|
||||
)
|
||||
),
|
||||
(
|
||||
'dummy-content',
|
||||
None,
|
||||
'This image file type is not supported. Supported file types are {supported_file_formats}.'.format(
|
||||
u'This image file type is not supported. Supported file types are {supported_file_formats}.'.format(
|
||||
supported_file_formats=settings.VIDEO_IMAGE_SUPPORTED_FILE_FORMATS.keys()
|
||||
)
|
||||
),
|
||||
(
|
||||
None,
|
||||
None,
|
||||
'This image file type is not supported. Supported file types are {supported_file_formats}.'.format(
|
||||
u'This image file type is not supported. Supported file types are {supported_file_formats}.'.format(
|
||||
supported_file_formats=settings.VIDEO_IMAGE_SUPPORTED_FILE_FORMATS.keys()
|
||||
)
|
||||
),
|
||||
@@ -361,7 +361,7 @@ class ScrapeVideoThumbnailsTestCase(CourseTestCase):
|
||||
scrape_youtube_thumbnail(course_id, video1_edx_video_id, 'test-yt-id')
|
||||
|
||||
mock_logger.info.assert_called_with(
|
||||
'VIDEOS: Scraping youtube video thumbnail failed for edx_video_id [%s] in course [%s] with error: %s',
|
||||
u'VIDEOS: Scraping youtube video thumbnail failed for edx_video_id [%s] in course [%s] with error: %s',
|
||||
video1_edx_video_id,
|
||||
course_id,
|
||||
error_message
|
||||
|
||||
@@ -144,7 +144,7 @@ class AuthTestCase(ContentStoreTestCase):
|
||||
reverse('signup'),
|
||||
)
|
||||
for page in pages:
|
||||
print("Checking '{0}'".format(page))
|
||||
print(u"Checking '{0}'".format(page))
|
||||
self.check_page_get(page, 200)
|
||||
|
||||
def test_create_account_errors(self):
|
||||
@@ -268,7 +268,7 @@ class AuthTestCase(ContentStoreTestCase):
|
||||
# Not logged in. Should redirect to login.
|
||||
print('Not logged in')
|
||||
for page in auth_pages:
|
||||
print("Checking '{0}'".format(page))
|
||||
print(u"Checking '{0}'".format(page))
|
||||
self.check_page_get(page, expected=302)
|
||||
|
||||
# Logged in should work.
|
||||
@@ -276,7 +276,7 @@ class AuthTestCase(ContentStoreTestCase):
|
||||
|
||||
print('Logged in')
|
||||
for page in simple_auth_pages:
|
||||
print("Checking '{0}'".format(page))
|
||||
print(u"Checking '{0}'".format(page))
|
||||
self.check_page_get(page, expected=200)
|
||||
|
||||
def test_index_auth(self):
|
||||
|
||||
@@ -100,7 +100,7 @@ def _remove_instructors(course_key):
|
||||
try:
|
||||
remove_all_instructors(course_key)
|
||||
except Exception as err:
|
||||
log.error("Error in deleting course groups for {0}: {1}".format(course_key, err))
|
||||
log.error(u"Error in deleting course groups for {0}: {1}".format(course_key, err))
|
||||
|
||||
|
||||
def get_lms_link_for_item(location, preview=False):
|
||||
@@ -318,7 +318,7 @@ def get_split_group_display_name(xblock, course):
|
||||
"""
|
||||
for user_partition in get_user_partition_info(xblock, schemes=['random'], course=course):
|
||||
for group in user_partition['groups']:
|
||||
if 'Group ID {group_id}'.format(group_id=group['id']) == xblock.display_name_with_default:
|
||||
if u'Group ID {group_id}'.format(group_id=group['id']) == xblock.display_name_with_default:
|
||||
return group['name']
|
||||
|
||||
|
||||
@@ -386,7 +386,7 @@ def get_user_partition_info(xblock, schemes=None, course=None):
|
||||
|
||||
if course is None:
|
||||
log.warning(
|
||||
"Could not find course %s to retrieve user partition information",
|
||||
u"Could not find course %s to retrieve user partition information",
|
||||
xblock.location.course_key
|
||||
)
|
||||
return []
|
||||
@@ -491,7 +491,7 @@ def get_visibility_partition_info(xblock, course=None):
|
||||
else:
|
||||
# Translators: This is building up a list of groups. It is marked for translation because of the
|
||||
# comma, which is used as a separator between each group.
|
||||
selected_groups_label = _('{previous_groups}, {current_group}').format(
|
||||
selected_groups_label = _(u'{previous_groups}, {current_group}').format(
|
||||
previous_groups=selected_groups_label,
|
||||
current_group=group['name']
|
||||
)
|
||||
|
||||
@@ -41,15 +41,15 @@ def validate_video_image(image_file, skip_aspect_ratio=False):
|
||||
if not all(hasattr(image_file, attr) for attr in ['name', 'content_type', 'size']):
|
||||
error = _('The image must have name, content type, and size information.')
|
||||
elif image_file.content_type not in settings.VIDEO_IMAGE_SUPPORTED_FILE_FORMATS.values():
|
||||
error = _('This image file type is not supported. Supported file types are {supported_file_formats}.').format(
|
||||
error = _(u'This image file type is not supported. Supported file types are {supported_file_formats}.').format(
|
||||
supported_file_formats=settings.VIDEO_IMAGE_SUPPORTED_FILE_FORMATS.keys()
|
||||
)
|
||||
elif image_file.size > settings.VIDEO_IMAGE_SETTINGS['VIDEO_IMAGE_MAX_BYTES']:
|
||||
error = _('This image file must be smaller than {image_max_size}.').format(
|
||||
error = _(u'This image file must be smaller than {image_max_size}.').format(
|
||||
image_max_size=settings.VIDEO_IMAGE_MAX_FILE_SIZE_MB
|
||||
)
|
||||
elif image_file.size < settings.VIDEO_IMAGE_SETTINGS['VIDEO_IMAGE_MIN_BYTES']:
|
||||
error = _('This image file must be larger than {image_min_size}.').format(
|
||||
error = _(u'This image file must be larger than {image_min_size}.').format(
|
||||
image_min_size=settings.VIDEO_IMAGE_MIN_FILE_SIZE_KB
|
||||
)
|
||||
else:
|
||||
@@ -61,15 +61,15 @@ def validate_video_image(image_file, skip_aspect_ratio=False):
|
||||
return _('There is a problem with this image file. Try to upload a different file.')
|
||||
image_file_aspect_ratio = abs(image_file_width / float(image_file_height) - settings.VIDEO_IMAGE_ASPECT_RATIO)
|
||||
if image_file_width < settings.VIDEO_IMAGE_MIN_WIDTH or image_file_height < settings.VIDEO_IMAGE_MIN_HEIGHT:
|
||||
error = _('Recommended image resolution is {image_file_max_width}x{image_file_max_height}. '
|
||||
'The minimum resolution is {image_file_min_width}x{image_file_min_height}.').format(
|
||||
error = _(u'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. '
|
||||
u'The minimum resolution is {image_file_min_width}x{image_file_min_height}.').format(
|
||||
image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
|
||||
image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
|
||||
image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
|
||||
image_file_min_height=settings.VIDEO_IMAGE_MIN_HEIGHT
|
||||
)
|
||||
elif not skip_aspect_ratio and image_file_aspect_ratio > settings.VIDEO_IMAGE_ASPECT_RATIO_ERROR_MARGIN:
|
||||
error = _('This image file must have an aspect ratio of {video_image_aspect_ratio_text}.').format(
|
||||
error = _(u'This image file must have an aspect ratio of {video_image_aspect_ratio_text}.').format(
|
||||
video_image_aspect_ratio_text=settings.VIDEO_IMAGE_ASPECT_RATIO_TEXT
|
||||
)
|
||||
else:
|
||||
@@ -106,7 +106,7 @@ def validate_and_update_video_image(course_key_string, edx_video_id, image_file,
|
||||
error = validate_video_image(image_file, skip_aspect_ratio=True)
|
||||
if error:
|
||||
LOGGER.info(
|
||||
'VIDEOS: Scraping youtube video thumbnail failed for edx_video_id [%s] in course [%s] with error: %s',
|
||||
u'VIDEOS: Scraping youtube video thumbnail failed for edx_video_id [%s] in course [%s] with error: %s',
|
||||
edx_video_id,
|
||||
course_key_string,
|
||||
error
|
||||
@@ -115,7 +115,7 @@ def validate_and_update_video_image(course_key_string, edx_video_id, image_file,
|
||||
|
||||
update_video_image(edx_video_id, course_key_string, image_file, image_filename)
|
||||
LOGGER.info(
|
||||
'VIDEOS: Scraping youtube video thumbnail for edx_video_id [%s] in course [%s]', edx_video_id, course_key_string
|
||||
u'VIDEOS: Scraping youtube video thumbnail for edx_video_id [%s] in course [%s]', edx_video_id, course_key_string
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -200,9 +200,9 @@ def _get_error_if_invalid_parameters(requested_filter):
|
||||
if invalid_filters:
|
||||
error_message = {
|
||||
'error_code': 'invalid_asset_type_filter',
|
||||
'developer_message': 'The asset_type parameter to the request is invalid. '
|
||||
'The {} filters are not described in the settings.FILES_AND_UPLOAD_TYPE_FILTERS '
|
||||
'dictionary.'.format(invalid_filters)
|
||||
'developer_message': u'The asset_type parameter to the request is invalid. '
|
||||
u'The {} filters are not described in the settings.FILES_AND_UPLOAD_TYPE_FILTERS '
|
||||
u'dictionary.'.format(invalid_filters)
|
||||
}
|
||||
return JsonResponse({'error': error_message}, status=400)
|
||||
|
||||
@@ -424,7 +424,7 @@ def _get_error_if_course_does_not_exist(course_key):
|
||||
try:
|
||||
modulestore().get_course(course_key)
|
||||
except ItemNotFoundError:
|
||||
logging.error('Could not find course: %s', course_key)
|
||||
logging.error(u'Could not find course: %s', course_key)
|
||||
return HttpResponseBadRequest()
|
||||
|
||||
|
||||
@@ -456,8 +456,8 @@ def _check_file_size_is_too_large(file_metadata):
|
||||
|
||||
def _get_file_too_large_error_message(filename):
|
||||
return _(
|
||||
'File {filename} exceeds maximum size of '
|
||||
'{maximum_size_in_megabytes} MB.'
|
||||
u'File {filename} exceeds maximum size of '
|
||||
u'{maximum_size_in_megabytes} MB.'
|
||||
).format(
|
||||
filename=filename,
|
||||
maximum_size_in_megabytes=settings.MAX_ASSET_UPLOAD_FILE_SIZE_IN_MB,
|
||||
@@ -564,7 +564,7 @@ def _delete_thumbnail(thumbnail_location, course_key, asset_key):
|
||||
contentstore().delete(thumbnail_content.get_id())
|
||||
del_cached_content(thumbnail_location)
|
||||
except Exception: # pylint: disable=broad-except
|
||||
logging.warning('Could not delete thumbnail: %s', thumbnail_location)
|
||||
logging.warning(u'Could not delete thumbnail: %s', thumbnail_location)
|
||||
|
||||
|
||||
def _get_asset_json(display_name, content_type, date, location, thumbnail_location, locked):
|
||||
|
||||
@@ -83,7 +83,7 @@ def _delete_asset(course_key, asset_key_string):
|
||||
except InvalidKeyError:
|
||||
# Unable to parse the asset key, log and return
|
||||
LOGGER.info(
|
||||
"In course %r, unable to parse asset key %r, not attempting to delete signatory.",
|
||||
u"In course %r, unable to parse asset key %r, not attempting to delete signatory.",
|
||||
course_key,
|
||||
asset_key_string,
|
||||
)
|
||||
@@ -91,7 +91,7 @@ def _delete_asset(course_key, asset_key_string):
|
||||
else:
|
||||
# Unable to parse the asset key, log and return
|
||||
LOGGER.info(
|
||||
"In course %r, unable to parse asset key %r, not attempting to delete signatory.",
|
||||
u"In course %r, unable to parse asset key %r, not attempting to delete signatory.",
|
||||
course_key,
|
||||
asset_key_string,
|
||||
)
|
||||
@@ -149,7 +149,7 @@ class CertificateManager(object):
|
||||
# Ensure the schema version meets our expectations
|
||||
if certificate_data.get("version") != CERTIFICATE_SCHEMA_VERSION:
|
||||
raise TypeError(
|
||||
"Unsupported certificate schema version: {0}. Expected version: {1}.".format(
|
||||
u"Unsupported certificate schema version: {0}. Expected version: {1}.".format(
|
||||
certificate_data.get("version"),
|
||||
CERTIFICATE_SCHEMA_VERSION
|
||||
)
|
||||
@@ -238,7 +238,7 @@ class CertificateManager(object):
|
||||
# Ensure the schema fieldset meets our expectations
|
||||
for key in ("name", "description", "version"):
|
||||
if key not in value:
|
||||
raise CertificateValidationError(_("Certificate dict {0} missing value key '{1}'").format(value, key))
|
||||
raise CertificateValidationError(_(u"Certificate dict {0} missing value key '{1}'").format(value, key))
|
||||
|
||||
# Load up the Certificate data
|
||||
certificate_data = CertificateManager.parse(value)
|
||||
@@ -343,7 +343,7 @@ def certificate_activation_handler(request, course_key_string):
|
||||
try:
|
||||
course = _get_course_and_check_access(course_key, request.user)
|
||||
except PermissionDenied:
|
||||
msg = _('PermissionDenied: Failed in authenticating {user}').format(user=request.user)
|
||||
msg = _(u'PermissionDenied: Failed in authenticating {user}').format(user=request.user)
|
||||
return JsonResponse({"error": msg}, status=403)
|
||||
|
||||
data = json.loads(request.body)
|
||||
@@ -381,7 +381,7 @@ def certificates_list_handler(request, course_key_string):
|
||||
try:
|
||||
course = _get_course_and_check_access(course_key, request.user)
|
||||
except PermissionDenied:
|
||||
msg = _('PermissionDenied: Failed in authenticating {user}').format(user=request.user)
|
||||
msg = _(u'PermissionDenied: Failed in authenticating {user}').format(user=request.user)
|
||||
return JsonResponse({"error": msg}, status=403)
|
||||
|
||||
if 'text/html' in request.META.get('HTTP_ACCEPT', 'text/html'):
|
||||
|
||||
@@ -234,7 +234,7 @@ def get_component_templates(courselike, library=False):
|
||||
return {
|
||||
"show_legend": XBlockStudioConfigurationFlag.is_enabled(),
|
||||
"allow_unsupported_xblocks": allow_unsupported,
|
||||
"documentation_label": _("{platform_name} Support Levels:").format(platform_name=settings.PLATFORM_NAME)
|
||||
"documentation_label": _(u"{platform_name} Support Levels:").format(platform_name=settings.PLATFORM_NAME)
|
||||
}
|
||||
|
||||
component_display_names = {
|
||||
@@ -323,7 +323,7 @@ def get_component_templates(courselike, library=False):
|
||||
try:
|
||||
component_display_name = xblock_type_display_name(component)
|
||||
except PluginMissingError:
|
||||
log.warning('Unable to load xblock type %s to read display_name', component, exc_info=True)
|
||||
log.warning(u'Unable to load xblock type %s to read display_name', component, exc_info=True)
|
||||
else:
|
||||
templates_for_category.append(
|
||||
create_template_dict(
|
||||
@@ -381,12 +381,12 @@ def get_component_templates(courselike, library=False):
|
||||
# prevents any authors from trying to instantiate the
|
||||
# non-existent component type by not showing it in the menu
|
||||
log.warning(
|
||||
"Advanced component %s does not exist. It will not be added to the Studio new component menu.",
|
||||
u"Advanced component %s does not exist. It will not be added to the Studio new component menu.",
|
||||
category
|
||||
)
|
||||
else:
|
||||
log.error(
|
||||
"Improper format for course advanced keys! %s",
|
||||
u"Improper format for course advanced keys! %s",
|
||||
course_advanced_keys
|
||||
)
|
||||
if len(advanced_component_templates['templates']) > 0:
|
||||
@@ -459,7 +459,7 @@ def component_handler(request, usage_key_string, handler, suffix=''):
|
||||
handler_descriptor.xmodule_runtime = StudioEditModuleRuntime(request.user)
|
||||
resp = handler_descriptor.handle(handler, req, suffix)
|
||||
except NoSuchHandlerError:
|
||||
log.info("XBlock %s attempted to access missing handler %r", handler_descriptor, handler, exc_info=True)
|
||||
log.info(u"XBlock %s attempted to access missing handler %r", handler_descriptor, handler, exc_info=True)
|
||||
raise Http404
|
||||
|
||||
# unintentional update to handle any side effects of handle call
|
||||
|
||||
@@ -846,7 +846,7 @@ def _create_or_rerun_course(request):
|
||||
})
|
||||
except InvalidKeyError as error:
|
||||
return JsonResponse({
|
||||
"ErrMsg": _("Unable to create course '{name}'.\n\n{err}").format(name=display_name, err=text_type(error))}
|
||||
"ErrMsg": _(u"Unable to create course '{name}'.\n\n{err}").format(name=display_name, err=text_type(error))}
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -246,7 +246,7 @@ def add_entrance_exam_milestone(course_id, x_block):
|
||||
if len(milestones):
|
||||
milestone = milestones[0]
|
||||
else:
|
||||
description = 'Autogenerated during {} entrance exam creation.'.format(unicode(course_id))
|
||||
description = u'Autogenerated during {} entrance exam creation.'.format(unicode(course_id))
|
||||
milestone = milestones_helpers.add_milestone({
|
||||
'name': _('Completed Course Entrance Exam'),
|
||||
'namespace': milestone_namespace,
|
||||
|
||||
@@ -32,7 +32,7 @@ def export_git(request, course_key_string):
|
||||
course_module = modulestore().get_course(course_key)
|
||||
failed = False
|
||||
|
||||
log.debug('export_git course_module=%s', course_module)
|
||||
log.debug(u'export_git course_module=%s', course_module)
|
||||
|
||||
msg = ""
|
||||
if 'action' in request.GET and course_module.giturl:
|
||||
|
||||
@@ -141,7 +141,7 @@ def _write_chunk(request, courselike_key):
|
||||
if not course_dir.isdir():
|
||||
os.mkdir(course_dir)
|
||||
|
||||
logging.debug('importing course to {0}'.format(temp_filepath))
|
||||
logging.debug(u'importing course to {0}'.format(temp_filepath))
|
||||
|
||||
# Get upload chunks byte ranges
|
||||
try:
|
||||
@@ -198,7 +198,7 @@ def _write_chunk(request, courselike_key):
|
||||
}]
|
||||
})
|
||||
|
||||
log.info("Course import %s: Upload complete", courselike_key)
|
||||
log.info(u"Course import %s: Upload complete", courselike_key)
|
||||
with open(temp_filepath, 'rb') as local_file:
|
||||
django_file = File(local_file)
|
||||
storage_path = course_import_export_storage.save(u'olx_import/' + filename, django_file)
|
||||
@@ -210,7 +210,7 @@ def _write_chunk(request, courselike_key):
|
||||
_save_request_status(request, courselike_string, -1)
|
||||
if course_dir.isdir():
|
||||
shutil.rmtree(course_dir)
|
||||
log.info("Course import %s: Temp data cleared", courselike_key)
|
||||
log.info(u"Course import %s: Temp data cleared", courselike_key)
|
||||
|
||||
log.exception(
|
||||
"error importing course"
|
||||
@@ -277,7 +277,7 @@ def send_tarball(tarball, size):
|
||||
"""
|
||||
wrapper = FileWrapper(tarball, settings.COURSE_EXPORT_DOWNLOAD_CHUNK_SIZE)
|
||||
response = StreamingHttpResponse(wrapper, content_type='application/x-tgz')
|
||||
response['Content-Disposition'] = 'attachment; filename=%s' % os.path.basename(tarball.name.encode('utf-8'))
|
||||
response['Content-Disposition'] = u'attachment; filename=%s' % os.path.basename(tarball.name.encode('utf-8'))
|
||||
response['Content-Length'] = size
|
||||
return response
|
||||
|
||||
@@ -375,7 +375,7 @@ def export_status_handler(request, course_key_string):
|
||||
output_url = reverse_course_url('export_output_handler', course_key)
|
||||
elif isinstance(artifact.file.storage, S3BotoStorage):
|
||||
filename = os.path.basename(artifact.file.name).encode('utf-8')
|
||||
disposition = 'attachment; filename="{}"'.format(filename)
|
||||
disposition = u'attachment; filename="{}"'.format(filename)
|
||||
output_url = artifact.file.storage.url(artifact.file.name, response_headers={
|
||||
'response-content-disposition': disposition,
|
||||
'response-content-encoding': 'application/octet-stream',
|
||||
|
||||
@@ -344,7 +344,7 @@ def xblock_view_handler(request, usage_key_string, view_name):
|
||||
# dungeon and surface as uneditable, unsaveable, and undeletable
|
||||
# component-goblins.
|
||||
except Exception as exc: # pylint: disable=broad-except
|
||||
log.debug("Unable to render %s for %r", view_name, xblock, exc_info=True)
|
||||
log.debug(u"Unable to render %s for %r", view_name, xblock, exc_info=True)
|
||||
fragment = Fragment(render_to_string('html_error.html', {'message': str(exc)}))
|
||||
|
||||
elif view_name in PREVIEW_VIEWS + container_views:
|
||||
@@ -368,8 +368,8 @@ def xblock_view_handler(request, usage_key_string, view_name):
|
||||
}
|
||||
except ValueError:
|
||||
return HttpResponse(
|
||||
content="Couldn't parse paging parameters: enable_paging: "
|
||||
"{0}, page_number: {1}, page_size: {2}".format(
|
||||
content=u"Couldn't parse paging parameters: enable_paging: "
|
||||
u"{0}, page_number: {1}, page_size: {2}".format(
|
||||
request.GET.get('enable_paging', 'false'),
|
||||
request.GET.get('page_number', 0),
|
||||
request.GET.get('page_size', 0)
|
||||
@@ -587,7 +587,7 @@ def _save_xblock(user, xblock, data=None, children_strings=None, metadata=None,
|
||||
except ValueError as verr:
|
||||
reason = _("Invalid data")
|
||||
if text_type(verr):
|
||||
reason = _("Invalid data ({details})").format(details=text_type(verr))
|
||||
reason = _(u"Invalid data ({details})").format(details=text_type(verr))
|
||||
return JsonResponse({"error": reason}, 400)
|
||||
|
||||
field.write_to(xblock, value)
|
||||
@@ -679,7 +679,7 @@ def _create_item(request):
|
||||
# Only these categories are supported at this time.
|
||||
if category not in ['html', 'problem', 'video']:
|
||||
return HttpResponseBadRequest(
|
||||
"Category '%s' not supported for Libraries" % category, content_type='text/plain'
|
||||
u"Category '%s' not supported for Libraries" % category, content_type='text/plain'
|
||||
)
|
||||
|
||||
created_block = create_xblock(
|
||||
@@ -767,7 +767,7 @@ def _move_item(source_usage_key, target_parent_usage_key, user, target_index=Non
|
||||
|
||||
if (valid_move_type.get(target_parent_type, '') != source_type and
|
||||
target_parent_type not in parent_component_types):
|
||||
error = _('You can not move {source_type} into {target_parent_type}.').format(
|
||||
error = _(u'You can not move {source_type} into {target_parent_type}.').format(
|
||||
source_type=source_type,
|
||||
target_parent_type=target_parent_type,
|
||||
)
|
||||
@@ -780,7 +780,7 @@ def _move_item(source_usage_key, target_parent_usage_key, user, target_index=Non
|
||||
elif target_parent_type == 'split_test':
|
||||
error = _('You can not move an item directly into content experiment.')
|
||||
elif source_index is None:
|
||||
error = _('{source_usage_key} not found in {parent_usage_key}.').format(
|
||||
error = _(u'{source_usage_key} not found in {parent_usage_key}.').format(
|
||||
source_usage_key=unicode(source_usage_key),
|
||||
parent_usage_key=unicode(source_parent.location)
|
||||
)
|
||||
@@ -788,12 +788,12 @@ def _move_item(source_usage_key, target_parent_usage_key, user, target_index=Non
|
||||
try:
|
||||
target_index = int(target_index) if target_index is not None else None
|
||||
if len(target_parent.children) < target_index:
|
||||
error = _('You can not move {source_usage_key} at an invalid index ({target_index}).').format(
|
||||
error = _(u'You can not move {source_usage_key} at an invalid index ({target_index}).').format(
|
||||
source_usage_key=unicode(source_usage_key),
|
||||
target_index=target_index
|
||||
)
|
||||
except ValueError:
|
||||
error = _('You must provide target_index ({target_index}) as an integer.').format(
|
||||
error = _(u'You must provide target_index ({target_index}) as an integer.').format(
|
||||
target_index=target_index
|
||||
)
|
||||
if error:
|
||||
@@ -811,7 +811,7 @@ def _move_item(source_usage_key, target_parent_usage_key, user, target_index=Non
|
||||
)
|
||||
|
||||
log.info(
|
||||
'MOVE: %s moved from %s to %s at %d index',
|
||||
u'MOVE: %s moved from %s to %s at %d index',
|
||||
unicode(source_usage_key),
|
||||
unicode(source_parent.location),
|
||||
unicode(target_parent_usage_key),
|
||||
@@ -852,9 +852,9 @@ def _duplicate_item(parent_usage_key, duplicate_source_usage_key, user, display_
|
||||
duplicate_metadata['display_name'] = display_name
|
||||
else:
|
||||
if source_item.display_name is None:
|
||||
duplicate_metadata['display_name'] = _("Duplicate of {0}").format(source_item.category)
|
||||
duplicate_metadata['display_name'] = _(u"Duplicate of {0}").format(source_item.category)
|
||||
else:
|
||||
duplicate_metadata['display_name'] = _("Duplicate of '{0}'").format(source_item.display_name)
|
||||
duplicate_metadata['display_name'] = _(u"Duplicate of '{0}'").format(source_item.display_name)
|
||||
|
||||
asides_to_create = []
|
||||
for aside in source_item.runtime.get_asides(source_item):
|
||||
@@ -1150,7 +1150,7 @@ def create_xblock_info(xblock, data=None, metadata=None, include_ancestor_info=F
|
||||
# Translators: The {pct_sign} here represents the percent sign, i.e., '%'
|
||||
# in many languages. This is used to avoid Transifex's misinterpreting of
|
||||
# '% o'. The percent sign is also translatable as a standalone string.
|
||||
explanatory_message = _('Students must score {score}{pct_sign} or higher to access course materials.').format(
|
||||
explanatory_message = _(u'Students must score {score}{pct_sign} or higher to access course materials.').format(
|
||||
score=int(parent_xblock.entrance_exam_minimum_score_pct * 100),
|
||||
# Translators: This is the percent sign. It will be used to represent
|
||||
# a percent value out of 100, e.g. "58%" means "58/100".
|
||||
@@ -1487,6 +1487,6 @@ def _xblock_type_and_display_name(xblock):
|
||||
"""
|
||||
Returns a string representation of the xblock's type and display name
|
||||
"""
|
||||
return _('{section_or_subsection} "{display_name}"').format(
|
||||
return _(u'{section_or_subsection} "{display_name}"').format(
|
||||
section_or_subsection=xblock_type_display_name(xblock),
|
||||
display_name=xblock.display_name_with_default)
|
||||
|
||||
@@ -165,12 +165,12 @@ def _create_library(request):
|
||||
except KeyError as error:
|
||||
log.exception("Unable to create library - missing required JSON key.")
|
||||
return JsonResponseBadRequest({
|
||||
"ErrMsg": _("Unable to create library - missing required field '{field}'").format(field=text_type(error))
|
||||
"ErrMsg": _(u"Unable to create library - missing required field '{field}'").format(field=text_type(error))
|
||||
})
|
||||
except InvalidKeyError as error:
|
||||
log.exception("Unable to create library - invalid key.")
|
||||
return JsonResponseBadRequest({
|
||||
"ErrMsg": _("Unable to create library '{name}'.\n\n{err}").format(name=display_name, err=text_type(error))
|
||||
"ErrMsg": _(u"Unable to create library '{name}'.\n\n{err}").format(name=display_name, err=text_type(error))
|
||||
})
|
||||
except DuplicateCourseError:
|
||||
log.exception("Unable to create library - one already exists with the same key.")
|
||||
|
||||
@@ -72,7 +72,7 @@ def preview_handler(request, usage_key_string, handler, suffix=''):
|
||||
resp = instance.handle(handler, req, suffix)
|
||||
|
||||
except NoSuchHandlerError:
|
||||
log.exception("XBlock %s attempted to access missing handler %r", instance, handler)
|
||||
log.exception(u"XBlock %s attempted to access missing handler %r", instance, handler)
|
||||
raise Http404
|
||||
|
||||
except NotFoundError:
|
||||
@@ -284,7 +284,7 @@ def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False):
|
||||
is_reorderable = _is_xblock_reorderable(xblock, context)
|
||||
selected_groups_label = get_visibility_partition_info(xblock)['selected_groups_label']
|
||||
if selected_groups_label:
|
||||
selected_groups_label = _('Access restricted to: {list_of_groups}').format(list_of_groups=selected_groups_label)
|
||||
selected_groups_label = _(u'Access restricted to: {list_of_groups}').format(list_of_groups=selected_groups_label)
|
||||
course = modulestore().get_course(xblock.location.course_key)
|
||||
template_context = {
|
||||
'xblock_context': context,
|
||||
@@ -325,6 +325,6 @@ def get_preview_fragment(request, descriptor, context):
|
||||
try:
|
||||
fragment = module.render(preview_view, context)
|
||||
except Exception as exc: # pylint: disable=broad-except
|
||||
log.warning("Unable to render %s for %r", preview_view, module, exc_info=True)
|
||||
log.warning(u"Unable to render %s for %r", preview_view, module, exc_info=True)
|
||||
fragment = Fragment(render_to_string('html_error.html', {'message': str(exc)}))
|
||||
return fragment
|
||||
|
||||
@@ -97,7 +97,7 @@ def reorder_tabs_handler(course_item, request):
|
||||
tab = get_tab_by_tab_id_locator(old_tab_list, tab_id_locator)
|
||||
if tab is None:
|
||||
return JsonResponse(
|
||||
{"error": "Tab with id_locator '{0}' does not exist.".format(tab_id_locator)}, status=400
|
||||
{"error": u"Tab with id_locator '{0}' does not exist.".format(tab_id_locator)}, status=400
|
||||
)
|
||||
new_tab_list.append(tab)
|
||||
|
||||
@@ -111,7 +111,7 @@ def reorder_tabs_handler(course_item, request):
|
||||
CourseTabList.validate_tabs(new_tab_list)
|
||||
except InvalidTabsException, exception:
|
||||
return JsonResponse(
|
||||
{"error": "New list of tabs is not valid: {0}.".format(str(exception))}, status=400
|
||||
{"error": u"New list of tabs is not valid: {0}.".format(str(exception))}, status=400
|
||||
)
|
||||
|
||||
# persist the new order of the tabs
|
||||
@@ -133,7 +133,7 @@ def edit_tab_handler(course_item, request):
|
||||
tab = get_tab_by_tab_id_locator(course_item.tabs, tab_id_locator)
|
||||
if tab is None:
|
||||
return JsonResponse(
|
||||
{"error": "Tab with id_locator '{0}' does not exist.".format(tab_id_locator)}, status=400
|
||||
{"error": u"Tab with id_locator '{0}' does not exist.".format(tab_id_locator)}, status=400
|
||||
)
|
||||
|
||||
if 'is_hidden' in request.json:
|
||||
@@ -141,7 +141,7 @@ def edit_tab_handler(course_item, request):
|
||||
tab.is_hidden = request.json['is_hidden']
|
||||
modulestore().update_item(course_item, request.user.id)
|
||||
else:
|
||||
raise NotImplementedError('Unsupported request to edit tab: {0}'.format(request.json))
|
||||
raise NotImplementedError(u'Unsupported request to edit tab: {0}'.format(request.json))
|
||||
|
||||
return JsonResponse()
|
||||
|
||||
|
||||
@@ -151,8 +151,8 @@ class CertificatesBaseTestCase(object):
|
||||
Test invalid json handling.
|
||||
"""
|
||||
# Invalid JSON.
|
||||
invalid_json = "{u'name': 'Test Name', u'description': 'Test description'," \
|
||||
" u'version': " + str(CERTIFICATE_SCHEMA_VERSION) + ", []}"
|
||||
invalid_json = u"{u'name': 'Test Name', u'description': 'Test description'," \
|
||||
u" u'version': " + str(CERTIFICATE_SCHEMA_VERSION) + ", []}"
|
||||
|
||||
response = self.client.post(
|
||||
self._url(),
|
||||
|
||||
@@ -56,13 +56,13 @@ class ContainerPageTestCase(StudioPageTestCase, LibraryTestCase):
|
||||
self._test_html_content(
|
||||
self.child_container,
|
||||
expected_section_tag=(
|
||||
'<section class="wrapper-xblock level-page is-hidden studio-xblock-wrapper" '
|
||||
'data-locator="{0}" data-course-key="{0.course_key}">'.format(self.child_container.location)
|
||||
u'<section class="wrapper-xblock level-page is-hidden studio-xblock-wrapper" '
|
||||
u'data-locator="{0}" data-course-key="{0.course_key}">'.format(self.child_container.location)
|
||||
),
|
||||
expected_breadcrumbs=(
|
||||
r'<a href="/course/{course}{section_parameters}" class="{classes}">\s*Week 1\s*</a>\s*'
|
||||
r'<a href="/course/{course}{subsection_parameters}" class="{classes}">\s*Lesson 1\s*</a>\s*'
|
||||
r'<a href="/container/{unit}" class="{classes}">\s*Unit\s*</a>'
|
||||
ur'<a href="/course/{course}{section_parameters}" class="{classes}">\s*Week 1\s*</a>\s*'
|
||||
ur'<a href="/course/{course}{subsection_parameters}" class="{classes}">\s*Lesson 1\s*</a>\s*'
|
||||
ur'<a href="/container/{unit}" class="{classes}">\s*Unit\s*</a>'
|
||||
).format(
|
||||
course=re.escape(unicode(self.course.id)),
|
||||
unit=re.escape(unicode(self.vertical.location)),
|
||||
@@ -84,19 +84,19 @@ class ContainerPageTestCase(StudioPageTestCase, LibraryTestCase):
|
||||
self._test_html_content(
|
||||
xblock,
|
||||
expected_section_tag=(
|
||||
'<section class="wrapper-xblock level-page is-hidden studio-xblock-wrapper" '
|
||||
'data-locator="{0}" data-course-key="{0.course_key}">'.format(draft_container.location)
|
||||
u'<section class="wrapper-xblock level-page is-hidden studio-xblock-wrapper" '
|
||||
u'data-locator="{0}" data-course-key="{0.course_key}">'.format(draft_container.location)
|
||||
),
|
||||
expected_breadcrumbs=(
|
||||
r'<a href="/course/{course}{section_parameters}" class="{classes}">\s*Week 1\s*</a>\s*'
|
||||
r'<a href="/course/{course}{subsection_parameters}" class="{classes}">\s*Lesson 1\s*</a>\s*'
|
||||
r'<a href="/container/{unit}" class="{classes}">\s*Unit\s*</a>\s*'
|
||||
r'<a href="/container/{split_test}" class="{classes}">\s*Split Test\s*</a>'
|
||||
ur'<a href="/course/{course}{section_parameters}" class="{classes}">\s*Week 1\s*</a>\s*'
|
||||
ur'<a href="/course/{course}{subsection_parameters}" class="{classes}">\s*Lesson 1\s*</a>\s*'
|
||||
ur'<a href="/container/{unit}" class="{classes}">\s*Unit\s*</a>\s*'
|
||||
ur'<a href="/container/{split_test}" class="{classes}">\s*Split Test\s*</a>'
|
||||
).format(
|
||||
course=re.escape(unicode(self.course.id)),
|
||||
unit=re.escape(unicode(self.vertical.location)),
|
||||
split_test=re.escape(unicode(self.child_container.location)),
|
||||
classes='navigation-item navigation-link navigation-parent',
|
||||
classes=u'navigation-item navigation-link navigation-parent',
|
||||
section_parameters=re.escape(u'?show={}'.format(http.urlquote(self.chapter.location))),
|
||||
subsection_parameters=re.escape(u'?show={}'.format(http.urlquote(self.sequential.location))),
|
||||
),
|
||||
|
||||
@@ -529,7 +529,7 @@ class TestCourseOutline(CourseTestCase):
|
||||
ItemFactory.create(
|
||||
parent_location=self.vertical.location,
|
||||
category=block_type,
|
||||
display_name='{} Problem'.format(block_type)
|
||||
display_name=u'{} Problem'.format(block_type)
|
||||
)
|
||||
|
||||
if not publish:
|
||||
@@ -546,7 +546,7 @@ class TestCourseOutline(CourseTestCase):
|
||||
expected_blocks.append(
|
||||
[
|
||||
reverse_usage_url('container_handler', self.vertical.location),
|
||||
'{} Problem'.format(block_type)
|
||||
u'{} Problem'.format(block_type)
|
||||
]
|
||||
)
|
||||
|
||||
|
||||
@@ -53,12 +53,12 @@ class HelperMethods(object):
|
||||
sequential = ItemFactory.create(
|
||||
category='sequential',
|
||||
parent_location=self.course.location,
|
||||
display_name='Test Subsection {}'.format(name_suffix)
|
||||
display_name=u'Test Subsection {}'.format(name_suffix)
|
||||
)
|
||||
vertical = ItemFactory.create(
|
||||
category='vertical',
|
||||
parent_location=sequential.location,
|
||||
display_name='Test Unit {}'.format(name_suffix)
|
||||
display_name=u'Test Unit {}'.format(name_suffix)
|
||||
)
|
||||
c0_url = self.course.id.make_usage_key("vertical", "split_test_cond0")
|
||||
c1_url = self.course.id.make_usage_key("vertical", "split_test_cond1")
|
||||
@@ -122,14 +122,14 @@ class HelperMethods(object):
|
||||
subsection = ItemFactory.create(
|
||||
category='sequential',
|
||||
parent_location=self.course.location,
|
||||
display_name="Test Subsection {}".format(name_suffix)
|
||||
display_name=u"Test Subsection {}".format(name_suffix)
|
||||
)
|
||||
vertical_parent_location = subsection.location
|
||||
|
||||
vertical = ItemFactory.create(
|
||||
category='vertical',
|
||||
parent_location=vertical_parent_location,
|
||||
display_name="Test Unit {}".format(name_suffix)
|
||||
display_name=u"Test Unit {}".format(name_suffix)
|
||||
)
|
||||
|
||||
problem = ItemFactory.create(
|
||||
@@ -226,7 +226,7 @@ class GroupConfigurationsBaseTestCase(object):
|
||||
Test invalid json handling.
|
||||
"""
|
||||
# No property name.
|
||||
invalid_json = "{u'name': 'Test Name', []}"
|
||||
invalid_json = u"{u'name': 'Test Name', []}"
|
||||
|
||||
response = self.client.post(
|
||||
self._url(),
|
||||
|
||||
@@ -250,7 +250,7 @@ class GetItemTest(ItemTest):
|
||||
html,
|
||||
# The instance of the wrapper class will have an auto-generated ID. Allow any
|
||||
# characters after wrapper.
|
||||
r'"/container/{}" class="action-button">\s*<span class="action-button-text">View</span>'.format(
|
||||
ur'"/container/{}" class="action-button">\s*<span class="action-button-text">View</span>'.format(
|
||||
wrapper_usage_key
|
||||
)
|
||||
)
|
||||
@@ -640,10 +640,10 @@ class DuplicateHelper(object):
|
||||
return duplicated_item.display_name == original_item.category
|
||||
return duplicated_item.display_name == original_item.display_name
|
||||
if original_item.display_name is not None:
|
||||
return duplicated_item.display_name == "Duplicate of '{display_name}'".format(
|
||||
return duplicated_item.display_name == u"Duplicate of '{display_name}'".format(
|
||||
display_name=original_item.display_name
|
||||
)
|
||||
return duplicated_item.display_name == "Duplicate of {display_name}".format(
|
||||
return duplicated_item.display_name == u"Duplicate of {display_name}".format(
|
||||
display_name=original_item.category
|
||||
)
|
||||
|
||||
@@ -983,7 +983,7 @@ class TestMoveItem(ItemTest):
|
||||
self.assertEqual(response.status_code, 400)
|
||||
response = json.loads(response.content)
|
||||
|
||||
expected_error = 'You can not move {usage_key} at an invalid index ({target_index}).'.format(
|
||||
expected_error = u'You can not move {usage_key} at an invalid index ({target_index}).'.format(
|
||||
usage_key=self.html_usage_key,
|
||||
target_index=parent_children_length + 10
|
||||
)
|
||||
@@ -1000,7 +1000,7 @@ class TestMoveItem(ItemTest):
|
||||
self.assertEqual(response.status_code, 400)
|
||||
response = json.loads(response.content)
|
||||
|
||||
expected_error = 'You can not move {source_type} into {target_type}.'.format(
|
||||
expected_error = u'You can not move {source_type} into {target_type}.'.format(
|
||||
source_type=self.html_usage_key.block_type,
|
||||
target_type=self.seq_usage_key.block_type
|
||||
)
|
||||
@@ -1145,7 +1145,7 @@ class TestMoveItem(ItemTest):
|
||||
self.assertEqual(response.status_code, 400)
|
||||
response = json.loads(response.content)
|
||||
|
||||
error = 'You must provide target_index ({target_index}) as an integer.'.format(target_index=target_index)
|
||||
error = u'You must provide target_index ({target_index}) as an integer.'.format(target_index=target_index)
|
||||
self.assertEqual(response['error'], error)
|
||||
new_parent_loc = self.store.get_parent_location(self.html_usage_key)
|
||||
self.assertEqual(new_parent_loc, parent_loc)
|
||||
@@ -1242,7 +1242,7 @@ class TestMoveItem(ItemTest):
|
||||
insert_at = 0
|
||||
self.assert_move_item(self.html_usage_key, self.vert2_usage_key, insert_at)
|
||||
mock_logger.info.assert_called_with(
|
||||
'MOVE: %s moved from %s to %s at %d index',
|
||||
u'MOVE: %s moved from %s to %s at %d index',
|
||||
unicode(self.html_usage_key),
|
||||
unicode(self.vert_usage_key),
|
||||
unicode(self.vert2_usage_key),
|
||||
|
||||
@@ -21,9 +21,9 @@ class TestOrganizationListing(TestCase):
|
||||
self.org_short_names = ["alphaX", "betaX", "orgX"]
|
||||
for index, short_name in enumerate(self.org_short_names):
|
||||
add_organization(organization_data={
|
||||
'name': 'Test Organization %s' % index,
|
||||
'name': u'Test Organization %s' % index,
|
||||
'short_name': short_name,
|
||||
'description': 'Testing Organization %s Description' % index,
|
||||
'description': u'Testing Organization %s Description' % index,
|
||||
})
|
||||
|
||||
def test_organization_list(self):
|
||||
|
||||
@@ -836,7 +836,7 @@ class TestCheckTranscripts(BaseTranscripts):
|
||||
"""
|
||||
def test_success_download_nonyoutube(self):
|
||||
subs_id = str(uuid4())
|
||||
self.item.data = textwrap.dedent("""
|
||||
self.item.data = textwrap.dedent(u"""
|
||||
<video youtube="" sub="{}">
|
||||
<source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4"/>
|
||||
<source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.webm"/>
|
||||
@@ -1030,7 +1030,7 @@ class TestCheckTranscripts(BaseTranscripts):
|
||||
usage_key = self._get_usage_key(resp)
|
||||
subs_id = str(uuid4())
|
||||
item = modulestore().get_item(usage_key)
|
||||
item.data = textwrap.dedent("""
|
||||
item.data = textwrap.dedent(u"""
|
||||
<not_video youtube="" sub="{}">
|
||||
<source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.mp4"/>
|
||||
<source src="http://www.quirksmode.org/html5/videos/big_buck_bunny.webm"/>
|
||||
|
||||
@@ -449,7 +449,7 @@ class VideosHandlerTestCase(VideoUploadTestMixin, CourseTestCase):
|
||||
)
|
||||
self.assertEqual(response.status_code, 400)
|
||||
response = json.loads(response.content)
|
||||
self.assertEqual(response['error'], 'The file name for %s must contain only ASCII characters.' % file_name)
|
||||
self.assertEqual(response['error'], u'The file name for %s must contain only ASCII characters.' % file_name)
|
||||
|
||||
@override_settings(AWS_ACCESS_KEY_ID='test_key_id', AWS_SECRET_ACCESS_KEY='test_secret')
|
||||
@patch('boto.s3.key.Key')
|
||||
@@ -726,7 +726,7 @@ class VideosHandlerTestCase(VideoUploadTestMixin, CourseTestCase):
|
||||
)
|
||||
|
||||
mock_logger.info.assert_called_with(
|
||||
'VIDEOS: Video status update with id [%s], status [%s] and message [%s]',
|
||||
u'VIDEOS: Video status update with id [%s], status [%s] and message [%s]',
|
||||
edx_video_id,
|
||||
'upload_failed',
|
||||
'server down'
|
||||
@@ -935,7 +935,7 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
|
||||
{
|
||||
'extension': '.tiff'
|
||||
},
|
||||
'This image file type is not supported. Supported file types are {supported_file_formats}.'.format(
|
||||
u'This image file type is not supported. Supported file types are {supported_file_formats}.'.format(
|
||||
supported_file_formats=settings.VIDEO_IMAGE_SUPPORTED_FILE_FORMATS.keys()
|
||||
)
|
||||
),
|
||||
@@ -944,7 +944,7 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
|
||||
{
|
||||
'size': settings.VIDEO_IMAGE_SETTINGS['VIDEO_IMAGE_MAX_BYTES'] + 10
|
||||
},
|
||||
'This image file must be smaller than {image_max_size}.'.format(
|
||||
u'This image file must be smaller than {image_max_size}.'.format(
|
||||
image_max_size=settings.VIDEO_IMAGE_MAX_FILE_SIZE_MB
|
||||
)
|
||||
),
|
||||
@@ -952,7 +952,7 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
|
||||
{
|
||||
'size': settings.VIDEO_IMAGE_SETTINGS['VIDEO_IMAGE_MIN_BYTES'] - 10
|
||||
},
|
||||
'This image file must be larger than {image_min_size}.'.format(
|
||||
u'This image file must be larger than {image_min_size}.'.format(
|
||||
image_min_size=settings.VIDEO_IMAGE_MIN_FILE_SIZE_KB
|
||||
)
|
||||
),
|
||||
@@ -962,7 +962,7 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
|
||||
'width': 16, # 16x9
|
||||
'height': 9
|
||||
},
|
||||
'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format(
|
||||
u'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format(
|
||||
image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
|
||||
image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
|
||||
image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
|
||||
@@ -974,7 +974,7 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
|
||||
'width': settings.VIDEO_IMAGE_MIN_WIDTH - 10,
|
||||
'height': settings.VIDEO_IMAGE_MIN_HEIGHT
|
||||
},
|
||||
'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format(
|
||||
u'Recommended image resolution is {image_file_max_width}x{image_file_max_height}. The minimum resolution is {image_file_min_width}x{image_file_min_height}.'.format(
|
||||
image_file_max_width=settings.VIDEO_IMAGE_MAX_WIDTH,
|
||||
image_file_max_height=settings.VIDEO_IMAGE_MAX_HEIGHT,
|
||||
image_file_min_width=settings.VIDEO_IMAGE_MIN_WIDTH,
|
||||
@@ -1032,7 +1032,7 @@ class VideoImageTestCase(VideoUploadTestBase, CourseTestCase):
|
||||
'width': settings.VIDEO_IMAGE_MIN_WIDTH + 100,
|
||||
'height': settings.VIDEO_IMAGE_MIN_HEIGHT + 200
|
||||
},
|
||||
'This image file must have an aspect ratio of {video_image_aspect_ratio_text}.'.format(
|
||||
u'This image file must have an aspect ratio of {video_image_aspect_ratio_text}.'.format(
|
||||
video_image_aspect_ratio_text=settings.VIDEO_IMAGE_ASPECT_RATIO_TEXT
|
||||
)
|
||||
),
|
||||
@@ -1411,7 +1411,7 @@ class VideoUrlsCsvTestCase(VideoUploadTestMixin, CourseTestCase):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(
|
||||
response["Content-Disposition"],
|
||||
"attachment; filename={course}_video_urls.csv".format(course=self.course.id.course)
|
||||
u"attachment; filename={course}_video_urls.csv".format(course=self.course.id.course)
|
||||
)
|
||||
response_reader = StringIO(response.content)
|
||||
reader = csv.DictReader(response_reader, dialect=csv.excel)
|
||||
@@ -1419,7 +1419,7 @@ class VideoUrlsCsvTestCase(VideoUploadTestMixin, CourseTestCase):
|
||||
reader.fieldnames,
|
||||
(
|
||||
["Name", "Duration", "Date Added", "Video ID", "Status"] +
|
||||
["{} URL".format(profile) for profile in expected_profiles]
|
||||
[u"{} URL".format(profile) for profile in expected_profiles]
|
||||
)
|
||||
)
|
||||
rows = list(reader)
|
||||
@@ -1436,7 +1436,7 @@ class VideoUrlsCsvTestCase(VideoUploadTestMixin, CourseTestCase):
|
||||
self.assertEqual(response_video["Video ID"], original_video["edx_video_id"])
|
||||
self.assertEqual(response_video["Status"], convert_video_status(original_video))
|
||||
for profile in expected_profiles:
|
||||
response_profile_url = response_video["{} URL".format(profile)]
|
||||
response_profile_url = response_video[u"{} URL".format(profile)]
|
||||
original_encoded_for_profile = next(
|
||||
(
|
||||
original_encoded
|
||||
@@ -1468,5 +1468,5 @@ class VideoUrlsCsvTestCase(VideoUploadTestMixin, CourseTestCase):
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertEqual(
|
||||
response["Content-Disposition"],
|
||||
"attachment; filename=video_urls.csv; filename*=utf-8''n%C3%B3n-%C3%A4scii_video_urls.csv"
|
||||
u"attachment; filename=video_urls.csv; filename*=utf-8''n%C3%B3n-%C3%A4scii_video_urls.csv"
|
||||
)
|
||||
|
||||
@@ -29,7 +29,7 @@ class StudioPageTestCase(CourseTestCase):
|
||||
self.assertIsNotNone(url)
|
||||
resp = self.client.get_html(url)
|
||||
self.assertEqual(resp.status_code, 200)
|
||||
return resp.content
|
||||
return resp.content.decode(resp.charset)
|
||||
|
||||
def get_preview_html(self, xblock, view_name):
|
||||
"""
|
||||
|
||||
@@ -162,7 +162,7 @@ def transcript_download_handler(request):
|
||||
)
|
||||
# Construct an HTTP response
|
||||
response = HttpResponse(transcript_content, content_type=Transcript.mime_types[Transcript.SRT])
|
||||
response['Content-Disposition'] = 'attachment; filename="{filename}"'.format(filename=transcript_filename)
|
||||
response['Content-Disposition'] = u'attachment; filename="{filename}"'.format(filename=transcript_filename)
|
||||
else:
|
||||
response = HttpResponseNotFound()
|
||||
|
||||
|
||||
@@ -262,7 +262,7 @@ def download_transcripts(request):
|
||||
|
||||
# Construct an HTTP response
|
||||
response = HttpResponse(content, content_type=mimetype)
|
||||
response['Content-Disposition'] = 'attachment; filename="{filename}"'.format(filename=filename.encode('utf-8'))
|
||||
response['Content-Disposition'] = u'attachment; filename="{filename}"'.format(filename=filename.encode('utf-8'))
|
||||
return response
|
||||
|
||||
|
||||
@@ -337,7 +337,7 @@ def check_transcripts(request):
|
||||
local_transcripts = contentstore().find(content_location).data
|
||||
transcripts_presence['youtube_local'] = True
|
||||
except NotFoundError:
|
||||
log.debug("Can't find transcripts in storage for youtube id: %s", youtube_id)
|
||||
log.debug(u"Can't find transcripts in storage for youtube id: %s", youtube_id)
|
||||
|
||||
# youtube server
|
||||
youtube_text_api = copy.deepcopy(settings.YOUTUBE['TEXT_API'])
|
||||
@@ -371,7 +371,7 @@ def check_transcripts(request):
|
||||
html5_subs.append(contentstore().find(content_location).data)
|
||||
transcripts_presence['html5_local'].append(html5_id)
|
||||
except NotFoundError:
|
||||
log.debug("Can't find transcripts in storage for non-youtube video_id: %s", html5_id)
|
||||
log.debug(u"Can't find transcripts in storage for non-youtube video_id: %s", html5_id)
|
||||
if len(html5_subs) == 2: # check html5 transcripts for equality
|
||||
transcripts_presence['html5_equal'] = json.loads(html5_subs[0]) == json.loads(html5_subs[1])
|
||||
|
||||
@@ -426,12 +426,12 @@ def _transcripts_logic(transcripts_presence, videos):
|
||||
else: # html5 source have no subtitles
|
||||
# check if item sub has subtitles
|
||||
if transcripts_presence['current_item_subs'] and not transcripts_presence['is_youtube_mode']:
|
||||
log.debug("Command is use existing %s subs", transcripts_presence['current_item_subs'])
|
||||
log.debug(u"Command is use existing %s subs", transcripts_presence['current_item_subs'])
|
||||
command = 'use_existing'
|
||||
else:
|
||||
command = 'not_found'
|
||||
log.debug(
|
||||
"Resulted command: %s, current transcripts: %s, youtube mode: %s",
|
||||
u"Resulted command: %s, current transcripts: %s, youtube mode: %s",
|
||||
command,
|
||||
transcripts_presence['current_item_subs'],
|
||||
transcripts_presence['is_youtube_mode']
|
||||
|
||||
@@ -113,7 +113,7 @@ def _course_team_user(request, course_key, email):
|
||||
user = User.objects.get(email=email)
|
||||
except Exception:
|
||||
msg = {
|
||||
"error": _("Could not find user by email address '{email}'.").format(email=email),
|
||||
"error": _(u"Could not find user by email address '{email}'.").format(email=email),
|
||||
}
|
||||
return JsonResponse(msg, 404)
|
||||
|
||||
@@ -157,7 +157,7 @@ def _course_team_user(request, course_key, email):
|
||||
# can't modify an inactive user but can remove it
|
||||
if not (user.is_active or new_role is None):
|
||||
msg = {
|
||||
"error": _('User {email} has registered but has not yet activated his/her account.').format(email=email),
|
||||
"error": _(u'User {email} has registered but has not yet activated his/her account.').format(email=email),
|
||||
}
|
||||
return JsonResponse(msg, 400)
|
||||
|
||||
|
||||
@@ -220,7 +220,7 @@ def video_images_handler(request, course_key_string, edx_video_id=None):
|
||||
with closing(image_file):
|
||||
image_url = update_video_image(edx_video_id, course_key_string, image_file, image_file.name)
|
||||
LOGGER.info(
|
||||
'VIDEOS: Video image uploaded for edx_video_id [%s] in course [%s]', edx_video_id, course_key_string
|
||||
u'VIDEOS: Video image uploaded for edx_video_id [%s] in course [%s]', edx_video_id, course_key_string
|
||||
)
|
||||
|
||||
return JsonResponse({'image_url': image_url})
|
||||
@@ -256,17 +256,17 @@ def validate_transcript_preferences(provider, cielo24_fidelity, cielo24_turnarou
|
||||
|
||||
# Validate transcription turnaround
|
||||
if cielo24_turnaround not in transcription_plans[provider]['turnaround']:
|
||||
error = 'Invalid cielo24 turnaround {}.'.format(cielo24_turnaround)
|
||||
error = u'Invalid cielo24 turnaround {}.'.format(cielo24_turnaround)
|
||||
return error, preferences
|
||||
|
||||
# Validate transcription languages
|
||||
supported_languages = transcription_plans[provider]['fidelity'][cielo24_fidelity]['languages']
|
||||
if video_source_language not in supported_languages:
|
||||
error = 'Unsupported source language {}.'.format(video_source_language)
|
||||
error = u'Unsupported source language {}.'.format(video_source_language)
|
||||
return error, preferences
|
||||
|
||||
if not len(preferred_languages) or not (set(preferred_languages) <= set(supported_languages.keys())):
|
||||
error = 'Invalid languages {}.'.format(preferred_languages)
|
||||
error = u'Invalid languages {}.'.format(preferred_languages)
|
||||
return error, preferences
|
||||
|
||||
# Validated Cielo24 preferences
|
||||
@@ -277,23 +277,23 @@ def validate_transcript_preferences(provider, cielo24_fidelity, cielo24_turnarou
|
||||
'preferred_languages': preferred_languages,
|
||||
}
|
||||
else:
|
||||
error = 'Invalid cielo24 fidelity {}.'.format(cielo24_fidelity)
|
||||
error = u'Invalid cielo24 fidelity {}.'.format(cielo24_fidelity)
|
||||
elif provider == TranscriptProvider.THREE_PLAY_MEDIA:
|
||||
|
||||
# Validate transcription turnaround
|
||||
if three_play_turnaround not in transcription_plans[provider]['turnaround']:
|
||||
error = 'Invalid 3play turnaround {}.'.format(three_play_turnaround)
|
||||
error = u'Invalid 3play turnaround {}.'.format(three_play_turnaround)
|
||||
return error, preferences
|
||||
|
||||
# Validate transcription languages
|
||||
valid_translations_map = transcription_plans[provider]['translations']
|
||||
if video_source_language not in valid_translations_map.keys():
|
||||
error = 'Unsupported source language {}.'.format(video_source_language)
|
||||
error = u'Unsupported source language {}.'.format(video_source_language)
|
||||
return error, preferences
|
||||
|
||||
valid_target_languages = valid_translations_map[video_source_language]
|
||||
if not len(preferred_languages) or not (set(preferred_languages) <= set(valid_target_languages)):
|
||||
error = 'Invalid languages {}.'.format(preferred_languages)
|
||||
error = u'Invalid languages {}.'.format(preferred_languages)
|
||||
return error, preferences
|
||||
|
||||
# Validated 3PlayMedia preferences
|
||||
@@ -303,7 +303,7 @@ def validate_transcript_preferences(provider, cielo24_fidelity, cielo24_turnarou
|
||||
'preferred_languages': preferred_languages,
|
||||
}
|
||||
else:
|
||||
error = 'Invalid provider {}.'.format(provider)
|
||||
error = u'Invalid provider {}.'.format(provider)
|
||||
|
||||
return error, preferences
|
||||
|
||||
@@ -370,7 +370,7 @@ def video_encodings_download(request, course_key_string):
|
||||
# Translators: This is the header for a CSV file column
|
||||
# containing URLs for video encodings for the named profile
|
||||
# (e.g. desktop, mobile high quality, mobile low quality)
|
||||
return _("{profile_name} URL").format(profile_name=profile)
|
||||
return _(u"{profile_name} URL").format(profile_name=profile)
|
||||
|
||||
profile_whitelist = VideoUploadConfig.get_profile_whitelist()
|
||||
videos, __ = _get_videos(course)
|
||||
@@ -471,7 +471,7 @@ def convert_video_status(video, is_video_encodes_ready=False):
|
||||
if video['status'] == 'upload' and (now - video['created']) > timedelta(hours=MAX_UPLOAD_HOURS):
|
||||
new_status = 'upload_failed'
|
||||
status = StatusDisplayStrings.get(new_status)
|
||||
message = 'Video with id [%s] is still in upload after [%s] hours, setting status to [%s]' % (
|
||||
message = u'Video with id [%s] is still in upload after [%s] hours, setting status to [%s]' % (
|
||||
video['edx_video_id'], MAX_UPLOAD_HOURS, new_status
|
||||
)
|
||||
send_video_status_update([
|
||||
@@ -710,7 +710,7 @@ def videos_post(course, request):
|
||||
try:
|
||||
file_name.encode('ascii')
|
||||
except UnicodeEncodeError:
|
||||
error_msg = 'The file name for %s must contain only ASCII characters.' % file_name
|
||||
error_msg = u'The file name for %s must contain only ASCII characters.' % file_name
|
||||
return JsonResponse({'error': error_msg}, status=400)
|
||||
|
||||
edx_video_id = unicode(uuid4())
|
||||
@@ -791,7 +791,7 @@ def send_video_status_update(updates):
|
||||
for update in updates:
|
||||
update_video_status(update.get('edxVideoId'), update.get('status'))
|
||||
LOGGER.info(
|
||||
'VIDEOS: Video status update with id [%s], status [%s] and message [%s]',
|
||||
u'VIDEOS: Video status update with id [%s], status [%s] and message [%s]',
|
||||
update.get('edxVideoId'),
|
||||
update.get('status'),
|
||||
update.get('message')
|
||||
|
||||
@@ -108,7 +108,7 @@ def send_user_notification_callback(sender, **kwargs):
|
||||
try:
|
||||
user.email_user(subject, message, studio_request_email)
|
||||
except:
|
||||
log.warning("Unable to send course creator status e-mail to %s", user.email)
|
||||
log.warning(u"Unable to send course creator status e-mail to %s", user.email)
|
||||
|
||||
|
||||
@receiver(send_admin_notification, sender=CourseCreator)
|
||||
@@ -134,4 +134,4 @@ def send_admin_notification_callback(sender, **kwargs):
|
||||
fail_silently=False
|
||||
)
|
||||
except SMTPException:
|
||||
log.warning("Failure sending 'pending state' e-mail for %s to %s", user.email, studio_request_email)
|
||||
log.warning(u"Failure sending 'pending state' e-mail for %s to %s", user.email, studio_request_email)
|
||||
|
||||
@@ -182,8 +182,8 @@ class ForcePublishCourseView(MaintenanceBaseView):
|
||||
if not hasattr(source_store, 'force_publish_course'):
|
||||
self.context['msg'] = _('Force publishing course is not supported with old mongo courses.')
|
||||
log.warning(
|
||||
'Force publishing course is not supported with old mongo courses. \
|
||||
%s attempted to force publish the course %s.',
|
||||
u'Force publishing course is not supported with old mongo courses. \
|
||||
%s attempted to force publish the course %s.', # pylint: disable=unicode-format-string
|
||||
request.user,
|
||||
course_id,
|
||||
exc_info=True
|
||||
@@ -196,7 +196,7 @@ class ForcePublishCourseView(MaintenanceBaseView):
|
||||
if current_versions['published-branch'] == current_versions['draft-branch']:
|
||||
self.context['msg'] = _('Course is already in published state.')
|
||||
log.warning(
|
||||
'Course is already in published state. %s attempted to force publish the course %s.',
|
||||
u'Course is already in published state. %s attempted to force publish the course %s.',
|
||||
request.user,
|
||||
course_id,
|
||||
exc_info=True
|
||||
@@ -205,7 +205,7 @@ class ForcePublishCourseView(MaintenanceBaseView):
|
||||
|
||||
self.context['current_versions'] = current_versions
|
||||
log.info(
|
||||
'%s dry ran force publish the course %s.',
|
||||
u'%s dry ran force publish the course %s.',
|
||||
request.user,
|
||||
course_id,
|
||||
exc_info=True
|
||||
|
||||
@@ -203,7 +203,7 @@ class CourseMetadata(object):
|
||||
if hasattr(descriptor, key) and getattr(descriptor, key) != val:
|
||||
key_values[key] = descriptor.fields[key].from_json(val)
|
||||
except (TypeError, ValueError) as err:
|
||||
raise ValueError(_("Incorrect format for field '{name}'. {detailed_message}").format(
|
||||
raise ValueError(_(u"Incorrect format for field '{name}'. {detailed_message}").format(
|
||||
name=model['display_name'], detailed_message=text_type(err)))
|
||||
|
||||
return cls.update_from_dict(key_values, descriptor, user)
|
||||
|
||||
@@ -97,7 +97,7 @@ class StructuredTagsAside(XBlockAside):
|
||||
|
||||
for posted_tag_value in posted_data[av_tag.name]:
|
||||
if posted_tag_value not in tag_available_values and posted_tag_value not in tag_current_values:
|
||||
return Response("Invalid tag value was passed: %s" % posted_tag_value, status=400)
|
||||
return Response(u"Invalid tag value was passed: %s" % posted_tag_value, status=400)
|
||||
|
||||
saved_tags[av_tag.name] = posted_data[av_tag.name]
|
||||
need_update = True
|
||||
|
||||
Reference in New Issue
Block a user