4
AUTHORS
4
AUTHORS
@@ -233,4 +233,6 @@ Dongwook Yoon <dy252@cornell.edu>
|
||||
Awais Qureshi <awais.qureshi@arbisoft.com>
|
||||
Eric Fischer <efischer@edx.org>
|
||||
Brian Beggs <macdiesel@gmail.com>
|
||||
Bill DeRusha <bill@edx.org>
|
||||
Bill DeRusha <bill@edx.org>
|
||||
Kevin Falcone <kevin@edx.org>
|
||||
Mirjam Škarica <mirjamskarica@gmail.com>
|
||||
|
||||
@@ -67,20 +67,20 @@ def _click_advanced():
|
||||
world.wait_for_visible(tab2_css)
|
||||
|
||||
|
||||
def _find_matching_link(category, component_type):
|
||||
def _find_matching_button(category, component_type):
|
||||
"""
|
||||
Find the link with the specified text. There should be one and only one.
|
||||
Find the button with the specified text. There should be one and only one.
|
||||
"""
|
||||
|
||||
# The tab shows links for the given category
|
||||
links = world.css_find('div.new-component-{} a'.format(category))
|
||||
# The tab shows buttons for the given category
|
||||
buttons = world.css_find('div.new-component-{} button'.format(category))
|
||||
|
||||
# Find the link whose text matches what you're looking for
|
||||
matched_links = [link for link in links if link.text == component_type]
|
||||
# Find the button whose text matches what you're looking for
|
||||
matched_buttons = [btn for btn in buttons if btn.text == component_type]
|
||||
|
||||
# There should be one and only one
|
||||
assert_equal(len(matched_links), 1)
|
||||
return matched_links[0]
|
||||
assert_equal(len(matched_buttons), 1)
|
||||
return matched_buttons[0]
|
||||
|
||||
|
||||
def click_component_from_menu(category, component_type, is_advanced):
|
||||
@@ -100,7 +100,7 @@ def click_component_from_menu(category, component_type, is_advanced):
|
||||
|
||||
# Retry this in case the list is empty because you tried too fast.
|
||||
link = world.retry_on_exception(
|
||||
lambda: _find_matching_link(category, component_type),
|
||||
lambda: _find_matching_button(category, component_type),
|
||||
ignored_exceptions=AssertionError
|
||||
)
|
||||
|
||||
|
||||
@@ -18,18 +18,6 @@ from xmodule.modulestore import ModuleStoreEnum
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
|
||||
def print_out_all_courses():
|
||||
"""
|
||||
Print out all the courses available in the course_key format so that
|
||||
the user can correct any course_key mistakes
|
||||
"""
|
||||
courses = modulestore().get_courses_keys()
|
||||
print 'Available courses:'
|
||||
for course in courses:
|
||||
print str(course)
|
||||
print ''
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"""
|
||||
Delete a MongoDB backed course
|
||||
@@ -58,8 +46,6 @@ class Command(BaseCommand):
|
||||
elif len(args) > 2:
|
||||
raise CommandError("Too many arguments! Expected <course_key> <commit>")
|
||||
|
||||
print_out_all_courses()
|
||||
|
||||
if not modulestore().get_course(course_key):
|
||||
raise CommandError("Course with '%s' key not found." % args[0])
|
||||
|
||||
@@ -67,4 +53,4 @@ class Command(BaseCommand):
|
||||
if query_yes_no("Deleting course {0}. Confirm?".format(course_key), default="no"):
|
||||
if query_yes_no("Are you sure. This action cannot be undone!", default="no"):
|
||||
delete_course_and_groups(course_key, ModuleStoreEnum.UserID.mgmt_command)
|
||||
print_out_all_courses()
|
||||
print "Deleted course {}".format(course_key)
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
""" Management command to update courses' search index """
|
||||
import logging
|
||||
from django.core.management import BaseCommand, CommandError
|
||||
from optparse import make_option
|
||||
from textwrap import dedent
|
||||
|
||||
from contentstore.courseware_index import CoursewareSearchIndexer
|
||||
from search.search_engine_base import SearchEngine
|
||||
from elasticsearch import exceptions
|
||||
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
from opaque_keys import InvalidKeyError
|
||||
from opaque_keys.edx.locator import CourseLocator
|
||||
|
||||
from .prompt import query_yes_no
|
||||
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
"""
|
||||
Command to re-index courses
|
||||
|
||||
Examples:
|
||||
|
||||
./manage.py reindex_course <course_id_1> <course_id_2> - reindexes courses with keys course_id_1 and course_id_2
|
||||
./manage.py reindex_course --all - reindexes all available courses
|
||||
./manage.py reindex_course --setup - reindexes all courses for devstack setup
|
||||
"""
|
||||
help = dedent(__doc__)
|
||||
|
||||
can_import_settings = True
|
||||
|
||||
args = "<course_id course_id ...>"
|
||||
|
||||
all_option = make_option('--all',
|
||||
action='store_true',
|
||||
dest='all',
|
||||
default=False,
|
||||
help='Reindex all courses')
|
||||
|
||||
setup_option = make_option('--setup',
|
||||
action='store_true',
|
||||
dest='setup',
|
||||
default=False,
|
||||
help='Reindex all courses on developers stack setup')
|
||||
|
||||
option_list = BaseCommand.option_list + (all_option, setup_option)
|
||||
|
||||
CONFIRMATION_PROMPT = u"Re-indexing all courses might be a time consuming operation. Do you want to continue?"
|
||||
|
||||
def _parse_course_key(self, raw_value):
|
||||
""" Parses course key from string """
|
||||
try:
|
||||
result = CourseKey.from_string(raw_value)
|
||||
except InvalidKeyError:
|
||||
raise CommandError("Invalid course_key: '%s'." % raw_value)
|
||||
|
||||
if not isinstance(result, CourseLocator):
|
||||
raise CommandError(u"Argument {0} is not a course key".format(raw_value))
|
||||
|
||||
return result
|
||||
|
||||
def handle(self, *args, **options):
|
||||
"""
|
||||
By convention set by Django developers, this method actually executes command's actions.
|
||||
So, there could be no better docstring than emphasize this once again.
|
||||
"""
|
||||
all_option = options.get('all', False)
|
||||
setup_option = options.get('setup', False)
|
||||
index_all_courses_option = all_option or setup_option
|
||||
|
||||
if len(args) == 0 and not index_all_courses_option:
|
||||
raise CommandError(u"reindex_course requires one or more arguments: <course_id>")
|
||||
|
||||
store = modulestore()
|
||||
|
||||
if index_all_courses_option:
|
||||
index_name = CoursewareSearchIndexer.INDEX_NAME
|
||||
doc_type = CoursewareSearchIndexer.DOCUMENT_TYPE
|
||||
if setup_option:
|
||||
try:
|
||||
# try getting the ElasticSearch engine
|
||||
searcher = SearchEngine.get_search_engine(index_name)
|
||||
except exceptions.ElasticsearchException as exc:
|
||||
logging.exception('Search Engine error - %s', unicode(exc))
|
||||
return
|
||||
|
||||
index_exists = searcher._es.indices.exists(index=index_name) # pylint: disable=protected-access
|
||||
doc_type_exists = searcher._es.indices.exists_type( # pylint: disable=protected-access
|
||||
index=index_name,
|
||||
doc_type=doc_type
|
||||
)
|
||||
|
||||
index_mapping = searcher._es.indices.get_mapping( # pylint: disable=protected-access
|
||||
index=index_name,
|
||||
doc_type=doc_type
|
||||
) if index_exists and doc_type_exists else {}
|
||||
|
||||
if index_exists and index_mapping:
|
||||
return
|
||||
|
||||
# if reindexing is done during devstack setup step, don't prompt the user
|
||||
if setup_option or query_yes_no(self.CONFIRMATION_PROMPT, default="no"):
|
||||
# in case of --setup or --all, get the list of course keys from all courses
|
||||
# that are stored in the modulestore
|
||||
course_keys = [course.id for course in modulestore().get_courses()]
|
||||
else:
|
||||
return
|
||||
else:
|
||||
# in case course keys are provided as arguments
|
||||
course_keys = map(self._parse_course_key, args)
|
||||
|
||||
for course_key in course_keys:
|
||||
CoursewareSearchIndexer.do_course_reindex(store, course_key)
|
||||
@@ -5,6 +5,7 @@ Unittests for deleting a course in an chosen modulestore
|
||||
import unittest
|
||||
import mock
|
||||
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
from django.core.management import CommandError
|
||||
from contentstore.management.commands.delete_course import Command # pylint: disable=import-error
|
||||
from contentstore.tests.utils import CourseTestCase # pylint: disable=import-error
|
||||
@@ -94,27 +95,23 @@ class DeleteCourseTest(CourseTestCase):
|
||||
run=course_run
|
||||
)
|
||||
|
||||
def test_courses_keys_listing(self):
|
||||
"""
|
||||
Test if the command lists out available course key courses
|
||||
"""
|
||||
courses = [str(key) for key in modulestore().get_courses_keys()]
|
||||
self.assertIn("TestX/TS01/2015_Q1", courses)
|
||||
|
||||
def test_course_key_not_found(self):
|
||||
"""
|
||||
Test for when a non-existing course key is entered
|
||||
"""
|
||||
errstring = "Course with 'TestX/TS01/2015_Q7' key not found."
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
self.command.handle("TestX/TS01/2015_Q7", "commit")
|
||||
self.command.handle('TestX/TS01/2015_Q7', "commit")
|
||||
|
||||
def test_course_deleted(self):
|
||||
"""
|
||||
Testing if the entered course was deleted
|
||||
"""
|
||||
|
||||
#Test if the course that is about to be deleted exists
|
||||
self.assertIsNotNone(modulestore().get_course(SlashSeparatedCourseKey("TestX", "TS01", "2015_Q1")))
|
||||
|
||||
with mock.patch(self.YESNO_PATCH_LOCATION) as patched_yes_no:
|
||||
patched_yes_no.return_value = True
|
||||
self.command.handle("TestX/TS01/2015_Q1", "commit")
|
||||
courses = [unicode(key) for key in modulestore().get_courses_keys()]
|
||||
self.assertNotIn("TestX/TS01/2015_Q1", courses)
|
||||
self.command.handle('TestX/TS01/2015_Q1', "commit")
|
||||
self.assertIsNone(modulestore().get_course(SlashSeparatedCourseKey("TestX", "TS01", "2015_Q1")))
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
""" Tests for course reindex command """
|
||||
import ddt
|
||||
from django.core.management import call_command, CommandError
|
||||
import mock
|
||||
|
||||
from xmodule.modulestore import ModuleStoreEnum
|
||||
from xmodule.modulestore.django import modulestore
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
from common.test.utils import nostderr
|
||||
from xmodule.modulestore.tests.factories import CourseFactory, LibraryFactory
|
||||
|
||||
from contentstore.management.commands.reindex_course import Command as ReindexCommand
|
||||
from contentstore.courseware_index import SearchIndexingError
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
class TestReindexCourse(ModuleStoreTestCase):
|
||||
""" Tests for course reindex command """
|
||||
def setUp(self):
|
||||
""" Setup method - create courses """
|
||||
super(TestReindexCourse, self).setUp()
|
||||
self.store = modulestore()
|
||||
self.first_lib = LibraryFactory.create(
|
||||
org="test", library="lib1", display_name="run1", default_store=ModuleStoreEnum.Type.split
|
||||
)
|
||||
self.second_lib = LibraryFactory.create(
|
||||
org="test", library="lib2", display_name="run2", default_store=ModuleStoreEnum.Type.split
|
||||
)
|
||||
|
||||
self.first_course = CourseFactory.create(
|
||||
org="test", course="course1", display_name="run1"
|
||||
)
|
||||
self.second_course = CourseFactory.create(
|
||||
org="test", course="course2", display_name="run1"
|
||||
)
|
||||
|
||||
REINDEX_PATH_LOCATION = 'contentstore.management.commands.reindex_course.CoursewareSearchIndexer.do_course_reindex'
|
||||
MODULESTORE_PATCH_LOCATION = 'contentstore.management.commands.reindex_course.modulestore'
|
||||
YESNO_PATCH_LOCATION = 'contentstore.management.commands.reindex_course.query_yes_no'
|
||||
|
||||
def _get_lib_key(self, library):
|
||||
""" Get's library key as it is passed to indexer """
|
||||
return library.location.library_key
|
||||
|
||||
def _build_calls(self, *courses):
|
||||
""" Builds a list of mock.call instances representing calls to reindexing method """
|
||||
return [mock.call(self.store, course.id) for course in courses]
|
||||
|
||||
def test_given_no_arguments_raises_command_error(self):
|
||||
""" Test that raises CommandError for incorrect arguments """
|
||||
with self.assertRaises(SystemExit), nostderr():
|
||||
with self.assertRaisesRegexp(CommandError, ".* requires one or more arguments .*"):
|
||||
call_command('reindex_course')
|
||||
|
||||
@ddt.data('qwerty', 'invalid_key', 'xblock-v1:qwe+rty')
|
||||
def test_given_invalid_course_key_raises_not_found(self, invalid_key):
|
||||
""" Test that raises InvalidKeyError for invalid keys """
|
||||
errstring = "Invalid course_key: '%s'." % invalid_key
|
||||
with self.assertRaises(SystemExit) as ex:
|
||||
with self.assertRaisesRegexp(CommandError, errstring):
|
||||
call_command('reindex_course', invalid_key)
|
||||
self.assertEqual(ex.exception.code, 1)
|
||||
|
||||
def test_given_library_key_raises_command_error(self):
|
||||
""" Test that raises CommandError if library key is passed """
|
||||
with self.assertRaises(SystemExit), nostderr():
|
||||
with self.assertRaisesRegexp(SearchIndexingError, ".* is not a course key"):
|
||||
call_command('reindex_course', unicode(self._get_lib_key(self.first_lib)))
|
||||
|
||||
with self.assertRaises(SystemExit), nostderr():
|
||||
with self.assertRaisesRegexp(SearchIndexingError, ".* is not a course key"):
|
||||
call_command('reindex_course', unicode(self._get_lib_key(self.second_lib)))
|
||||
|
||||
with self.assertRaises(SystemExit), nostderr():
|
||||
with self.assertRaisesRegexp(SearchIndexingError, ".* is not a course key"):
|
||||
call_command(
|
||||
'reindex_course',
|
||||
unicode(self.second_course.id),
|
||||
unicode(self._get_lib_key(self.first_lib))
|
||||
)
|
||||
|
||||
def test_given_id_list_indexes_courses(self):
|
||||
""" Test that reindexes courses when given single course key or a list of course keys """
|
||||
with mock.patch(self.REINDEX_PATH_LOCATION) as patched_index, \
|
||||
mock.patch(self.MODULESTORE_PATCH_LOCATION, mock.Mock(return_value=self.store)):
|
||||
call_command('reindex_course', unicode(self.first_course.id))
|
||||
self.assertEqual(patched_index.mock_calls, self._build_calls(self.first_course))
|
||||
patched_index.reset_mock()
|
||||
|
||||
call_command('reindex_course', unicode(self.second_course.id))
|
||||
self.assertEqual(patched_index.mock_calls, self._build_calls(self.second_course))
|
||||
patched_index.reset_mock()
|
||||
|
||||
call_command(
|
||||
'reindex_course',
|
||||
unicode(self.first_course.id),
|
||||
unicode(self.second_course.id)
|
||||
)
|
||||
expected_calls = self._build_calls(self.first_course, self.second_course)
|
||||
self.assertEqual(patched_index.mock_calls, expected_calls)
|
||||
|
||||
def test_given_all_key_prompts_and_reindexes_all_courses(self):
|
||||
""" Test that reindexes all courses when --all key is given and confirmed """
|
||||
with mock.patch(self.YESNO_PATCH_LOCATION) as patched_yes_no:
|
||||
patched_yes_no.return_value = True
|
||||
with mock.patch(self.REINDEX_PATH_LOCATION) as patched_index, \
|
||||
mock.patch(self.MODULESTORE_PATCH_LOCATION, mock.Mock(return_value=self.store)):
|
||||
call_command('reindex_course', all=True)
|
||||
|
||||
patched_yes_no.assert_called_once_with(ReindexCommand.CONFIRMATION_PROMPT, default='no')
|
||||
expected_calls = self._build_calls(self.first_course, self.second_course)
|
||||
self.assertItemsEqual(patched_index.mock_calls, expected_calls)
|
||||
|
||||
def test_given_all_key_prompts_and_reindexes_all_courses_cancelled(self):
|
||||
""" Test that does not reindex anything when --all key is given and cancelled """
|
||||
with mock.patch(self.YESNO_PATCH_LOCATION) as patched_yes_no:
|
||||
patched_yes_no.return_value = False
|
||||
with mock.patch(self.REINDEX_PATH_LOCATION) as patched_index, \
|
||||
mock.patch(self.MODULESTORE_PATCH_LOCATION, mock.Mock(return_value=self.store)):
|
||||
call_command('reindex_course', all=True)
|
||||
|
||||
patched_yes_no.assert_called_once_with(ReindexCommand.CONFIRMATION_PROMPT, default='no')
|
||||
patched_index.assert_not_called()
|
||||
|
||||
def test_fail_fast_if_reindex_fails(self):
|
||||
""" Test that fails on first reindexing exception """
|
||||
with mock.patch(self.REINDEX_PATH_LOCATION) as patched_index:
|
||||
patched_index.side_effect = SearchIndexingError("message", [])
|
||||
|
||||
with self.assertRaises(SearchIndexingError):
|
||||
call_command('reindex_course', unicode(self.second_course.id))
|
||||
@@ -170,6 +170,9 @@ FEATURES = {
|
||||
# Teams feature
|
||||
'ENABLE_TEAMS': True,
|
||||
|
||||
# Teams search feature
|
||||
'ENABLE_TEAMS_SEARCH': False,
|
||||
|
||||
# Show video bumper in Studio
|
||||
'ENABLE_VIDEO_BUMPER': False,
|
||||
|
||||
|
||||
@@ -281,5 +281,8 @@ SEARCH_ENGINE = "search.tests.mock_search_engine.MockSearchEngine"
|
||||
# teams feature
|
||||
FEATURES['ENABLE_TEAMS'] = True
|
||||
|
||||
# teams search
|
||||
FEATURES['ENABLE_TEAMS_SEARCH'] = True
|
||||
|
||||
# Dummy secret key for dev/test
|
||||
SECRET_KEY = '85920908f28904ed733fe576320db18cabd7b6cd'
|
||||
|
||||
@@ -79,7 +79,7 @@ function(_, Course, CertificatesCollection, CertificateModel, CertificateDetails
|
||||
};
|
||||
|
||||
beforeEach(function() {
|
||||
TemplateHelpers.installTemplates(['certificate-details', 'signatory-details', 'signatory-editor'], true);
|
||||
TemplateHelpers.installTemplates(['certificate-details', 'signatory-details', 'signatory-editor', 'signatory-actions'], true);
|
||||
|
||||
this.newModelOptions = {add: true};
|
||||
this.model = new CertificateModel({
|
||||
|
||||
@@ -40,6 +40,7 @@ function ($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, Sign
|
||||
eventAgg: this.eventAgg
|
||||
});
|
||||
this.template = this.loadTemplate('signatory-details');
|
||||
this.signatory_action_template = this.loadTemplate('signatory-actions');
|
||||
},
|
||||
|
||||
loadTemplate: function(name) {
|
||||
@@ -51,6 +52,7 @@ function ($, _, str, Backbone, gettext, TemplateUtils, ViewUtils, BaseView, Sign
|
||||
// Retrieve the edit view for this model
|
||||
if (event && event.preventDefault) { event.preventDefault(); }
|
||||
this.$el.html(this.edit_view.render());
|
||||
$(this.signatory_action_template()).appendTo(this.el);
|
||||
this.edit_view.delegateEvents();
|
||||
this.delegateEvents();
|
||||
},
|
||||
|
||||
@@ -552,7 +552,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
|
||||
var clickNewComponent;
|
||||
|
||||
clickNewComponent = function (index) {
|
||||
containerPage.$(".new-component .new-component-type a.single-template")[index].click();
|
||||
containerPage.$(".new-component .new-component-type button.single-template")[index].click();
|
||||
};
|
||||
|
||||
it('Attaches a handler to new component button', function() {
|
||||
@@ -598,7 +598,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
|
||||
var showTemplatePicker, verifyCreateHtmlComponent;
|
||||
|
||||
showTemplatePicker = function () {
|
||||
containerPage.$('.new-component .new-component-type a.multiple-templates')[0].click();
|
||||
containerPage.$('.new-component .new-component-type button.multiple-templates')[0].click();
|
||||
};
|
||||
|
||||
verifyCreateHtmlComponent = function (test, templateIndex, expectedRequest) {
|
||||
@@ -606,7 +606,7 @@ define(["jquery", "underscore", "underscore.string", "common/js/spec_helpers/aja
|
||||
renderContainerPage(test, mockContainerXBlockHtml);
|
||||
showTemplatePicker();
|
||||
xblockCount = containerPage.$('.studio-xblock-wrapper').length;
|
||||
containerPage.$('.new-component-html a')[templateIndex].click();
|
||||
containerPage.$('.new-component-html button')[templateIndex].click();
|
||||
EditHelpers.verifyXBlockRequest(requests, expectedRequest);
|
||||
AjaxHelpers.respondWithJson(requests, {"locator": "new_item"});
|
||||
respondWithHtml(mockXBlockHtml);
|
||||
|
||||
@@ -89,24 +89,24 @@ function ($, AjaxHelpers, ViewHelpers, ManageUsersFactory, ViewUtils) {
|
||||
|
||||
it("displays an error when the user has already been added", function () {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
var promptSpy = ViewHelpers.createPromptSpy();
|
||||
$('.create-user-button').click();
|
||||
$('.user-email-input').val('honor@example.com');
|
||||
var warningPromptSelector = '.wrapper-prompt.is-shown .prompt.warning';
|
||||
expect($(warningPromptSelector).length).toEqual(0);
|
||||
$('.form-create.create-user .action-primary').click();
|
||||
expect($(warningPromptSelector).length).toEqual(1);
|
||||
expect($(warningPromptSelector)).toContainText('Already a library team member');
|
||||
ViewHelpers.verifyPromptShowing(promptSpy, 'Already a library team member');
|
||||
expect(requests.length).toEqual(0);
|
||||
});
|
||||
|
||||
|
||||
it("can remove a user's permission to access the library", function () {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
var promptSpy = ViewHelpers.createPromptSpy();
|
||||
var reloadSpy = spyOn(ViewUtils, 'reload');
|
||||
var email = "honor@example.com";
|
||||
$('.user-item[data-email="'+email+'"] .action-delete .delete').click();
|
||||
expect($('.wrapper-prompt.is-shown .prompt.warning').length).toEqual(1);
|
||||
$('.wrapper-prompt.is-shown .action-primary').click();
|
||||
ViewHelpers.verifyPromptShowing(promptSpy, 'Are you sure?');
|
||||
ViewHelpers.confirmPrompt(promptSpy);
|
||||
ViewHelpers.verifyPromptHidden(promptSpy);
|
||||
AjaxHelpers.expectJsonRequest(requests, 'DELETE', getUrl(email), {role: null});
|
||||
AjaxHelpers.respondWithJson(requests, {'result': 'ok'});
|
||||
expect(reloadSpy).toHaveBeenCalled();
|
||||
|
||||
@@ -6,10 +6,10 @@ define(["jquery", "underscore", "gettext", "js/views/baseview", "common/js/compo
|
||||
function ($, _, gettext, BaseView, ViewUtils, AddXBlockButton, AddXBlockMenu) {
|
||||
var AddXBlockComponent = BaseView.extend({
|
||||
events: {
|
||||
'click .new-component .new-component-type a.multiple-templates': 'showComponentTemplates',
|
||||
'click .new-component .new-component-type a.single-template': 'createNewComponent',
|
||||
'click .new-component .new-component-type button.multiple-templates': 'showComponentTemplates',
|
||||
'click .new-component .new-component-type button.single-template': 'createNewComponent',
|
||||
'click .new-component .cancel-button': 'closeNewComponent',
|
||||
'click .new-component-templates .new-component-template a': 'createNewComponent',
|
||||
'click .new-component-templates .new-component-template .button-component': 'createNewComponent',
|
||||
'click .new-component-templates .cancel-button': 'closeNewComponent'
|
||||
},
|
||||
|
||||
@@ -43,13 +43,17 @@ define(["jquery", "underscore", "gettext", "js/views/baseview", "common/js/compo
|
||||
type = $(event.currentTarget).data('type');
|
||||
this.$('.new-component').slideUp(250);
|
||||
this.$('.new-component-' + type).slideDown(250);
|
||||
this.$('.new-component-' + type + ' div').focus();
|
||||
},
|
||||
|
||||
closeNewComponent: function(event) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
type = $(event.currentTarget).data('type');
|
||||
this.$('.new-component').slideDown(250);
|
||||
this.$('.new-component-templates').slideUp(250);
|
||||
this.$('ul.new-component-type li button[data-type=' + type + ']').focus();
|
||||
|
||||
},
|
||||
|
||||
createNewComponent: function(event) {
|
||||
|
||||
@@ -13,40 +13,35 @@
|
||||
|
||||
.large-advanced-icon {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
height: 60px;
|
||||
margin-right: ($baseline/4);
|
||||
width: ($baseline*3);
|
||||
height: ($baseline*3);
|
||||
background: url(../images/large-advanced-icon.png) center no-repeat;
|
||||
}
|
||||
|
||||
.large-discussion-icon {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
height: 60px;
|
||||
margin-right: ($baseline/4);
|
||||
width: ($baseline*3);
|
||||
height: ($baseline*3);
|
||||
background: url(../images/large-discussion-icon.png) center no-repeat;
|
||||
}
|
||||
|
||||
.large-html-icon {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
height: 60px;
|
||||
margin-right: ($baseline/4);
|
||||
width: ($baseline*3);
|
||||
height: ($baseline*3);
|
||||
background: url(../images/large-html-icon.png) center no-repeat;
|
||||
}
|
||||
|
||||
.large-problem-icon {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
height: 60px;
|
||||
margin-right: ($baseline/4);
|
||||
width: ($baseline*3);
|
||||
height: ($baseline*3);
|
||||
background: url(../images/large-problem-icon.png) center no-repeat;
|
||||
}
|
||||
|
||||
.large-video-icon {
|
||||
display: inline-block;
|
||||
width: 100px;
|
||||
height: 60px;
|
||||
margin-right: ($baseline/4);
|
||||
width: ($baseline*3);
|
||||
height: ($baseline*3);
|
||||
background: url(../images/large-video-icon.png) center no-repeat;
|
||||
}
|
||||
|
||||
@@ -130,9 +130,10 @@
|
||||
width: ($baseline*5);
|
||||
height: ($baseline*5);
|
||||
margin-bottom: ($baseline/2);
|
||||
box-shadow: 0 1px 1px $shadow, 0 1px 0 rgba(255, 255, 255, .4) inset;
|
||||
border: 1px solid $green-d2;
|
||||
border-radius: ($baseline/4);
|
||||
box-shadow: 0 1px 1px $shadow, 0 1px 0 rgba(255, 255, 255, .4) inset;
|
||||
padding: 0;
|
||||
background-color: $green-l1;
|
||||
text-align: center;
|
||||
color: $white;
|
||||
@@ -195,16 +196,17 @@
|
||||
}
|
||||
}
|
||||
|
||||
a {
|
||||
.button-component {
|
||||
@include clearfix();
|
||||
@include transition(none);
|
||||
@extend %t-demi-strong;
|
||||
display: block;
|
||||
width: 100%;
|
||||
border: 0px;
|
||||
padding: 7px $baseline;
|
||||
background: $white;
|
||||
color: $gray-d3;
|
||||
|
||||
text-align: left;
|
||||
|
||||
&:hover {
|
||||
@include transition(background-color $tmg-f2 linear 0s);
|
||||
|
||||
@@ -380,6 +380,12 @@
|
||||
color: $gray-l3;
|
||||
}
|
||||
}
|
||||
&.custom-signatory-action {
|
||||
position: relative;
|
||||
top: 0;
|
||||
left: 0;
|
||||
opacity: 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
.copy {
|
||||
@@ -522,6 +528,10 @@
|
||||
|
||||
.signatory-panel-body {
|
||||
padding: $baseline;
|
||||
|
||||
.signatory-image {
|
||||
margin-top: 20px;
|
||||
}
|
||||
}
|
||||
|
||||
.signatory-panel-body label {
|
||||
|
||||
@@ -11,7 +11,7 @@ from django.utils.translation import ugettext as _
|
||||
<%block name="bodyclass">is-signedin course view-certificates</%block>
|
||||
|
||||
<%block name="header_extras">
|
||||
% for template_name in ["certificate-details", "certificate-editor", "signatory-editor", "signatory-details", "basic-modal", "modal-button", "list", "upload-dialog", "certificate-web-preview"]:
|
||||
% for template_name in ["certificate-details", "certificate-editor", "signatory-editor", "signatory-details", "basic-modal", "modal-button", "list", "upload-dialog", "certificate-web-preview", "signatory-actions"]:
|
||||
<script type="text/template" id="${template_name}-tpl">
|
||||
<%static:include path="js/${template_name}.underscore" />
|
||||
</script>
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
<% if (type === 'advanced' || templates.length > 1) { %>
|
||||
<a href="#" class="multiple-templates add-xblock-component-button" data-type="<%= type %>">
|
||||
<button type="button" class="multiple-templates add-xblock-component-button" data-type="<%= type %>">
|
||||
<% } else { %>
|
||||
<a href="#" class="single-template add-xblock-component-button" data-type="<%= type %>" data-category="<%= templates[0].category %>">
|
||||
<button type="button" class="single-template add-xblock-component-button" data-type="<%= type %>" data-category="<%= templates[0].category %>">
|
||||
<% } %>
|
||||
<span class="large-template-icon large-<%= type %>-icon"></span>
|
||||
<span class="sr"> <%= gettext("Add Component:") %></span>
|
||||
<span class="name"><%= display_name %></span>
|
||||
</a>
|
||||
</button>
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
<div class="tab-group tabs">
|
||||
<ul class="problem-type-tabs nav-tabs">
|
||||
<div class="tab-group tabs" tabindex="-1" role="dialog" aria-label="<%-
|
||||
interpolate(
|
||||
gettext('%(type)s Component Template Menu'),
|
||||
{type: type},
|
||||
true
|
||||
)
|
||||
%>">
|
||||
<ul class="problem-type-tabs nav-tabs" tabindex='-1'>
|
||||
<li class="current">
|
||||
<a class="link-tab" href="#tab1"><%= gettext("Common Problem Types") %></a>
|
||||
</li>
|
||||
@@ -13,16 +19,16 @@
|
||||
<% if (templates[i].tab == "common") { %>
|
||||
<% if (!templates[i].boilerplate_name) { %>
|
||||
<li class="editor-md empty">
|
||||
<a href="#" data-category="<%= templates[i].category %>">
|
||||
<button type="button" class="button-component" data-category="<%= templates[i].category %>">
|
||||
<span class="name"><%= templates[i].display_name %></span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<% } else { %>
|
||||
<li class="editor-md">
|
||||
<a href="#" data-category="<%= templates[i].category %>"
|
||||
<button type="button" class="button-component" data-category="<%= templates[i].category %>"
|
||||
data-boilerplate="<%= templates[i].boilerplate_name %>">
|
||||
<span class="name"><%= templates[i].display_name %></span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<% } %>
|
||||
<% } %>
|
||||
@@ -34,14 +40,14 @@
|
||||
<% for (var i = 0; i < templates.length; i++) { %>
|
||||
<% if (templates[i].tab == "advanced") { %>
|
||||
<li class="editor-manual">
|
||||
<a href="#" data-category="<%= templates[i].category %>"
|
||||
<button type="button" class="button-component" data-category="<%= templates[i].category %>"
|
||||
data-boilerplate="<%= templates[i].boilerplate_name %>">
|
||||
<span class="name"><%= templates[i].display_name %></span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</ul>
|
||||
</div>
|
||||
<button class="cancel-button" data-type="<%= type %>"><%= gettext("Cancel") %></button>
|
||||
</div>
|
||||
<a href="#" class="cancel-button"><%= gettext("Cancel") %></a>
|
||||
|
||||
@@ -1,23 +1,29 @@
|
||||
<% if (type === 'advanced' || templates.length > 1) { %>
|
||||
<div class="tab current" id="tab1">
|
||||
<div class="tab current" id="tab1" tabindex="-1" role="dialog" aria-label="<%-
|
||||
interpolate(
|
||||
gettext('%(type)s Component Template Menu'),
|
||||
{type: type},
|
||||
true
|
||||
)
|
||||
%>">
|
||||
<ul class="new-component-template">
|
||||
<% for (var i = 0; i < templates.length; i++) { %>
|
||||
<% if (!templates[i].boilerplate_name) { %>
|
||||
<li class="editor-md empty">
|
||||
<a href="#" data-category="<%= templates[i].category %>">
|
||||
<button type="button" class="button-component" data-category="<%= templates[i].category %>">
|
||||
<span class="name"><%= templates[i].display_name %></span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<% } else { %>
|
||||
<li class="editor-md">
|
||||
<a href="#" data-category="<%= templates[i].category %>"
|
||||
<button type="button" class="button-component" data-category="<%= templates[i].category %>"
|
||||
data-boilerplate="<%= templates[i].boilerplate_name %>">
|
||||
<span class="name"><%= templates[i].display_name %></span>
|
||||
</a>
|
||||
</button>
|
||||
</li>
|
||||
<% } %>
|
||||
<% } %>
|
||||
</ul>
|
||||
<button class="cancel-button" data-type="<%= type %>"><%= gettext("Cancel") %></button>
|
||||
</div>
|
||||
<a href="#" class="cancel-button"><%= gettext("Cancel") %></a>
|
||||
<% } %>
|
||||
|
||||
@@ -17,12 +17,12 @@
|
||||
<span class="title"><%= gettext("Certificate Details") %></span>
|
||||
</header>
|
||||
<div class="actual-course-title">
|
||||
<span class="certificate-label"><%= gettext('Course Title') %>: </span>
|
||||
<span class="certificate-label"><b><%= gettext('Course Title') %>: </b> </span>
|
||||
<span class="certificate-value"><%= course.get('name') %></span>
|
||||
</div>
|
||||
<% if (course_title) { %>
|
||||
<div class="course-title-override">
|
||||
<span class="certificate-label"><%= gettext('Course Title Override') %>: </span>
|
||||
<span class="certificate-label"><b><%= gettext('Course Title Override') %>: </b></span>
|
||||
<span class="certificate-value"><%= course_title %></span>
|
||||
</div>
|
||||
<% } %>
|
||||
|
||||
@@ -19,6 +19,10 @@
|
||||
<textarea id="certificate-description-<%= uniqueId %>" class="certificate-description-input text input-text" name="certificate-description" placeholder="<%= gettext("Description of the certificate") %>" aria-describedby="certificate-description-<%=uniqueId %>-tip"><%= description %></textarea>
|
||||
<span id="certificate-description-<%= uniqueId %>-tip" class="tip tip-stacked"><%= gettext("Description of the certificate") %></span>
|
||||
</div>
|
||||
<div class="field text actual-course-title">
|
||||
<label class="actual-course-title"><b><%= gettext("Course Title") %></b></label>
|
||||
<span class="actual-title"><%= course.get('name') %></span>
|
||||
</div>
|
||||
<div class="input-wrap field text add-certificate-course-title">
|
||||
<label for="certificate-course-title-<%= uniqueId %>"><%= gettext("Course Title Override") %></label>
|
||||
<input id="certificate-course-title-<%= uniqueId %>" class="certificate-course-title-input input-text" name="certificate-course-title" type="text" placeholder="<%= gettext("Course title") %>" value="<%= course_title %>" aria-describedby="certificate-course-title-<%=uniqueId %>-tip" />
|
||||
|
||||
6
cms/templates/js/signatory-actions.underscore
Normal file
6
cms/templates/js/signatory-actions.underscore
Normal file
@@ -0,0 +1,6 @@
|
||||
<div class="collection-edit">
|
||||
<div class="actions custom-signatory-action">
|
||||
<button class="signatory-panel-save action action-primary" type="submit"><%= gettext("Save") %></button>
|
||||
<button class="signatory-panel-close action action-secondary action-cancel"><%= gettext("Cancel") %></button>
|
||||
</div>
|
||||
</div>
|
||||
@@ -9,16 +9,25 @@
|
||||
<div class="signatory-panel-header">Signatory <%= signatory_number %> </div>
|
||||
<div class="signatory-panel-body">
|
||||
<div>
|
||||
<span class="signatory-name-label"><%= gettext("Name") %>: </span>
|
||||
<span class="signatory-name-value"><%= name %></span>
|
||||
<div>
|
||||
<span class="signatory-name-label"><b><%= gettext("Name") %>:</b> </span>
|
||||
<span class="signatory-name-value"><%= name %></span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="signatory-title-label"><b><%= gettext("Title") %>:</b> </span>
|
||||
<span class="signatory-title-value"><%= title %></span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="signatory-organization-label"><b><%= gettext("Organization") %>:</b> </span>
|
||||
<span class="signatory-organization-value"><%= organization %></span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<span class="signatory-title-label"><%= gettext("Title") %>: </span>
|
||||
<span class="signatory-title-value"><%= title %></span>
|
||||
</div>
|
||||
<div>
|
||||
<span class="signatory-organization-label"><%= gettext("Organization") %>: </span>
|
||||
<span class="signatory-organization-value"><%= organization %></span>
|
||||
<div class="signatory-image">
|
||||
<% if (signature_image_path != "") { %>
|
||||
<div class="wrapper-signature-image">
|
||||
<img class="signature-image" src="<%= signature_image_path %>" alt="Signature Image">
|
||||
</div>
|
||||
<% } %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,15 +1,5 @@
|
||||
<div class="signatory-panel-default">
|
||||
|
||||
<% if (!is_editing_all_collections) { %>
|
||||
<a class="signatory-panel-close" href="javascript:void(0);" data-tooltip="Close">
|
||||
<i class="icon fa fa-close" aria-hidden="true"></i>
|
||||
<span class="sr action-button-text"><%= gettext("Close") %></span>
|
||||
</a>
|
||||
<a class="signatory-panel-save" href="javascript:void(0);" data-tooltip="Save">
|
||||
<i class="icon fa fa-save" aria-hidden="true"></i>
|
||||
<span class="sr action-button-text"><%= gettext("Save") %></span>
|
||||
</a>
|
||||
<% } else if (signatories_count > 1 && (total_saved_signatories > 1 || isNew) ) { %>
|
||||
<% if (is_editing_all_collections && signatories_count > 1 && (total_saved_signatories > 1 || isNew) ) { %>
|
||||
<a class="signatory-panel-delete" href="#" data-tooltip="Delete">
|
||||
<i class="icon fa fa-trash-o" aria-hidden="true"></i>
|
||||
<span class="sr action-button-text"><%= gettext("Delete") %></span>
|
||||
|
||||
@@ -189,7 +189,7 @@ def auth_pipeline_urls(auth_entry, redirect_url=None):
|
||||
return {
|
||||
provider.provider_id: third_party_auth.pipeline.get_login_url(
|
||||
provider.provider_id, auth_entry, redirect_url=redirect_url
|
||||
) for provider in third_party_auth.provider.Registry.enabled()
|
||||
) for provider in third_party_auth.provider.Registry.accepting_logins()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1046,9 +1046,10 @@ class CourseEnrollment(models.Model):
|
||||
`course_key` is our usual course_id string (e.g. "edX/Test101/2013_Fall)
|
||||
|
||||
`mode` is a string specifying what kind of enrollment this is. The
|
||||
default is "honor", meaning honor certificate. Future options
|
||||
may include "audit", "verified_id", etc. Please don't use it
|
||||
until we have these mapped out.
|
||||
default is 'honor', meaning honor certificate. Other options
|
||||
include 'professional', 'verified', 'audit',
|
||||
'no-id-professional' and 'credit'.
|
||||
See CourseMode in common/djangoapps/course_modes/models.py.
|
||||
|
||||
`check_access`: if True, we check that an accessible course actually
|
||||
exists for the given course_key before we enroll the student.
|
||||
|
||||
@@ -447,10 +447,11 @@ def register_user(request, extra_context=None):
|
||||
if third_party_auth.is_enabled() and pipeline.running(request):
|
||||
running_pipeline = pipeline.get(request)
|
||||
current_provider = provider.Registry.get_from_pipeline(running_pipeline)
|
||||
overrides = current_provider.get_register_form_data(running_pipeline.get('kwargs'))
|
||||
overrides['running_pipeline'] = running_pipeline
|
||||
overrides['selected_provider'] = current_provider.name
|
||||
context.update(overrides)
|
||||
if current_provider is not None:
|
||||
overrides = current_provider.get_register_form_data(running_pipeline.get('kwargs'))
|
||||
overrides['running_pipeline'] = running_pipeline
|
||||
overrides['selected_provider'] = current_provider.name
|
||||
context.update(overrides)
|
||||
|
||||
return render_to_response('register.html', context)
|
||||
|
||||
@@ -1769,6 +1770,10 @@ def auto_auth(request):
|
||||
full_name = request.GET.get('full_name', username)
|
||||
is_staff = request.GET.get('staff', None)
|
||||
course_id = request.GET.get('course_id', None)
|
||||
|
||||
# mode has to be one of 'honor'/'professional'/'verified'/'audit'/'no-id-professional'/'credit'
|
||||
enrollment_mode = request.GET.get('enrollment_mode', 'honor')
|
||||
|
||||
course_key = None
|
||||
if course_id:
|
||||
course_key = CourseLocator.from_string(course_id)
|
||||
@@ -1816,7 +1821,7 @@ def auto_auth(request):
|
||||
|
||||
# Enroll the user in a course
|
||||
if course_key is not None:
|
||||
CourseEnrollment.enroll(user, course_key)
|
||||
CourseEnrollment.enroll(user, course_key, mode=enrollment_mode)
|
||||
|
||||
# Apply the roles
|
||||
for role_name in role_names:
|
||||
|
||||
@@ -6,7 +6,7 @@ Admin site configuration for third party authentication
|
||||
from django.contrib import admin
|
||||
|
||||
from config_models.admin import ConfigurationModelAdmin, KeyedConfigurationModelAdmin
|
||||
from .models import OAuth2ProviderConfig, SAMLProviderConfig, SAMLConfiguration, SAMLProviderData
|
||||
from .models import OAuth2ProviderConfig, SAMLProviderConfig, SAMLConfiguration, SAMLProviderData, LTIProviderConfig
|
||||
from .tasks import fetch_saml_metadata
|
||||
|
||||
|
||||
@@ -88,3 +88,26 @@ class SAMLProviderDataAdmin(admin.ModelAdmin):
|
||||
return self.readonly_fields
|
||||
|
||||
admin.site.register(SAMLProviderData, SAMLProviderDataAdmin)
|
||||
|
||||
|
||||
class LTIProviderConfigAdmin(KeyedConfigurationModelAdmin):
|
||||
""" Django Admin class for LTIProviderConfig """
|
||||
|
||||
exclude = (
|
||||
'icon_class',
|
||||
'secondary',
|
||||
)
|
||||
|
||||
def get_list_display(self, request):
|
||||
""" Don't show every single field in the admin change list """
|
||||
return (
|
||||
'name',
|
||||
'enabled',
|
||||
'lti_consumer_key',
|
||||
'lti_max_timestamp_age',
|
||||
'change_date',
|
||||
'changed_by',
|
||||
'edit_link',
|
||||
)
|
||||
|
||||
admin.site.register(LTIProviderConfig, LTIProviderConfigAdmin)
|
||||
|
||||
202
common/djangoapps/third_party_auth/lti.py
Normal file
202
common/djangoapps/third_party_auth/lti.py
Normal file
@@ -0,0 +1,202 @@
|
||||
"""
|
||||
Third-party-auth module for Learning Tools Interoperability
|
||||
"""
|
||||
import logging
|
||||
import calendar
|
||||
import time
|
||||
|
||||
from django.contrib.auth import REDIRECT_FIELD_NAME
|
||||
from oauthlib.common import Request
|
||||
from oauthlib.oauth1.rfc5849.signature import (
|
||||
normalize_base_string_uri,
|
||||
normalize_parameters,
|
||||
collect_parameters,
|
||||
construct_base_string,
|
||||
sign_hmac_sha1,
|
||||
)
|
||||
from social.backends.base import BaseAuth
|
||||
from social.exceptions import AuthFailed
|
||||
from social.utils import sanitize_redirect
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
LTI_PARAMS_KEY = 'tpa-lti-params'
|
||||
|
||||
|
||||
class LTIAuthBackend(BaseAuth):
|
||||
"""
|
||||
Third-party-auth module for Learning Tools Interoperability
|
||||
"""
|
||||
|
||||
name = 'lti'
|
||||
|
||||
def start(self):
|
||||
"""
|
||||
Prepare to handle a login request.
|
||||
|
||||
This method replaces social.actions.do_auth and must be kept in sync
|
||||
with any upstream changes in that method. In the current version of
|
||||
the upstream, this means replacing the logic to populate the session
|
||||
from request parameters, and not calling backend.start() to avoid
|
||||
an unwanted redirect to the non-existent login page.
|
||||
"""
|
||||
|
||||
# Clean any partial pipeline data
|
||||
self.strategy.clean_partial_pipeline()
|
||||
|
||||
# Save validated LTI parameters (or None if invalid or not submitted)
|
||||
validated_lti_params = self.get_validated_lti_params(self.strategy)
|
||||
|
||||
# Set a auth_entry here so we don't have to receive that as a custom parameter
|
||||
self.strategy.session_setdefault('auth_entry', 'login')
|
||||
|
||||
if not validated_lti_params:
|
||||
self.strategy.session_set(LTI_PARAMS_KEY, None)
|
||||
raise AuthFailed(self, "LTI parameters could not be validated.")
|
||||
else:
|
||||
self.strategy.session_set(LTI_PARAMS_KEY, validated_lti_params)
|
||||
|
||||
# Save extra data into session.
|
||||
# While Basic LTI 1.0 specifies that the message is to be signed using OAuth, implying
|
||||
# that any GET parameters should be stripped from the base URL and included as signed
|
||||
# parameters, typical LTI Tool Consumer implementations do not support this behaviour. As
|
||||
# a workaround, we accept TPA parameters from LTI custom parameters prefixed with "tpa_".
|
||||
|
||||
for field_name in self.setting('FIELDS_STORED_IN_SESSION', []):
|
||||
if 'custom_tpa_' + field_name in validated_lti_params:
|
||||
self.strategy.session_set(field_name, validated_lti_params['custom_tpa_' + field_name])
|
||||
|
||||
if 'custom_tpa_' + REDIRECT_FIELD_NAME in validated_lti_params:
|
||||
# Check and sanitize a user-defined GET/POST next field value
|
||||
redirect_uri = validated_lti_params['custom_tpa_' + REDIRECT_FIELD_NAME]
|
||||
if self.setting('SANITIZE_REDIRECTS', True):
|
||||
redirect_uri = sanitize_redirect(self.strategy.request_host(), redirect_uri)
|
||||
self.strategy.session_set(REDIRECT_FIELD_NAME, redirect_uri or self.setting('LOGIN_REDIRECT_URL'))
|
||||
|
||||
def auth_html(self):
|
||||
"""
|
||||
Not used
|
||||
"""
|
||||
raise NotImplementedError("Not used")
|
||||
|
||||
def auth_url(self):
|
||||
"""
|
||||
Not used
|
||||
"""
|
||||
raise NotImplementedError("Not used")
|
||||
|
||||
def auth_complete(self, *args, **kwargs):
|
||||
"""
|
||||
Completes third-part-auth authentication
|
||||
"""
|
||||
lti_params = self.strategy.session_get(LTI_PARAMS_KEY)
|
||||
kwargs.update({'response': {LTI_PARAMS_KEY: lti_params}, 'backend': self})
|
||||
return self.strategy.authenticate(*args, **kwargs)
|
||||
|
||||
def get_user_id(self, details, response):
|
||||
"""
|
||||
Computes social auth username from LTI parameters
|
||||
"""
|
||||
lti_params = response[LTI_PARAMS_KEY]
|
||||
return lti_params['oauth_consumer_key'] + ":" + lti_params['user_id']
|
||||
|
||||
def get_user_details(self, response):
|
||||
"""
|
||||
Retrieves user details from LTI parameters
|
||||
"""
|
||||
details = {}
|
||||
lti_params = response[LTI_PARAMS_KEY]
|
||||
|
||||
def add_if_exists(lti_key, details_key):
|
||||
"""
|
||||
Adds LTI parameter to user details dict if it exists
|
||||
"""
|
||||
if lti_key in lti_params and lti_params[lti_key]:
|
||||
details[details_key] = lti_params[lti_key]
|
||||
|
||||
add_if_exists('email', 'email')
|
||||
add_if_exists('lis_person_name_full', 'fullname')
|
||||
add_if_exists('lis_person_name_given', 'first_name')
|
||||
add_if_exists('lis_person_name_family', 'last_name')
|
||||
return details
|
||||
|
||||
@classmethod
|
||||
def get_validated_lti_params(cls, strategy):
|
||||
"""
|
||||
Validates LTI signature and returns LTI parameters
|
||||
"""
|
||||
request = Request(
|
||||
uri=strategy.request.build_absolute_uri(), http_method=strategy.request.method, body=strategy.request.body
|
||||
)
|
||||
lti_consumer_key = request.oauth_consumer_key
|
||||
(lti_consumer_valid, lti_consumer_secret, lti_max_timestamp_age) = cls.load_lti_consumer(lti_consumer_key)
|
||||
current_time = calendar.timegm(time.gmtime())
|
||||
return cls._get_validated_lti_params_from_values(
|
||||
request=request, current_time=current_time,
|
||||
lti_consumer_valid=lti_consumer_valid,
|
||||
lti_consumer_secret=lti_consumer_secret,
|
||||
lti_max_timestamp_age=lti_max_timestamp_age
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def _get_validated_lti_params_from_values(cls, request, current_time,
|
||||
lti_consumer_valid, lti_consumer_secret, lti_max_timestamp_age):
|
||||
"""
|
||||
Validates LTI signature and returns LTI parameters
|
||||
"""
|
||||
|
||||
# Taking a cue from oauthlib, to avoid leaking information through a timing attack,
|
||||
# we proceed through the entire validation before rejecting any request for any reason.
|
||||
# However, as noted there, the value of doing this is dubious.
|
||||
|
||||
base_uri = normalize_base_string_uri(request.uri)
|
||||
parameters = collect_parameters(uri_query=request.uri_query, body=request.body)
|
||||
parameters_string = normalize_parameters(parameters)
|
||||
base_string = construct_base_string(request.http_method, base_uri, parameters_string)
|
||||
|
||||
computed_signature = sign_hmac_sha1(base_string, unicode(lti_consumer_secret), '')
|
||||
submitted_signature = request.oauth_signature
|
||||
|
||||
data = {parameter_value_pair[0]: parameter_value_pair[1] for parameter_value_pair in parameters}
|
||||
|
||||
def safe_int(value):
|
||||
"""
|
||||
Interprets parameter as an int or returns 0 if not possible
|
||||
"""
|
||||
try:
|
||||
return int(value)
|
||||
except (ValueError, TypeError):
|
||||
return 0
|
||||
|
||||
oauth_timestamp = safe_int(request.oauth_timestamp)
|
||||
|
||||
# As this must take constant time, do not use shortcutting operators such as 'and'.
|
||||
# Instead, use constant time operators such as '&', which is the bitwise and.
|
||||
valid = (lti_consumer_valid)
|
||||
valid = valid & (submitted_signature == computed_signature)
|
||||
valid = valid & (request.oauth_version == '1.0')
|
||||
valid = valid & (request.oauth_signature_method == 'HMAC-SHA1')
|
||||
valid = valid & ('user_id' in data) # Not required by LTI but can't log in without one
|
||||
valid = valid & (oauth_timestamp >= current_time - lti_max_timestamp_age)
|
||||
valid = valid & (oauth_timestamp <= current_time)
|
||||
|
||||
if valid:
|
||||
return data
|
||||
else:
|
||||
return None
|
||||
|
||||
@classmethod
|
||||
def load_lti_consumer(cls, lti_consumer_key):
|
||||
"""
|
||||
Retrieves LTI consumer details from database
|
||||
"""
|
||||
from .models import LTIProviderConfig
|
||||
provider_config = LTIProviderConfig.current(lti_consumer_key)
|
||||
if provider_config and provider_config.enabled:
|
||||
return (
|
||||
provider_config.enabled,
|
||||
provider_config.get_lti_consumer_secret(),
|
||||
provider_config.lti_max_timestamp_age,
|
||||
)
|
||||
else:
|
||||
return False, '', -1
|
||||
@@ -0,0 +1,149 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# pylint: disable=C,E,F,R,W
|
||||
from south.utils import datetime_utils as datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding model 'LTIProviderConfig'
|
||||
db.create_table('third_party_auth_ltiproviderconfig', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('change_date', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)),
|
||||
('changed_by', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'], null=True, on_delete=models.PROTECT)),
|
||||
('enabled', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('icon_class', self.gf('django.db.models.fields.CharField')(default='fa-sign-in', max_length=50)),
|
||||
('name', self.gf('django.db.models.fields.CharField')(max_length=50)),
|
||||
('secondary', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('skip_registration_form', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('skip_email_verification', self.gf('django.db.models.fields.BooleanField')(default=False)),
|
||||
('lti_consumer_key', self.gf('django.db.models.fields.CharField')(max_length=255)),
|
||||
('lti_consumer_secret', self.gf('django.db.models.fields.CharField')(max_length=255)),
|
||||
('lti_max_timestamp_age', self.gf('django.db.models.fields.IntegerField')(default=10)),
|
||||
))
|
||||
db.send_create_signal('third_party_auth', ['LTIProviderConfig'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'LTIProviderConfig'
|
||||
db.delete_table('third_party_auth_ltiproviderconfig')
|
||||
|
||||
|
||||
models = {
|
||||
'auth.group': {
|
||||
'Meta': {'object_name': 'Group'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
|
||||
'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
|
||||
},
|
||||
'auth.permission': {
|
||||
'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
|
||||
'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'auth.user': {
|
||||
'Meta': {'object_name': 'User'},
|
||||
'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
|
||||
'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
|
||||
'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
|
||||
'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
|
||||
'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'})
|
||||
},
|
||||
'contenttypes.contenttype': {
|
||||
'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
|
||||
'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'third_party_auth.ltiproviderconfig': {
|
||||
'Meta': {'object_name': 'LTIProviderConfig'},
|
||||
'change_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'changed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.PROTECT'}),
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'icon_class': ('django.db.models.fields.CharField', [], {'default': "'fa-sign-in'", 'max_length': '50'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'lti_consumer_key': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'lti_consumer_secret': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'lti_max_timestamp_age': ('django.db.models.fields.IntegerField', [], {'default': '10'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
|
||||
'secondary': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'skip_email_verification': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'skip_registration_form': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
|
||||
},
|
||||
'third_party_auth.oauth2providerconfig': {
|
||||
'Meta': {'object_name': 'OAuth2ProviderConfig'},
|
||||
'backend_name': ('django.db.models.fields.CharField', [], {'max_length': '50', 'db_index': 'True'}),
|
||||
'change_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'changed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.PROTECT'}),
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'icon_class': ('django.db.models.fields.CharField', [], {'default': "'fa-sign-in'", 'max_length': '50'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'key': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
|
||||
'other_settings': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'secondary': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'secret': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'skip_email_verification': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'skip_registration_form': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
|
||||
},
|
||||
'third_party_auth.samlconfiguration': {
|
||||
'Meta': {'object_name': 'SAMLConfiguration'},
|
||||
'change_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'changed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.PROTECT'}),
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'entity_id': ('django.db.models.fields.CharField', [], {'default': "'http://saml.example.com'", 'max_length': '255'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'org_info_str': ('django.db.models.fields.TextField', [], {'default': '\'{"en-US": {"url": "http://www.example.com", "displayname": "Example Inc.", "name": "example"}}\''}),
|
||||
'other_config_str': ('django.db.models.fields.TextField', [], {'default': '\'{\\n"SECURITY_CONFIG": {"metadataCacheDuration": 604800, "signMetadata": false}\\n}\''}),
|
||||
'private_key': ('django.db.models.fields.TextField', [], {}),
|
||||
'public_key': ('django.db.models.fields.TextField', [], {})
|
||||
},
|
||||
'third_party_auth.samlproviderconfig': {
|
||||
'Meta': {'object_name': 'SAMLProviderConfig'},
|
||||
'attr_email': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
|
||||
'attr_first_name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
|
||||
'attr_full_name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
|
||||
'attr_last_name': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
|
||||
'attr_user_permanent_id': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
|
||||
'attr_username': ('django.db.models.fields.CharField', [], {'max_length': '128', 'blank': 'True'}),
|
||||
'backend_name': ('django.db.models.fields.CharField', [], {'default': "'tpa-saml'", 'max_length': '50'}),
|
||||
'change_date': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
|
||||
'changed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'on_delete': 'models.PROTECT'}),
|
||||
'enabled': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'entity_id': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'icon_class': ('django.db.models.fields.CharField', [], {'default': "'fa-sign-in'", 'max_length': '50'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'idp_slug': ('django.db.models.fields.SlugField', [], {'max_length': '30'}),
|
||||
'metadata_source': ('django.db.models.fields.CharField', [], {'max_length': '255'}),
|
||||
'name': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
|
||||
'other_settings': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
|
||||
'secondary': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'skip_email_verification': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
|
||||
'skip_registration_form': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
|
||||
},
|
||||
'third_party_auth.samlproviderdata': {
|
||||
'Meta': {'ordering': "('-fetched_at',)", 'object_name': 'SAMLProviderData'},
|
||||
'entity_id': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'expires_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'db_index': 'True'}),
|
||||
'fetched_at': ('django.db.models.fields.DateTimeField', [], {'db_index': 'True'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'public_key': ('django.db.models.fields.TextField', [], {}),
|
||||
'sso_url': ('django.db.models.fields.URLField', [], {'max_length': '200'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['third_party_auth']
|
||||
@@ -3,6 +3,8 @@
|
||||
Models used to implement SAML SSO support in third_party_auth
|
||||
(inlcuding Shibboleth support)
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
from config_models.models import ConfigurationModel, cache
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import ValidationError
|
||||
@@ -11,9 +13,11 @@ from django.utils import timezone
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
import json
|
||||
import logging
|
||||
from provider.utils import long_token
|
||||
from social.backends.base import BaseAuth
|
||||
from social.backends.oauth import OAuthAuth
|
||||
from social.backends.saml import SAMLAuth, SAMLIdentityProvider
|
||||
from .lti import LTIAuthBackend, LTI_PARAMS_KEY
|
||||
from social.exceptions import SocialAuthBaseException
|
||||
from social.utils import module_member
|
||||
|
||||
@@ -32,6 +36,7 @@ def _load_backend_classes(base_class=BaseAuth):
|
||||
_PSA_BACKENDS = {backend_class.name: backend_class for backend_class in _load_backend_classes()}
|
||||
_PSA_OAUTH2_BACKENDS = [backend_class.name for backend_class in _load_backend_classes(OAuthAuth)]
|
||||
_PSA_SAML_BACKENDS = [backend_class.name for backend_class in _load_backend_classes(SAMLAuth)]
|
||||
_LTI_BACKENDS = [backend_class.name for backend_class in _load_backend_classes(LTIAuthBackend)]
|
||||
|
||||
|
||||
def clean_json(value, of_type):
|
||||
@@ -95,6 +100,7 @@ class ProviderConfig(ConfigurationModel):
|
||||
)
|
||||
prefix = None # used for provider_id. Set to a string value in subclass
|
||||
backend_name = None # Set to a field or fixed value in subclass
|
||||
accepts_logins = True # Whether to display a sign-in button when the provider is enabled
|
||||
|
||||
# "enabled" field is inherited from ConfigurationModel
|
||||
|
||||
@@ -454,3 +460,70 @@ class SAMLProviderData(models.Model):
|
||||
|
||||
cache.set(cls.cache_key_name(entity_id), current, cls.cache_timeout)
|
||||
return current
|
||||
|
||||
|
||||
class LTIProviderConfig(ProviderConfig):
|
||||
"""
|
||||
Configuration required for this edX instance to act as a LTI
|
||||
Tool Provider and allow users to authenticate and be enrolled in a
|
||||
course via third party LTI Tool Consumers.
|
||||
"""
|
||||
prefix = 'lti'
|
||||
backend_name = 'lti'
|
||||
icon_class = None # This provider is not visible to users
|
||||
secondary = False # This provider is not visible to users
|
||||
accepts_logins = False # LTI login cannot be initiated by the tool provider
|
||||
KEY_FIELDS = ('lti_consumer_key', )
|
||||
|
||||
lti_consumer_key = models.CharField(
|
||||
max_length=255,
|
||||
help_text=(
|
||||
'The name that the LTI Tool Consumer will use to identify itself'
|
||||
)
|
||||
)
|
||||
lti_consumer_secret = models.CharField(
|
||||
default=long_token,
|
||||
max_length=255,
|
||||
help_text=(
|
||||
'The shared secret that the LTI Tool Consumer will use to '
|
||||
'authenticate requests. Only this edX instance and this '
|
||||
'tool consumer instance should know this value. '
|
||||
'For increased security, you can avoid storing this in '
|
||||
'your database by leaving this field blank and setting '
|
||||
'SOCIAL_AUTH_LTI_CONSUMER_SECRETS = {"consumer key": "secret", ...} '
|
||||
'in your instance\'s Django setttigs (or lms.auth.json)'
|
||||
),
|
||||
blank=True,
|
||||
)
|
||||
|
||||
lti_max_timestamp_age = models.IntegerField(
|
||||
default=10,
|
||||
help_text=(
|
||||
'The maximum age of oauth_timestamp values, in seconds.'
|
||||
)
|
||||
)
|
||||
|
||||
def match_social_auth(self, social_auth):
|
||||
""" Is this provider being used for this UserSocialAuth entry? """
|
||||
prefix = self.lti_consumer_key + ":"
|
||||
return self.backend_name == social_auth.provider and social_auth.uid.startswith(prefix)
|
||||
|
||||
def is_active_for_pipeline(self, pipeline):
|
||||
""" Is this provider being used for the specified pipeline? """
|
||||
try:
|
||||
return (
|
||||
self.backend_name == pipeline['backend'] and
|
||||
self.lti_consumer_key == pipeline['kwargs']['response'][LTI_PARAMS_KEY]['oauth_consumer_key']
|
||||
)
|
||||
except KeyError:
|
||||
return False
|
||||
|
||||
def get_lti_consumer_secret(self):
|
||||
""" If the LTI consumer secret is not stored in the database, check Django settings instead """
|
||||
if self.lti_consumer_secret:
|
||||
return self.lti_consumer_secret
|
||||
return getattr(settings, 'SOCIAL_AUTH_LTI_CONSUMER_SECRETS', {}).get(self.lti_consumer_key, '')
|
||||
|
||||
class Meta(object): # pylint: disable=missing-docstring
|
||||
verbose_name = "Provider Configuration (LTI)"
|
||||
verbose_name_plural = verbose_name
|
||||
|
||||
@@ -99,13 +99,6 @@ AUTH_ENTRY_LOGIN = 'login'
|
||||
AUTH_ENTRY_REGISTER = 'register'
|
||||
AUTH_ENTRY_ACCOUNT_SETTINGS = 'account_settings'
|
||||
|
||||
# This is left-over from an A/B test
|
||||
# of the new combined login/registration page (ECOM-369)
|
||||
# We need to keep both the old and new entry points
|
||||
# until every session from before the test ended has expired.
|
||||
AUTH_ENTRY_LOGIN_2 = 'account_login'
|
||||
AUTH_ENTRY_REGISTER_2 = 'account_register'
|
||||
|
||||
# Entry modes into the authentication process by a remote API call (as opposed to a browser session).
|
||||
AUTH_ENTRY_LOGIN_API = 'login_api'
|
||||
AUTH_ENTRY_REGISTER_API = 'register_api'
|
||||
@@ -126,28 +119,12 @@ AUTH_DISPATCH_URLS = {
|
||||
AUTH_ENTRY_LOGIN: '/login',
|
||||
AUTH_ENTRY_REGISTER: '/register',
|
||||
AUTH_ENTRY_ACCOUNT_SETTINGS: '/account/settings',
|
||||
|
||||
# This is left-over from an A/B test
|
||||
# of the new combined login/registration page (ECOM-369)
|
||||
# We need to keep both the old and new entry points
|
||||
# until every session from before the test ended has expired.
|
||||
AUTH_ENTRY_LOGIN_2: '/account/login/',
|
||||
AUTH_ENTRY_REGISTER_2: '/account/register/',
|
||||
|
||||
}
|
||||
|
||||
_AUTH_ENTRY_CHOICES = frozenset([
|
||||
AUTH_ENTRY_LOGIN,
|
||||
AUTH_ENTRY_REGISTER,
|
||||
AUTH_ENTRY_ACCOUNT_SETTINGS,
|
||||
|
||||
# This is left-over from an A/B test
|
||||
# of the new combined login/registration page (ECOM-369)
|
||||
# We need to keep both the old and new entry points
|
||||
# until every session from before the test ended has expired.
|
||||
AUTH_ENTRY_LOGIN_2,
|
||||
AUTH_ENTRY_REGISTER_2,
|
||||
|
||||
AUTH_ENTRY_LOGIN_API,
|
||||
AUTH_ENTRY_REGISTER_API,
|
||||
])
|
||||
@@ -395,9 +372,10 @@ def get_provider_user_states(user):
|
||||
if enabled_provider.match_social_auth(auth):
|
||||
association_id = auth.id
|
||||
break
|
||||
states.append(
|
||||
ProviderUserState(enabled_provider, user, association_id)
|
||||
)
|
||||
if enabled_provider.accepts_logins or association_id:
|
||||
states.append(
|
||||
ProviderUserState(enabled_provider, user, association_id)
|
||||
)
|
||||
|
||||
return states
|
||||
|
||||
@@ -508,13 +486,13 @@ def ensure_user_information(strategy, auth_entry, backend=None, user=None, socia
|
||||
if not user:
|
||||
if auth_entry in [AUTH_ENTRY_LOGIN_API, AUTH_ENTRY_REGISTER_API]:
|
||||
return HttpResponseBadRequest()
|
||||
elif auth_entry in [AUTH_ENTRY_LOGIN, AUTH_ENTRY_LOGIN_2]:
|
||||
elif auth_entry == AUTH_ENTRY_LOGIN:
|
||||
# User has authenticated with the third party provider but we don't know which edX
|
||||
# account corresponds to them yet, if any.
|
||||
if should_force_account_creation():
|
||||
return dispatch_to_register()
|
||||
return dispatch_to_login()
|
||||
elif auth_entry in [AUTH_ENTRY_REGISTER, AUTH_ENTRY_REGISTER_2]:
|
||||
elif auth_entry == AUTH_ENTRY_REGISTER:
|
||||
# User has authenticated with the third party provider and now wants to finish
|
||||
# creating their edX account.
|
||||
return dispatch_to_register()
|
||||
@@ -603,7 +581,7 @@ def login_analytics(strategy, auth_entry, *args, **kwargs):
|
||||
""" Sends login info to Segment.io """
|
||||
|
||||
event_name = None
|
||||
if auth_entry in [AUTH_ENTRY_LOGIN, AUTH_ENTRY_LOGIN_2]:
|
||||
if auth_entry == AUTH_ENTRY_LOGIN:
|
||||
event_name = 'edx.bi.user.account.authenticated'
|
||||
elif auth_entry in [AUTH_ENTRY_ACCOUNT_SETTINGS]:
|
||||
event_name = 'edx.bi.user.account.linked'
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
Third-party auth provider configuration API.
|
||||
"""
|
||||
from .models import (
|
||||
OAuth2ProviderConfig, SAMLConfiguration, SAMLProviderConfig,
|
||||
_PSA_OAUTH2_BACKENDS, _PSA_SAML_BACKENDS
|
||||
OAuth2ProviderConfig, SAMLConfiguration, SAMLProviderConfig, LTIProviderConfig,
|
||||
_PSA_OAUTH2_BACKENDS, _PSA_SAML_BACKENDS, _LTI_BACKENDS,
|
||||
)
|
||||
|
||||
|
||||
@@ -26,12 +26,21 @@ class Registry(object):
|
||||
provider = SAMLProviderConfig.current(idp_slug)
|
||||
if provider.enabled and provider.backend_name in _PSA_SAML_BACKENDS:
|
||||
yield provider
|
||||
for consumer_key in LTIProviderConfig.key_values('lti_consumer_key', flat=True):
|
||||
provider = LTIProviderConfig.current(consumer_key)
|
||||
if provider.enabled and provider.backend_name in _LTI_BACKENDS:
|
||||
yield provider
|
||||
|
||||
@classmethod
|
||||
def enabled(cls):
|
||||
"""Returns list of enabled providers."""
|
||||
return sorted(cls._enabled_providers(), key=lambda provider: provider.name)
|
||||
|
||||
@classmethod
|
||||
def accepting_logins(cls):
|
||||
"""Returns list of providers that can be used to initiate logins currently"""
|
||||
return [provider for provider in cls.enabled() if provider.accepts_logins]
|
||||
|
||||
@classmethod
|
||||
def get(cls, provider_id):
|
||||
"""Gets provider by provider_id string if enabled, else None."""
|
||||
@@ -83,3 +92,8 @@ class Registry(object):
|
||||
provider = SAMLProviderConfig.current(idp_name)
|
||||
if provider.backend_name == backend_name and provider.enabled:
|
||||
yield provider
|
||||
elif backend_name in _LTI_BACKENDS:
|
||||
for consumer_key in LTIProviderConfig.key_values('lti_consumer_key', flat=True):
|
||||
provider = LTIProviderConfig.current(consumer_key)
|
||||
if provider.backend_name == backend_name and provider.enabled:
|
||||
yield provider
|
||||
|
||||
@@ -20,6 +20,8 @@ class ConfigurationModelStrategy(DjangoStrategy):
|
||||
OAuthAuth subclasses will call this method for every setting they want to look up.
|
||||
SAMLAuthBackend subclasses will call this method only after first checking if the
|
||||
setting 'name' is configured via SAMLProviderConfig.
|
||||
LTIAuthBackend subclasses will call this method only after first checking if the
|
||||
setting 'name' is configured via LTIProviderConfig.
|
||||
"""
|
||||
if isinstance(backend, OAuthAuth):
|
||||
provider_config = OAuth2ProviderConfig.current(backend.name)
|
||||
@@ -29,6 +31,6 @@ class ConfigurationModelStrategy(DjangoStrategy):
|
||||
return provider_config.get_setting(name)
|
||||
except KeyError:
|
||||
pass
|
||||
# At this point, we know 'name' is not set in a [OAuth2|SAML]ProviderConfig row.
|
||||
# At this point, we know 'name' is not set in a [OAuth2|LTI|SAML]ProviderConfig row.
|
||||
# It's probably a global Django setting like 'FIELDS_STORED_IN_SESSION':
|
||||
return super(ConfigurationModelStrategy, self).setting(name, default, backend)
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
lti_message_type=basic-lti-launch-request<i_version=LTI-1p0&lis_outcome_service_url=http%3A%2F%2Fwww.imsglobal.org%2Fdevelopers%2FLTI%2Ftest%2Fv1p1%2Fcommon%2Ftool_consumer_outcome.php%3Fb64%3DMTIzNDU6OjpzZWNyZXQ%3D&lis_result_sourcedid=feb-123-456-2929%3A%3A28883&launch_presentation_return_url=http%3A%2F%2Fwww.imsglobal.org%2Fdevelopers%2FLTI%2Ftest%2Fv1p1%2Flms_return.php&user_id=292832126&custom_extra=parameter&oauth_version=1.0&oauth_nonce=c4936a7122f4f85c2d95afe32391573b&oauth_timestamp=1436823553&oauth_consumer_key=12345&oauth_signature_method=HMAC-SHA1&oauth_signature=STPWUouDw%2FlRGD4giWf8lpGTc54%3D&oauth_callback=about%3Ablank
|
||||
@@ -0,0 +1 @@
|
||||
some=garbage&values=provided
|
||||
@@ -0,0 +1 @@
|
||||
lti_message_type=basic-lti-launch-request<i_version=LTI-1p0&lis_outcome_service_url=http%3A%2F%2Fwww.imsglobal.org%2Fdevelopers%2FLTI%2Ftest%2Fv1p1%2Fcommon%2Ftool_consumer_outcome.php%3Fb64%3DMTIzNDU6OjpzZWNyZXQ%3D&lis_result_sourcedid=feb-123-456-2929%3A%3A28883&launch_presentation_return_url=http%3A%2F%2Fwww.imsglobal.org%2Fdevelopers%2FLTI%2Ftest%2Fv1p1%2Flms_return.php&user_id=292832126&custom_extra=parameter&oauth_version=1.0&oauth_nonce=c4936a7122f4f85c2d95afe32391573b&oauth_timestamp=1436823553&oauth_consumer_key=12345&oauth_signature_method=HMAC-SHA1&oauth_signature=STPWUouDw%2FlRGD4giWf8lpXXXXX%3D&oauth_callback=about%3Ablank
|
||||
@@ -0,0 +1 @@
|
||||
lti_message_type=basic-lti-launch-request<i_version=LTI-1p0&lis_outcome_service_url=http%3A%2F%2Fwww.imsglobal.org%2Fdevelopers%2FLTI%2Ftest%2Fv1p1%2Fcommon%2Ftool_consumer_outcome.php%3Fb64%3DMTIzNDU6OjpzZWNyZXQ%3D&lis_result_sourcedid=feb-123-456-2929%3A%3A28883&launch_presentation_return_url=http%3A%2F%2Fwww.imsglobal.org%2Fdevelopers%2FLTI%2Ftest%2Fv1p1%2Flms_return.php&user_id=292832126&custom_extra=parameter&oauth_version=1.0&oauth_nonce=c4936a7122f4f85c2d95afe32391573b&oauth_timestamp=1436823553&oauth_consumer_key=12345&oauth_signature_method=HMAC-SHA1&oauth_signature=STPWUouDw%2FlRGD4giWf8lpGTc54%3D&oauth_callback=about%3Ablank
|
||||
@@ -0,0 +1 @@
|
||||
lti_message_type=basic-lti-launch-request<i_version=LTI-1p0&lis_outcome_service_url=http%3A%2F%2Fwww.imsglobal.org%2Fdevelopers%2FLTI%2Ftest%2Fv1p1%2Fcommon%2Ftool_consumer_outcome.php%3Fb64%3DMTIzNDU6OjpzZWNyZXQ%3D&lis_result_sourcedid=feb-123-456-2929%3A%3A28883&launch_presentation_return_url=http%3A%2F%2Fwww.imsglobal.org%2Fdevelopers%2FLTI%2Ftest%2Fv1p1%2Flms_return.php&user_id=292832126&custom_extra=parameter&oauth_version=1.0&oauth_nonce=c4936a7122f4f85c2d95afe32391573b&oauth_timestamp=1436823553&oauth_consumer_key=12345&oauth_signature_method=HMAC-SHA1&oauth_signature=STPWUouDw%2FlRGD4giWf8lpGTc54%3D&oauth_callback=about%3Ablank
|
||||
@@ -0,0 +1 @@
|
||||
lti_message_type=basic-lti-launch-request&lis_outcome_service_url=http%3A%2F%2Fwww.imsglobal.org%2Fdevelopers%2FLTI%2Ftest%2Fv1p1%2Fcommon%2Ftool_consumer_outcome.php%3Fb64%3DMTIzNDU6OjpzZWNyZXQ%3D&lis_result_sourcedid=feb-123-456-2929%3A%3A28883&launch_presentation_return_url=http%3A%2F%2Fwww.imsglobal.org%2Fdevelopers%2FLTI%2Ftest%2Fv1p1%2Flms_return.php&custom_extra=parameter&oauth_version=1.0&oauth_nonce=c4936a7122f4f85c2d95afe32391573b&oauth_timestamp=1436823553&oauth_consumer_key=12345&oauth_signature_method=HMAC-SHA1&oauth_signature=STPWUouDw%2FlRGD4giWf8lpGTc54%3D&oauth_callback=about%3Ablank
|
||||
@@ -381,12 +381,6 @@ class IntegrationTest(testutil.TestCase, test.TestCase):
|
||||
def test_canceling_authentication_redirects_to_register_when_auth_entry_register(self):
|
||||
self.assert_exception_redirect_looks_correct('/register', auth_entry=pipeline.AUTH_ENTRY_REGISTER)
|
||||
|
||||
def test_canceling_authentication_redirects_to_login_when_auth_login_2(self):
|
||||
self.assert_exception_redirect_looks_correct('/account/login/', auth_entry=pipeline.AUTH_ENTRY_LOGIN_2)
|
||||
|
||||
def test_canceling_authentication_redirects_to_login_when_auth_register_2(self):
|
||||
self.assert_exception_redirect_looks_correct('/account/register/', auth_entry=pipeline.AUTH_ENTRY_REGISTER_2)
|
||||
|
||||
def test_canceling_authentication_redirects_to_account_settings_when_auth_entry_account_settings(self):
|
||||
self.assert_exception_redirect_looks_correct(
|
||||
'/account/settings', auth_entry=pipeline.AUTH_ENTRY_ACCOUNT_SETTINGS
|
||||
|
||||
159
common/djangoapps/third_party_auth/tests/specs/test_lti.py
Normal file
159
common/djangoapps/third_party_auth/tests/specs/test_lti.py
Normal file
@@ -0,0 +1,159 @@
|
||||
"""
|
||||
Integration tests for third_party_auth LTI auth providers
|
||||
"""
|
||||
import unittest
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.urlresolvers import reverse
|
||||
from oauthlib.oauth1.rfc5849 import Client, SIGNATURE_TYPE_BODY
|
||||
from third_party_auth.tests import testutil
|
||||
|
||||
FORM_ENCODED = 'application/x-www-form-urlencoded'
|
||||
|
||||
LTI_CONSUMER_KEY = 'consumer'
|
||||
LTI_CONSUMER_SECRET = 'secret'
|
||||
LTI_TPA_LOGIN_URL = 'http://testserver/auth/login/lti/'
|
||||
LTI_TPA_COMPLETE_URL = 'http://testserver/auth/complete/lti/'
|
||||
OTHER_LTI_CONSUMER_KEY = 'settings-consumer'
|
||||
OTHER_LTI_CONSUMER_SECRET = 'secret2'
|
||||
LTI_USER_ID = 'lti_user_id'
|
||||
EDX_USER_ID = 'test_user'
|
||||
EMAIL = 'lti_user@example.com'
|
||||
|
||||
|
||||
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
|
||||
class IntegrationTestLTI(testutil.TestCase):
|
||||
"""
|
||||
Integration tests for third_party_auth LTI auth providers
|
||||
"""
|
||||
|
||||
def setUp(self):
|
||||
super(IntegrationTestLTI, self).setUp()
|
||||
self.configure_lti_provider(
|
||||
name='Other Tool Consumer 1', enabled=True,
|
||||
lti_consumer_key='other1',
|
||||
lti_consumer_secret='secret1',
|
||||
lti_max_timestamp_age=10,
|
||||
)
|
||||
self.configure_lti_provider(
|
||||
name='LTI Test Tool Consumer', enabled=True,
|
||||
lti_consumer_key=LTI_CONSUMER_KEY,
|
||||
lti_consumer_secret=LTI_CONSUMER_SECRET,
|
||||
lti_max_timestamp_age=10,
|
||||
)
|
||||
self.configure_lti_provider(
|
||||
name='Tool Consumer with Secret in Settings', enabled=True,
|
||||
lti_consumer_key=OTHER_LTI_CONSUMER_KEY,
|
||||
lti_consumer_secret='',
|
||||
lti_max_timestamp_age=10,
|
||||
)
|
||||
self.lti = Client(
|
||||
client_key=LTI_CONSUMER_KEY,
|
||||
client_secret=LTI_CONSUMER_SECRET,
|
||||
signature_type=SIGNATURE_TYPE_BODY,
|
||||
)
|
||||
|
||||
def test_lti_login(self):
|
||||
# The user initiates a login from an external site
|
||||
(uri, _headers, body) = self.lti.sign(
|
||||
uri=LTI_TPA_LOGIN_URL, http_method='POST',
|
||||
headers={'Content-Type': FORM_ENCODED},
|
||||
body={
|
||||
'user_id': LTI_USER_ID,
|
||||
'custom_tpa_next': '/account/finish_auth/?course_id=my_course_id&enrollment_action=enroll',
|
||||
}
|
||||
)
|
||||
login_response = self.client.post(path=uri, content_type=FORM_ENCODED, data=body)
|
||||
# The user should be redirected to the registration form
|
||||
self.assertEqual(login_response.status_code, 302)
|
||||
self.assertTrue(login_response['Location'].endswith(reverse('signin_user')))
|
||||
register_response = self.client.get(login_response['Location'])
|
||||
self.assertEqual(register_response.status_code, 200)
|
||||
self.assertIn('currentProvider": "LTI Test Tool Consumer"', register_response.content)
|
||||
self.assertIn('"errorMessage": null', register_response.content)
|
||||
|
||||
# Now complete the form:
|
||||
ajax_register_response = self.client.post(
|
||||
reverse('user_api_registration'),
|
||||
{
|
||||
'email': EMAIL,
|
||||
'name': 'Myself',
|
||||
'username': EDX_USER_ID,
|
||||
'honor_code': True,
|
||||
}
|
||||
)
|
||||
self.assertEqual(ajax_register_response.status_code, 200)
|
||||
continue_response = self.client.get(LTI_TPA_COMPLETE_URL)
|
||||
# The user should be redirected to the finish_auth view which will enroll them.
|
||||
# FinishAuthView.js reads the URL parameters directly from $.url
|
||||
self.assertEqual(continue_response.status_code, 302)
|
||||
self.assertEqual(
|
||||
continue_response['Location'],
|
||||
'http://testserver/account/finish_auth/?course_id=my_course_id&enrollment_action=enroll'
|
||||
)
|
||||
|
||||
# Now check that we can login again
|
||||
self.client.logout()
|
||||
self.verify_user_email(EMAIL)
|
||||
(uri, _headers, body) = self.lti.sign(
|
||||
uri=LTI_TPA_LOGIN_URL, http_method='POST',
|
||||
headers={'Content-Type': FORM_ENCODED},
|
||||
body={'user_id': LTI_USER_ID}
|
||||
)
|
||||
login_2_response = self.client.post(path=uri, content_type=FORM_ENCODED, data=body)
|
||||
# The user should be redirected to the dashboard
|
||||
self.assertEqual(login_2_response.status_code, 302)
|
||||
self.assertEqual(login_2_response['Location'], LTI_TPA_COMPLETE_URL)
|
||||
continue_2_response = self.client.get(login_2_response['Location'])
|
||||
self.assertEqual(continue_2_response.status_code, 302)
|
||||
self.assertTrue(continue_2_response['Location'].endswith(reverse('dashboard')))
|
||||
|
||||
# Check that the user was created correctly
|
||||
user = User.objects.get(email=EMAIL)
|
||||
self.assertEqual(user.username, EDX_USER_ID)
|
||||
|
||||
def test_reject_initiating_login(self):
|
||||
response = self.client.get(LTI_TPA_LOGIN_URL)
|
||||
self.assertEqual(response.status_code, 405) # Not Allowed
|
||||
|
||||
def test_reject_bad_login(self):
|
||||
login_response = self.client.post(
|
||||
path=LTI_TPA_LOGIN_URL, content_type=FORM_ENCODED,
|
||||
data="invalid=login"
|
||||
)
|
||||
# The user should be redirected to the login page with an error message
|
||||
# (auth_entry defaults to login for this provider)
|
||||
self.assertEqual(login_response.status_code, 302)
|
||||
self.assertTrue(login_response['Location'].endswith(reverse('signin_user')))
|
||||
error_response = self.client.get(login_response['Location'])
|
||||
self.assertIn(
|
||||
'Authentication failed: LTI parameters could not be validated.',
|
||||
error_response.content
|
||||
)
|
||||
|
||||
def test_can_load_consumer_secret_from_settings(self):
|
||||
lti = Client(
|
||||
client_key=OTHER_LTI_CONSUMER_KEY,
|
||||
client_secret=OTHER_LTI_CONSUMER_SECRET,
|
||||
signature_type=SIGNATURE_TYPE_BODY,
|
||||
)
|
||||
(uri, _headers, body) = lti.sign(
|
||||
uri=LTI_TPA_LOGIN_URL, http_method='POST',
|
||||
headers={'Content-Type': FORM_ENCODED},
|
||||
body={
|
||||
'user_id': LTI_USER_ID,
|
||||
'custom_tpa_next': '/account/finish_auth/?course_id=my_course_id&enrollment_action=enroll',
|
||||
}
|
||||
)
|
||||
with self.settings(SOCIAL_AUTH_LTI_CONSUMER_SECRETS={OTHER_LTI_CONSUMER_KEY: OTHER_LTI_CONSUMER_SECRET}):
|
||||
login_response = self.client.post(path=uri, content_type=FORM_ENCODED, data=body)
|
||||
# The user should be redirected to the registration form
|
||||
self.assertEqual(login_response.status_code, 302)
|
||||
self.assertTrue(login_response['Location'].endswith(reverse('signin_user')))
|
||||
register_response = self.client.get(login_response['Location'])
|
||||
self.assertEqual(register_response.status_code, 200)
|
||||
self.assertIn(
|
||||
'currentProvider": "Tool Consumer with Secret in Settings"',
|
||||
register_response.content
|
||||
)
|
||||
self.assertIn('"errorMessage": null', register_response.content)
|
||||
@@ -1,7 +1,6 @@
|
||||
"""
|
||||
Third_party_auth integration tests using a mock version of the TestShib provider
|
||||
"""
|
||||
from django.contrib.auth.models import User
|
||||
from django.core.urlresolvers import reverse
|
||||
import httpretty
|
||||
from mock import patch
|
||||
@@ -38,7 +37,7 @@ class TestShibIntegrationTest(testutil.SAMLTestCase):
|
||||
|
||||
def metadata_callback(_request, _uri, headers):
|
||||
""" Return a cached copy of TestShib's metadata by reading it from disk """
|
||||
return (200, headers, self._read_data_file('testshib_metadata.xml'))
|
||||
return (200, headers, self.read_data_file('testshib_metadata.xml'))
|
||||
httpretty.register_uri(httpretty.GET, TESTSHIB_METADATA_URL, content_type='text/xml', body=metadata_callback)
|
||||
self.addCleanup(httpretty.disable)
|
||||
self.addCleanup(httpretty.reset)
|
||||
@@ -106,7 +105,7 @@ class TestShibIntegrationTest(testutil.SAMLTestCase):
|
||||
|
||||
# Now check that we can login again:
|
||||
self.client.logout()
|
||||
self._verify_user_email('myself@testshib.org')
|
||||
self.verify_user_email('myself@testshib.org')
|
||||
self._test_return_login()
|
||||
|
||||
def test_login(self):
|
||||
@@ -220,11 +219,5 @@ class TestShibIntegrationTest(testutil.SAMLTestCase):
|
||||
return self.client.post(
|
||||
TPA_TESTSHIB_COMPLETE_URL,
|
||||
content_type='application/x-www-form-urlencoded',
|
||||
data=self._read_data_file('testshib_response.txt'),
|
||||
data=self.read_data_file('testshib_response.txt'),
|
||||
)
|
||||
|
||||
def _verify_user_email(self, email):
|
||||
""" Mark the user with the given email as verified """
|
||||
user = User.objects.get(email=email)
|
||||
user.is_active = True
|
||||
user.save()
|
||||
|
||||
133
common/djangoapps/third_party_auth/tests/test_lti.py
Normal file
133
common/djangoapps/third_party_auth/tests/test_lti.py
Normal file
@@ -0,0 +1,133 @@
|
||||
"""
|
||||
Unit tests for third_party_auth LTI auth providers
|
||||
"""
|
||||
|
||||
import unittest
|
||||
from oauthlib.common import Request
|
||||
from third_party_auth.lti import LTIAuthBackend, LTI_PARAMS_KEY
|
||||
from third_party_auth.tests.testutil import ThirdPartyAuthTestMixin
|
||||
|
||||
|
||||
class UnitTestLTI(unittest.TestCase, ThirdPartyAuthTestMixin):
|
||||
"""
|
||||
Unit tests for third_party_auth LTI auth providers
|
||||
"""
|
||||
|
||||
def test_get_user_details_missing_keys(self):
|
||||
lti = LTIAuthBackend()
|
||||
details = lti.get_user_details({LTI_PARAMS_KEY: {
|
||||
'lis_person_name_full': 'Full name'
|
||||
}})
|
||||
self.assertEquals(details, {
|
||||
'fullname': 'Full name'
|
||||
})
|
||||
|
||||
def test_get_user_details_extra_keys(self):
|
||||
lti = LTIAuthBackend()
|
||||
details = lti.get_user_details({LTI_PARAMS_KEY: {
|
||||
'lis_person_name_full': 'Full name',
|
||||
'lis_person_name_given': 'Given',
|
||||
'lis_person_name_family': 'Family',
|
||||
'email': 'user@example.com',
|
||||
'other': 'something else'
|
||||
}})
|
||||
self.assertEquals(details, {
|
||||
'fullname': 'Full name',
|
||||
'first_name': 'Given',
|
||||
'last_name': 'Family',
|
||||
'email': 'user@example.com'
|
||||
})
|
||||
|
||||
def test_get_user_id(self):
|
||||
lti = LTIAuthBackend()
|
||||
user_id = lti.get_user_id(None, {LTI_PARAMS_KEY: {
|
||||
'oauth_consumer_key': 'consumer',
|
||||
'user_id': 'user'
|
||||
}})
|
||||
self.assertEquals(user_id, 'consumer:user')
|
||||
|
||||
def test_validate_lti_valid_request(self):
|
||||
request = Request(
|
||||
uri='https://example.com/lti',
|
||||
http_method='POST',
|
||||
body=self.read_data_file('lti_valid_request.txt')
|
||||
)
|
||||
parameters = LTIAuthBackend._get_validated_lti_params_from_values( # pylint: disable=protected-access
|
||||
request=request, current_time=1436823554,
|
||||
lti_consumer_valid=True, lti_consumer_secret='secret',
|
||||
lti_max_timestamp_age=10
|
||||
)
|
||||
self.assertTrue(parameters)
|
||||
self.assertDictContainsSubset({
|
||||
'custom_extra': 'parameter',
|
||||
'user_id': '292832126'
|
||||
}, parameters)
|
||||
|
||||
def test_validate_lti_valid_request_with_get_params(self):
|
||||
request = Request(
|
||||
uri='https://example.com/lti?user_id=292832126<i_version=LTI-1p0',
|
||||
http_method='POST',
|
||||
body=self.read_data_file('lti_valid_request_with_get_params.txt')
|
||||
)
|
||||
parameters = LTIAuthBackend._get_validated_lti_params_from_values( # pylint: disable=protected-access
|
||||
request=request, current_time=1436823554,
|
||||
lti_consumer_valid=True, lti_consumer_secret='secret',
|
||||
lti_max_timestamp_age=10
|
||||
)
|
||||
self.assertTrue(parameters)
|
||||
self.assertDictContainsSubset({
|
||||
'custom_extra': 'parameter',
|
||||
'user_id': '292832126'
|
||||
}, parameters)
|
||||
|
||||
def test_validate_lti_old_timestamp(self):
|
||||
request = Request(
|
||||
uri='https://example.com/lti',
|
||||
http_method='POST',
|
||||
body=self.read_data_file('lti_old_timestamp.txt')
|
||||
)
|
||||
parameters = LTIAuthBackend._get_validated_lti_params_from_values( # pylint: disable=protected-access
|
||||
request=request, current_time=1436900000,
|
||||
lti_consumer_valid=True, lti_consumer_secret='secret',
|
||||
lti_max_timestamp_age=10
|
||||
)
|
||||
self.assertFalse(parameters)
|
||||
|
||||
def test_validate_lti_invalid_signature(self):
|
||||
request = Request(
|
||||
uri='https://example.com/lti',
|
||||
http_method='POST',
|
||||
body=self.read_data_file('lti_invalid_signature.txt')
|
||||
)
|
||||
parameters = LTIAuthBackend._get_validated_lti_params_from_values( # pylint: disable=protected-access
|
||||
request=request, current_time=1436823554,
|
||||
lti_consumer_valid=True, lti_consumer_secret='secret',
|
||||
lti_max_timestamp_age=10
|
||||
)
|
||||
self.assertFalse(parameters)
|
||||
|
||||
def test_validate_lti_cannot_add_get_params(self):
|
||||
request = Request(
|
||||
uri='https://example.com/lti?custom_another=parameter',
|
||||
http_method='POST',
|
||||
body=self.read_data_file('lti_cannot_add_get_params.txt')
|
||||
)
|
||||
parameters = LTIAuthBackend._get_validated_lti_params_from_values( # pylint: disable=protected-access
|
||||
request=request, current_time=1436823554,
|
||||
lti_consumer_valid=True, lti_consumer_secret='secret',
|
||||
lti_max_timestamp_age=10
|
||||
)
|
||||
self.assertFalse(parameters)
|
||||
|
||||
def test_validate_lti_garbage(self):
|
||||
request = Request(
|
||||
uri='https://example.com/lti',
|
||||
http_method='POST',
|
||||
body=self.read_data_file('lti_garbage.txt')
|
||||
)
|
||||
parameters = LTIAuthBackend._get_validated_lti_params_from_values( # pylint: disable=protected-access
|
||||
request=request, current_time=1436823554,
|
||||
lti_consumer_valid=True, lti_consumer_secret='secret',
|
||||
lti_max_timestamp_age=10
|
||||
)
|
||||
self.assertFalse(parameters)
|
||||
@@ -6,11 +6,18 @@ Used by Django and non-Django tests; must not have Django deps.
|
||||
|
||||
from contextlib import contextmanager
|
||||
from django.conf import settings
|
||||
from django.contrib.auth.models import User
|
||||
import django.test
|
||||
import mock
|
||||
import os.path
|
||||
|
||||
from third_party_auth.models import OAuth2ProviderConfig, SAMLProviderConfig, SAMLConfiguration, cache as config_cache
|
||||
from third_party_auth.models import (
|
||||
OAuth2ProviderConfig,
|
||||
SAMLProviderConfig,
|
||||
SAMLConfiguration,
|
||||
LTIProviderConfig,
|
||||
cache as config_cache,
|
||||
)
|
||||
|
||||
|
||||
AUTH_FEATURES_KEY = 'ENABLE_THIRD_PARTY_AUTH'
|
||||
@@ -52,6 +59,13 @@ class ThirdPartyAuthTestMixin(object):
|
||||
obj.save()
|
||||
return obj
|
||||
|
||||
@staticmethod
|
||||
def configure_lti_provider(**kwargs):
|
||||
""" Update the settings for a LTI Tool Consumer third party auth provider """
|
||||
obj = LTIProviderConfig(**kwargs)
|
||||
obj.save()
|
||||
return obj
|
||||
|
||||
@classmethod
|
||||
def configure_google_provider(cls, **kwargs):
|
||||
""" Update the settings for the Google third party auth provider/backend """
|
||||
@@ -92,6 +106,19 @@ class ThirdPartyAuthTestMixin(object):
|
||||
kwargs.setdefault("secret", "test")
|
||||
return cls.configure_oauth_provider(**kwargs)
|
||||
|
||||
@classmethod
|
||||
def verify_user_email(cls, email):
|
||||
""" Mark the user with the given email as verified """
|
||||
user = User.objects.get(email=email)
|
||||
user.is_active = True
|
||||
user.save()
|
||||
|
||||
@staticmethod
|
||||
def read_data_file(filename):
|
||||
""" Read the contents of a file in the data folder """
|
||||
with open(os.path.join(os.path.dirname(__file__), 'data', filename)) as f:
|
||||
return f.read()
|
||||
|
||||
|
||||
class TestCase(ThirdPartyAuthTestMixin, django.test.TestCase):
|
||||
"""Base class for auth test cases."""
|
||||
@@ -111,18 +138,12 @@ class SAMLTestCase(TestCase):
|
||||
@classmethod
|
||||
def _get_public_key(cls, key_name='saml_key'):
|
||||
""" Get a public key for use in the test. """
|
||||
return cls._read_data_file('{}.pub'.format(key_name))
|
||||
return cls.read_data_file('{}.pub'.format(key_name))
|
||||
|
||||
@classmethod
|
||||
def _get_private_key(cls, key_name='saml_key'):
|
||||
""" Get a private key for use in the test. """
|
||||
return cls._read_data_file('{}.key'.format(key_name))
|
||||
|
||||
@staticmethod
|
||||
def _read_data_file(filename):
|
||||
""" Read the contents of a file in the data folder """
|
||||
with open(os.path.join(os.path.dirname(__file__), 'data', filename)) as f:
|
||||
return f.read()
|
||||
return cls.read_data_file('{}.key'.format(key_name))
|
||||
|
||||
def enable_saml(self, **kwargs):
|
||||
""" Enable SAML support (via SAMLConfiguration, not for any particular provider) """
|
||||
|
||||
@@ -2,11 +2,12 @@
|
||||
|
||||
from django.conf.urls import include, patterns, url
|
||||
|
||||
from .views import inactive_user_view, saml_metadata_view
|
||||
from .views import inactive_user_view, saml_metadata_view, lti_login_and_complete_view
|
||||
|
||||
urlpatterns = patterns(
|
||||
'',
|
||||
url(r'^auth/inactive', inactive_user_view),
|
||||
url(r'^auth/saml/metadata.xml', saml_metadata_view),
|
||||
url(r'^auth/login/(?P<backend>lti)/$', lti_login_and_complete_view),
|
||||
url(r'^auth/', include('social.apps.django_app.urls', namespace='social')),
|
||||
)
|
||||
|
||||
@@ -3,11 +3,17 @@ Extra views required for SSO
|
||||
"""
|
||||
from django.conf import settings
|
||||
from django.core.urlresolvers import reverse
|
||||
from django.http import HttpResponse, HttpResponseServerError, Http404
|
||||
from django.http import HttpResponse, HttpResponseServerError, Http404, HttpResponseNotAllowed
|
||||
from django.shortcuts import redirect
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
import social
|
||||
from social.apps.django_app.views import complete
|
||||
from social.apps.django_app.utils import load_strategy, load_backend
|
||||
from social.utils import setting_name
|
||||
from .models import SAMLConfiguration
|
||||
|
||||
URL_NAMESPACE = getattr(settings, setting_name('URL_NAMESPACE'), None) or 'social'
|
||||
|
||||
|
||||
def inactive_user_view(request):
|
||||
"""
|
||||
@@ -36,3 +42,15 @@ def saml_metadata_view(request):
|
||||
if not errors:
|
||||
return HttpResponse(content=metadata, content_type='text/xml')
|
||||
return HttpResponseServerError(content=', '.join(errors))
|
||||
|
||||
|
||||
@csrf_exempt
|
||||
@social.apps.django_app.utils.psa('{0}:complete'.format(URL_NAMESPACE))
|
||||
def lti_login_and_complete_view(request, backend, *args, **kwargs):
|
||||
"""This is a combination login/complete due to LTI being a one step login"""
|
||||
|
||||
if request.method != 'POST':
|
||||
return HttpResponseNotAllowed('POST')
|
||||
|
||||
request.backend.start()
|
||||
return complete(request, backend, *args, **kwargs)
|
||||
|
||||
@@ -60,6 +60,7 @@ lib_paths:
|
||||
- public/js/split_test_staff.js
|
||||
- common_static/js/src/accessibility_tools.js
|
||||
- common_static/js/vendor/moment.min.js
|
||||
- spec/main_requirejs.js
|
||||
|
||||
# Paths to spec (test) JavaScript files
|
||||
spec_paths:
|
||||
|
||||
11
common/lib/xmodule/xmodule/js/spec/main_requirejs.js
Normal file
11
common/lib/xmodule/xmodule/js/spec/main_requirejs.js
Normal file
@@ -0,0 +1,11 @@
|
||||
(function(requirejs) {
|
||||
requirejs.config({
|
||||
paths: {
|
||||
"moment": "xmodule/include/common_static/js/vendor/moment.min"
|
||||
},
|
||||
"moment": {
|
||||
exports: "moment"
|
||||
}
|
||||
});
|
||||
|
||||
}).call(this, RequireJS.requirejs);
|
||||
@@ -14,10 +14,9 @@
|
||||
|
||||
define(
|
||||
'video/01_initialize.js',
|
||||
['video/03_video_player.js', 'video/00_i18n.js'],
|
||||
function (VideoPlayer, i18n) {
|
||||
var moment = window.moment;
|
||||
|
||||
['video/03_video_player.js', 'video/00_i18n.js', 'moment'],
|
||||
function (VideoPlayer, i18n, moment) {
|
||||
var moment = moment || window.moment;
|
||||
/**
|
||||
* @function
|
||||
*
|
||||
|
||||
@@ -280,21 +280,6 @@ class MixedModuleStore(ModuleStoreDraftAndPublished, ModuleStoreWriteBase):
|
||||
courses[course_id] = course
|
||||
return courses.values()
|
||||
|
||||
@strip_key
|
||||
def get_courses_keys(self, **kwargs):
|
||||
'''
|
||||
Returns a list containing the top level XModuleDescriptors keys of the courses in this modulestore.
|
||||
'''
|
||||
courses = {}
|
||||
for store in self.modulestores:
|
||||
# filter out ones which were fetched from earlier stores but locations may not be ==
|
||||
for course in store.get_courses(**kwargs):
|
||||
course_id = self._clean_locator_for_mapping(course.id)
|
||||
if course_id not in courses:
|
||||
# course is indeed unique. save it in result
|
||||
courses[course_id] = course
|
||||
return courses.keys()
|
||||
|
||||
@strip_key
|
||||
def get_libraries(self, **kwargs):
|
||||
"""
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
isZeroIndexed: false,
|
||||
perPage: 10,
|
||||
|
||||
isStale: false,
|
||||
|
||||
sortField: '',
|
||||
sortDirection: 'descending',
|
||||
sortableFields: {},
|
||||
@@ -37,6 +39,8 @@
|
||||
filterField: '',
|
||||
filterableFields: {},
|
||||
|
||||
searchString: null,
|
||||
|
||||
paginator_core: {
|
||||
type: 'GET',
|
||||
dataType: 'json',
|
||||
@@ -51,9 +55,10 @@
|
||||
},
|
||||
|
||||
server_api: {
|
||||
'page': function () { return this.currentPage; },
|
||||
'page_size': function () { return this.perPage; },
|
||||
'sort_order': function () { return this.sortField; }
|
||||
page: function () { return this.currentPage; },
|
||||
page_size: function () { return this.perPage; },
|
||||
text_search: function () { return this.searchString ? this.searchString : ''; },
|
||||
sort_order: function () { return this.sortField; }
|
||||
},
|
||||
|
||||
parse: function (response) {
|
||||
@@ -61,7 +66,11 @@
|
||||
this.currentPage = response.current_page;
|
||||
this.totalPages = response.num_pages;
|
||||
this.start = response.start;
|
||||
this.sortField = response.sort_order;
|
||||
|
||||
// Note: sort_order is not returned when performing a search
|
||||
if (response.sort_order) {
|
||||
this.sortField = response.sort_order;
|
||||
}
|
||||
return response.results;
|
||||
},
|
||||
|
||||
@@ -84,6 +93,7 @@
|
||||
self = this;
|
||||
return this.goTo(page - (this.isZeroIndexed ? 1 : 0), {reset: true}).then(
|
||||
function () {
|
||||
self.isStale = false;
|
||||
self.trigger('page_changed');
|
||||
},
|
||||
function () {
|
||||
@@ -92,6 +102,24 @@
|
||||
);
|
||||
},
|
||||
|
||||
|
||||
/**
|
||||
* Refreshes the collection if it has been marked as stale.
|
||||
* @returns {promise} Returns a promise representing the refresh.
|
||||
*/
|
||||
refresh: function() {
|
||||
var deferred = $.Deferred();
|
||||
if (this.isStale) {
|
||||
this.setPage(1)
|
||||
.done(function() {
|
||||
deferred.resolve();
|
||||
});
|
||||
} else {
|
||||
deferred.resolve();
|
||||
}
|
||||
return deferred.promise();
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns true if the collection has a next page, false otherwise.
|
||||
*/
|
||||
@@ -183,7 +211,7 @@
|
||||
}
|
||||
}
|
||||
this.sortField = fieldName;
|
||||
this.setPage(1);
|
||||
this.isStale = true;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -193,7 +221,7 @@
|
||||
*/
|
||||
setSortDirection: function (direction) {
|
||||
this.sortDirection = direction;
|
||||
this.setPage(1);
|
||||
this.isStale = true;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -203,7 +231,19 @@
|
||||
*/
|
||||
setFilterField: function (fieldName) {
|
||||
this.filterField = fieldName;
|
||||
this.setPage(1);
|
||||
this.isStale = true;
|
||||
},
|
||||
|
||||
/**
|
||||
* Sets the string to use for a text search. If no string is specified then
|
||||
* the search is cleared.
|
||||
* @param searchString A string to search on, or null if no search is to be applied.
|
||||
*/
|
||||
setSearchString: function(searchString) {
|
||||
if (searchString !== this.searchString) {
|
||||
this.searchString = searchString;
|
||||
this.isStale = true;
|
||||
}
|
||||
}
|
||||
}, {
|
||||
SortDirection: {
|
||||
|
||||
@@ -43,10 +43,16 @@
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates the collection's sort order, and fetches an updated set of
|
||||
* results.
|
||||
* @returns {*} A promise for the collection being updated
|
||||
*/
|
||||
sortCollection: function () {
|
||||
var selected = this.$('#paging-header-select option:selected');
|
||||
this.sortOrder = selected.attr('value');
|
||||
this.collection.setSortField(this.sortOrder);
|
||||
return this.collection.refresh();
|
||||
}
|
||||
});
|
||||
return PagingHeader;
|
||||
|
||||
71
common/static/common/js/components/views/search_field.js
Normal file
71
common/static/common/js/components/views/search_field.js
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* A search field that works in concert with a paginated collection. When the user
|
||||
* performs a search, the collection's search string will be updated and then the
|
||||
* collection will be refreshed to show the first page of results.
|
||||
*/
|
||||
;(function (define) {
|
||||
'use strict';
|
||||
|
||||
define(['backbone', 'jquery', 'underscore', 'text!common/templates/components/search-field.underscore'],
|
||||
function (Backbone, $, _, searchFieldTemplate) {
|
||||
return Backbone.View.extend({
|
||||
|
||||
events: {
|
||||
'submit .search-form': 'performSearch',
|
||||
'blur .search-form': 'onFocusOut',
|
||||
'keyup .search-field': 'refreshState',
|
||||
'click .action-clear': 'clearSearch'
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
this.type = options.type;
|
||||
this.label = options.label;
|
||||
},
|
||||
|
||||
refreshState: function() {
|
||||
var searchField = this.$('.search-field'),
|
||||
clearButton = this.$('.action-clear'),
|
||||
searchString = $.trim(searchField.val());
|
||||
if (searchString) {
|
||||
clearButton.removeClass('is-hidden');
|
||||
} else {
|
||||
clearButton.addClass('is-hidden');
|
||||
}
|
||||
},
|
||||
|
||||
render: function() {
|
||||
this.$el.html(_.template(searchFieldTemplate, {
|
||||
type: this.type,
|
||||
searchString: this.collection.searchString,
|
||||
searchLabel: this.label
|
||||
}));
|
||||
this.refreshState();
|
||||
return this;
|
||||
},
|
||||
|
||||
onFocusOut: function(event) {
|
||||
// If the focus is going anywhere but the clear search
|
||||
// button then treat it as a request to search.
|
||||
if (!$(event.relatedTarget).hasClass('action-clear')) {
|
||||
this.performSearch(event);
|
||||
}
|
||||
},
|
||||
|
||||
performSearch: function(event) {
|
||||
var searchField = this.$('.search-field'),
|
||||
searchString = $.trim(searchField.val());
|
||||
event.preventDefault();
|
||||
this.collection.setSearchString(searchString);
|
||||
return this.collection.refresh();
|
||||
},
|
||||
|
||||
clearSearch: function(event) {
|
||||
event.preventDefault();
|
||||
this.$('.search-field').val('');
|
||||
this.collection.setSearchString('');
|
||||
this.refreshState();
|
||||
return this.collection.refresh();
|
||||
}
|
||||
});
|
||||
});
|
||||
}).call(this, define || RequireJS.define);
|
||||
@@ -10,11 +10,11 @@ define(['jquery',
|
||||
'use strict';
|
||||
|
||||
describe('PagingCollection', function () {
|
||||
var collection, requests, server, assertQueryParams;
|
||||
server = {
|
||||
var collection;
|
||||
var server = {
|
||||
isZeroIndexed: false,
|
||||
count: 43,
|
||||
respond: function () {
|
||||
respond: function (requests) {
|
||||
var params = (new URI(requests[requests.length - 1].url)).query(true),
|
||||
page = parseInt(params['page'], 10),
|
||||
page_size = parseInt(params['page_size'], 10),
|
||||
@@ -35,7 +35,7 @@ define(['jquery',
|
||||
}
|
||||
}
|
||||
};
|
||||
assertQueryParams = function (params) {
|
||||
var assertQueryParams = function (requests, params) {
|
||||
var urlParams = (new URI(requests[requests.length - 1].url)).query(true);
|
||||
_.each(params, function (value, key) {
|
||||
expect(urlParams[key]).toBe(value);
|
||||
@@ -45,7 +45,6 @@ define(['jquery',
|
||||
beforeEach(function () {
|
||||
collection = new PagingCollection();
|
||||
collection.perPage = 10;
|
||||
requests = AjaxHelpers.requests(this);
|
||||
server.isZeroIndexed = false;
|
||||
server.count = 43;
|
||||
});
|
||||
@@ -69,10 +68,11 @@ define(['jquery',
|
||||
});
|
||||
|
||||
it('can set the sort field', function () {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
collection.registerSortableField('test_field', 'Test Field');
|
||||
collection.setSortField('test_field', false);
|
||||
expect(requests.length).toBe(1);
|
||||
assertQueryParams({'sort_order': 'test_field'});
|
||||
collection.refresh();
|
||||
assertQueryParams(requests, {'sort_order': 'test_field'});
|
||||
expect(collection.sortField).toBe('test_field');
|
||||
expect(collection.sortDisplayName()).toBe('Test Field');
|
||||
});
|
||||
@@ -80,7 +80,7 @@ define(['jquery',
|
||||
it('can set the filter field', function () {
|
||||
collection.registerFilterableField('test_field', 'Test Field');
|
||||
collection.setFilterField('test_field');
|
||||
expect(requests.length).toBe(1);
|
||||
collection.refresh();
|
||||
// The default implementation does not send any query params for filtering
|
||||
expect(collection.filterField).toBe('test_field');
|
||||
expect(collection.filterDisplayName()).toBe('Test Field');
|
||||
@@ -88,11 +88,9 @@ define(['jquery',
|
||||
|
||||
it('can set the sort direction', function () {
|
||||
collection.setSortDirection(PagingCollection.SortDirection.ASCENDING);
|
||||
expect(requests.length).toBe(1);
|
||||
// The default implementation does not send any query params for sort direction
|
||||
expect(collection.sortDirection).toBe(PagingCollection.SortDirection.ASCENDING);
|
||||
collection.setSortDirection(PagingCollection.SortDirection.DESCENDING);
|
||||
expect(requests.length).toBe(2);
|
||||
expect(collection.sortDirection).toBe(PagingCollection.SortDirection.DESCENDING);
|
||||
});
|
||||
|
||||
@@ -113,11 +111,12 @@ define(['jquery',
|
||||
'queries with page, page_size, and sort_order parameters when zero indexed': [true, 2],
|
||||
'queries with page, page_size, and sort_order parameters when one indexed': [false, 3],
|
||||
}, function (isZeroIndexed, page) {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
collection.isZeroIndexed = isZeroIndexed;
|
||||
collection.perPage = 5;
|
||||
collection.sortField = 'test_field';
|
||||
collection.setPage(3);
|
||||
assertQueryParams({'page': page.toString(), 'page_size': '5', 'sort_order': 'test_field'});
|
||||
assertQueryParams(requests, {'page': page.toString(), 'page_size': '5', 'sort_order': 'test_field'});
|
||||
});
|
||||
|
||||
SpecHelpers.withConfiguration({
|
||||
@@ -129,27 +128,30 @@ define(['jquery',
|
||||
}, function () {
|
||||
describe('setPage', function() {
|
||||
it('triggers a reset event when the page changes successfully', function () {
|
||||
var resetTriggered = false;
|
||||
var requests = AjaxHelpers.requests(this),
|
||||
resetTriggered = false;
|
||||
collection.on('reset', function () { resetTriggered = true; });
|
||||
collection.setPage(3);
|
||||
server.respond();
|
||||
server.respond(requests);
|
||||
expect(resetTriggered).toBe(true);
|
||||
});
|
||||
|
||||
it('triggers an error event when the requested page is out of range', function () {
|
||||
var errorTriggered = false;
|
||||
var requests = AjaxHelpers.requests(this),
|
||||
errorTriggered = false;
|
||||
collection.on('error', function () { errorTriggered = true; });
|
||||
collection.setPage(17);
|
||||
server.respond();
|
||||
server.respond(requests);
|
||||
expect(errorTriggered).toBe(true);
|
||||
});
|
||||
|
||||
it('triggers an error event if the server responds with a 500', function () {
|
||||
var errorTriggered = false;
|
||||
var requests = AjaxHelpers.requests(this),
|
||||
errorTriggered = false;
|
||||
collection.on('error', function () { errorTriggered = true; });
|
||||
collection.setPage(2);
|
||||
expect(collection.getPage()).toBe(2);
|
||||
server.respond();
|
||||
server.respond(requests);
|
||||
collection.setPage(3);
|
||||
AjaxHelpers.respondWithError(requests, 500, {}, requests.length - 1);
|
||||
expect(errorTriggered).toBe(true);
|
||||
@@ -159,11 +161,12 @@ define(['jquery',
|
||||
|
||||
describe('getPage', function () {
|
||||
it('returns the correct page', function () {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
collection.setPage(1);
|
||||
server.respond();
|
||||
server.respond(requests);
|
||||
expect(collection.getPage()).toBe(1);
|
||||
collection.setPage(3);
|
||||
server.respond();
|
||||
server.respond(requests);
|
||||
expect(collection.getPage()).toBe(3);
|
||||
});
|
||||
});
|
||||
@@ -177,9 +180,10 @@ define(['jquery',
|
||||
'returns false on the last page': [5, 43, false]
|
||||
},
|
||||
function (page, count, result) {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
server.count = count;
|
||||
collection.setPage(page);
|
||||
server.respond();
|
||||
server.respond(requests);
|
||||
expect(collection.hasNextPage()).toBe(result);
|
||||
}
|
||||
);
|
||||
@@ -194,9 +198,10 @@ define(['jquery',
|
||||
'returns false on the first page': [1, 43, false]
|
||||
},
|
||||
function (page, count, result) {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
server.count = count;
|
||||
collection.setPage(page);
|
||||
server.respond();
|
||||
server.respond(requests);
|
||||
expect(collection.hasPreviousPage()).toBe(result);
|
||||
}
|
||||
);
|
||||
@@ -209,13 +214,14 @@ define(['jquery',
|
||||
'silently fails on the last page': [5, 43, 5]
|
||||
},
|
||||
function (page, count, newPage) {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
server.count = count;
|
||||
collection.setPage(page);
|
||||
server.respond();
|
||||
server.respond(requests);
|
||||
expect(collection.getPage()).toBe(page);
|
||||
collection.nextPage();
|
||||
if (requests.length > 1) {
|
||||
server.respond();
|
||||
server.respond(requests);
|
||||
}
|
||||
expect(collection.getPage()).toBe(newPage);
|
||||
}
|
||||
@@ -229,13 +235,14 @@ define(['jquery',
|
||||
'silently fails on the first page': [1, 43, 1]
|
||||
},
|
||||
function (page, count, newPage) {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
server.count = count;
|
||||
collection.setPage(page);
|
||||
server.respond();
|
||||
server.respond(requests);
|
||||
expect(collection.getPage()).toBe(page);
|
||||
collection.previousPage();
|
||||
if (requests.length > 1) {
|
||||
server.respond();
|
||||
server.respond(requests);
|
||||
}
|
||||
expect(collection.getPage()).toBe(newPage);
|
||||
}
|
||||
|
||||
105
common/static/common/js/spec/components/search_field_spec.js
Normal file
105
common/static/common/js/spec/components/search_field_spec.js
Normal file
@@ -0,0 +1,105 @@
|
||||
define([
|
||||
'underscore',
|
||||
'common/js/components/views/search_field',
|
||||
'common/js/components/collections/paging_collection',
|
||||
'common/js/spec_helpers/ajax_helpers'
|
||||
], function (_, SearchFieldView, PagingCollection, AjaxHelpers) {
|
||||
'use strict';
|
||||
describe('SearchFieldView', function () {
|
||||
var searchFieldView,
|
||||
mockUrl = '/api/mock_collection';
|
||||
|
||||
var newCollection = function (size, perPage) {
|
||||
var pageSize = 5,
|
||||
results = _.map(_.range(size), function (i) { return {foo: i}; });
|
||||
var collection = new PagingCollection(
|
||||
[],
|
||||
{
|
||||
url: mockUrl,
|
||||
count: results.length,
|
||||
num_pages: results.length / pageSize,
|
||||
current_page: 1,
|
||||
start: 0,
|
||||
results: _.first(results, perPage)
|
||||
},
|
||||
{parse: true}
|
||||
);
|
||||
collection.start = 0;
|
||||
collection.totalCount = results.length;
|
||||
return collection;
|
||||
};
|
||||
|
||||
var createSearchFieldView = function (options) {
|
||||
options = _.extend(
|
||||
{
|
||||
type: 'test',
|
||||
collection: newCollection(5, 4),
|
||||
el: $('.test-search')
|
||||
},
|
||||
options || {}
|
||||
);
|
||||
return new SearchFieldView(options);
|
||||
};
|
||||
|
||||
beforeEach(function() {
|
||||
setFixtures('<section class="test-search"></section>');
|
||||
});
|
||||
|
||||
it('correctly displays itself', function () {
|
||||
searchFieldView = createSearchFieldView().render();
|
||||
expect(searchFieldView.$('.search-field').val(), '');
|
||||
expect(searchFieldView.$('.action-clear')).toHaveClass('is-hidden');
|
||||
});
|
||||
|
||||
it('can display with an initial search string', function () {
|
||||
searchFieldView = createSearchFieldView({
|
||||
searchString: 'foo'
|
||||
}).render();
|
||||
expect(searchFieldView.$('.search-field').val(), 'foo');
|
||||
});
|
||||
|
||||
it('refreshes the collection when performing a search', function () {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
searchFieldView = createSearchFieldView().render();
|
||||
searchFieldView.$('.search-field').val('foo');
|
||||
searchFieldView.$('.action-search').click();
|
||||
AjaxHelpers.expectRequestURL(requests, mockUrl, {
|
||||
page: '1',
|
||||
page_size: '10',
|
||||
sort_order: '',
|
||||
text_search: 'foo'
|
||||
});
|
||||
AjaxHelpers.respondWithJson(requests, {
|
||||
count: 10,
|
||||
current_page: 1,
|
||||
num_pages: 1,
|
||||
start: 0,
|
||||
results: []
|
||||
});
|
||||
expect(searchFieldView.$('.search-field').val(), 'foo');
|
||||
});
|
||||
|
||||
it('can clear the search', function () {
|
||||
var requests = AjaxHelpers.requests(this);
|
||||
searchFieldView = createSearchFieldView({
|
||||
searchString: 'foo'
|
||||
}).render();
|
||||
searchFieldView.$('.action-clear').click();
|
||||
AjaxHelpers.expectRequestURL(requests, mockUrl, {
|
||||
page: '1',
|
||||
page_size: '10',
|
||||
sort_order: '',
|
||||
text_search: ''
|
||||
});
|
||||
AjaxHelpers.respondWithJson(requests, {
|
||||
count: 10,
|
||||
current_page: 1,
|
||||
num_pages: 1,
|
||||
start: 0,
|
||||
results: []
|
||||
});
|
||||
expect(searchFieldView.$('.search-field').val(), '');
|
||||
expect(searchFieldView.$('.action-clear')).toHaveClass('is-hidden');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,7 +1,7 @@
|
||||
define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) {
|
||||
'use strict';
|
||||
|
||||
var fakeServer, fakeRequests, expectRequest, expectJsonRequest, expectPostRequest, expectJsonRequestURL,
|
||||
var fakeServer, fakeRequests, expectRequest, expectJsonRequest, expectPostRequest, expectRequestURL,
|
||||
respondWithJson, respondWithError, respondWithTextError, respondWithNoContent;
|
||||
|
||||
/* These utility methods are used by Jasmine tests to create a mock server or
|
||||
@@ -77,7 +77,7 @@ define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) {
|
||||
* @param expectedParameters An object representing the URL parameters
|
||||
* @param requestIndex An optional index for the request (by default, the last request is used)
|
||||
*/
|
||||
expectJsonRequestURL = function(requests, expectedUrl, expectedParameters, requestIndex) {
|
||||
expectRequestURL = function(requests, expectedUrl, expectedParameters, requestIndex) {
|
||||
var request, parameters;
|
||||
if (_.isUndefined(requestIndex)) {
|
||||
requestIndex = requests.length - 1;
|
||||
@@ -153,15 +153,15 @@ define(['sinon', 'underscore', 'URI'], function(sinon, _, URI) {
|
||||
};
|
||||
|
||||
return {
|
||||
'server': fakeServer,
|
||||
'requests': fakeRequests,
|
||||
'expectRequest': expectRequest,
|
||||
'expectJsonRequest': expectJsonRequest,
|
||||
'expectJsonRequestURL': expectJsonRequestURL,
|
||||
'expectPostRequest': expectPostRequest,
|
||||
'respondWithJson': respondWithJson,
|
||||
'respondWithError': respondWithError,
|
||||
'respondWithTextError': respondWithTextError,
|
||||
'respondWithNoContent': respondWithNoContent,
|
||||
server: fakeServer,
|
||||
requests: fakeRequests,
|
||||
expectRequest: expectRequest,
|
||||
expectJsonRequest: expectJsonRequest,
|
||||
expectPostRequest: expectPostRequest,
|
||||
expectRequestURL: expectRequestURL,
|
||||
respondWithJson: respondWithJson,
|
||||
respondWithError: respondWithError,
|
||||
respondWithTextError: respondWithTextError,
|
||||
respondWithNoContent: respondWithNoContent
|
||||
};
|
||||
});
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
<div class="page-header-search wrapper-search-<%= type %>">
|
||||
<form class="search-form">
|
||||
<div class="wrapper-search-input">
|
||||
<label for="search-<%= type %>" class="search-label">><%- searchLabel %></label>
|
||||
<input id="search-<%= type %>" class="search-field" type="text" value="<%- searchString %>" placeholder="<%- searchLabel %>" />
|
||||
<button type="button" class="action action-clear <%= searchLabel ? '' : 'is-hidden' %>" aria-label="<%- gettext('Clear search') %>">
|
||||
<i class="icon fa fa-times-circle" aria-hidden="true"></i><span class="sr"><%- gettext('Search') %></span>
|
||||
</button>
|
||||
</div>
|
||||
<button type="submit" class="action action-search"><span class="icon fa-search" aria-hidden="true"></span><span class="sr"><%- gettext('Search') %></span></button>
|
||||
</form>
|
||||
</div>
|
||||
@@ -15,8 +15,8 @@
|
||||
<% } %>
|
||||
|
||||
<div class="copy">
|
||||
<h2 class="title title-3" id="<%= type %>-<%= intent %>-title"><%= title %></h2>
|
||||
<% if(obj.message) { %><p class="message" id="<%= type %>-<%= intent %>-description"><%= message %></p><% } %>
|
||||
<h2 class="title title-3" id="<%= type %>-<%= intent %>-title"><%- title %></h2>
|
||||
<% if(obj.message) { %><p class="message" id="<%= type %>-<%= intent %>-description"><%- message %></p><% } %>
|
||||
</div>
|
||||
|
||||
<% if(obj.actions) { %>
|
||||
@@ -24,13 +24,13 @@
|
||||
<ul>
|
||||
<% if(actions.primary) { %>
|
||||
<li class="nav-item">
|
||||
<button class="action-primary <%= actions.primary.class %>"><%= actions.primary.text %></button>
|
||||
<button class="action-primary <%= actions.primary.class %>"><%- actions.primary.text %></button>
|
||||
</li>
|
||||
<% } %>
|
||||
<% if(actions.secondary) {
|
||||
_.each(actions.secondary, function(secondary) { %>
|
||||
<li class="nav-item">
|
||||
<button class="action-secondary <%= secondary.class %>"><%= secondary.text %></button>
|
||||
<button class="action-secondary <%= secondary.class %>"><%- secondary.text %></button>
|
||||
</li>
|
||||
<% });
|
||||
} %>
|
||||
|
||||
@@ -289,7 +289,7 @@ define(['js/capa/drag_and_drop/draggable_events', 'js/capa/drag_and_drop/draggab
|
||||
|
||||
draggableObj.iconEl.appendTo(draggableObj.containerEl);
|
||||
|
||||
draggableObj.iconWidth = draggableObj.iconEl.width();
|
||||
draggableObj.iconWidth = draggableObj.iconEl.width() + 1;
|
||||
draggableObj.iconHeight = draggableObj.iconEl.height();
|
||||
draggableObj.iconWidthSmall = draggableObj.iconWidth;
|
||||
draggableObj.iconHeightSmall = draggableObj.iconHeight;
|
||||
|
||||
@@ -155,13 +155,14 @@
|
||||
|
||||
define([
|
||||
// Run the common tests that use RequireJS.
|
||||
'common-requirejs/include/common/js/spec/components/feedback_spec.js',
|
||||
'common-requirejs/include/common/js/spec/components/list_spec.js',
|
||||
'common-requirejs/include/common/js/spec/components/paginated_view_spec.js',
|
||||
'common-requirejs/include/common/js/spec/components/paging_collection_spec.js',
|
||||
'common-requirejs/include/common/js/spec/components/paging_header_spec.js',
|
||||
'common-requirejs/include/common/js/spec/components/paging_footer_spec.js',
|
||||
'common-requirejs/include/common/js/spec/components/view_utils_spec.js',
|
||||
'common-requirejs/include/common/js/spec/components/feedback_spec.js'
|
||||
'common-requirejs/include/common/js/spec/components/search_field_spec.js',
|
||||
'common-requirejs/include/common/js/spec/components/view_utils_spec.js'
|
||||
]);
|
||||
|
||||
}).call(this, requirejs, define);
|
||||
|
||||
@@ -17,7 +17,8 @@ class AutoAuthPage(PageObject):
|
||||
|
||||
CONTENT_REGEX = r'.+? user (?P<username>\S+) \((?P<email>.+?)\) with password \S+ and user_id (?P<user_id>\d+)$'
|
||||
|
||||
def __init__(self, browser, username=None, email=None, password=None, staff=None, course_id=None, roles=None):
|
||||
def __init__(self, browser, username=None, email=None, password=None, staff=None, course_id=None,
|
||||
enrollment_mode=None, roles=None):
|
||||
"""
|
||||
Auto-auth is an end-point for HTTP GET requests.
|
||||
By default, it will create accounts with random user credentials,
|
||||
@@ -52,6 +53,8 @@ class AutoAuthPage(PageObject):
|
||||
|
||||
if course_id is not None:
|
||||
self._params['course_id'] = course_id
|
||||
if enrollment_mode:
|
||||
self._params['enrollment_mode'] = enrollment_mode
|
||||
|
||||
if roles is not None:
|
||||
self._params['roles'] = roles
|
||||
|
||||
@@ -127,7 +127,7 @@ class CombinedLoginAndRegisterPage(PageObject):
|
||||
@property
|
||||
def url(self):
|
||||
"""Return the URL for the combined login/registration page. """
|
||||
url = "{base}/account/{login_or_register}".format(
|
||||
url = "{base}/{login_or_register}".format(
|
||||
base=BASE_URL,
|
||||
login_or_register=self._start_page
|
||||
)
|
||||
|
||||
@@ -20,6 +20,25 @@ TEAMS_HEADER_CSS = '.teams-header'
|
||||
CREATE_TEAM_LINK_CSS = '.create-team'
|
||||
|
||||
|
||||
class TeamCardsMixin(object):
|
||||
"""Provides common operations on the team card component."""
|
||||
|
||||
@property
|
||||
def team_cards(self):
|
||||
"""Get all the team cards on the page."""
|
||||
return self.q(css='.team-card')
|
||||
|
||||
@property
|
||||
def team_names(self):
|
||||
"""Return the names of each team on the page."""
|
||||
return self.q(css='h3.card-title').map(lambda e: e.text).results
|
||||
|
||||
@property
|
||||
def team_descriptions(self):
|
||||
"""Return the names of each team on the page."""
|
||||
return self.q(css='p.card-description').map(lambda e: e.text).results
|
||||
|
||||
|
||||
class TeamsPage(CoursePage):
|
||||
"""
|
||||
Teams page/tab.
|
||||
@@ -84,7 +103,7 @@ class TeamsPage(CoursePage):
|
||||
self.q(css='a.nav-item').filter(text=topic)[0].click()
|
||||
|
||||
|
||||
class MyTeamsPage(CoursePage, PaginatedUIMixin):
|
||||
class MyTeamsPage(CoursePage, PaginatedUIMixin, TeamCardsMixin):
|
||||
"""
|
||||
The 'My Teams' tab of the Teams page.
|
||||
"""
|
||||
@@ -98,11 +117,6 @@ class MyTeamsPage(CoursePage, PaginatedUIMixin):
|
||||
return False
|
||||
return 'is-active' in button_classes[0]
|
||||
|
||||
@property
|
||||
def team_cards(self):
|
||||
"""Get all the team cards on the page."""
|
||||
return self.q(css='.team-card')
|
||||
|
||||
|
||||
class BrowseTopicsPage(CoursePage, PaginatedUIMixin):
|
||||
"""
|
||||
@@ -128,6 +142,11 @@ class BrowseTopicsPage(CoursePage, PaginatedUIMixin):
|
||||
"""Return a list of the topic names present on the page."""
|
||||
return self.q(css=CARD_TITLE_CSS).map(lambda e: e.text).results
|
||||
|
||||
@property
|
||||
def topic_descriptions(self):
|
||||
"""Return a list of the topic descriptions present on the page."""
|
||||
return self.q(css='p.card-description').map(lambda e: e.text).results
|
||||
|
||||
def browse_teams_for_topic(self, topic_name):
|
||||
"""
|
||||
Show the teams list for `topic_name`.
|
||||
@@ -145,43 +164,43 @@ class BrowseTopicsPage(CoursePage, PaginatedUIMixin):
|
||||
self.wait_for_ajax()
|
||||
|
||||
|
||||
class BrowseTeamsPage(CoursePage, PaginatedUIMixin):
|
||||
class BaseTeamsPage(CoursePage, PaginatedUIMixin, TeamCardsMixin):
|
||||
"""
|
||||
The paginated UI for browsing teams within a Topic on the Teams
|
||||
page.
|
||||
"""
|
||||
def __init__(self, browser, course_id, topic):
|
||||
"""
|
||||
Set up `self.url_path` on instantiation, since it dynamically
|
||||
reflects the current topic. Note that `topic` is a dict
|
||||
representation of a topic following the same convention as a
|
||||
course module's topic.
|
||||
Note that `topic` is a dict representation of a topic following
|
||||
the same convention as a course module's topic.
|
||||
"""
|
||||
super(BrowseTeamsPage, self).__init__(browser, course_id)
|
||||
super(BaseTeamsPage, self).__init__(browser, course_id)
|
||||
self.topic = topic
|
||||
self.url_path = "teams/#topics/{topic_id}".format(topic_id=self.topic['id'])
|
||||
|
||||
def is_browser_on_page(self):
|
||||
"""Check if we're on the teams list page for a particular topic."""
|
||||
self.wait_for_element_presence('.team-actions', 'Wait for the bottom links to be present')
|
||||
"""Check if we're on a teams list page for a particular topic."""
|
||||
has_correct_url = self.url.endswith(self.url_path)
|
||||
teams_list_view_present = self.q(css='.teams-main').present
|
||||
return has_correct_url and teams_list_view_present
|
||||
|
||||
@property
|
||||
def header_topic_name(self):
|
||||
def header_name(self):
|
||||
"""Get the topic name displayed by the page header"""
|
||||
return self.q(css=TEAMS_HEADER_CSS + ' .page-title')[0].text
|
||||
|
||||
@property
|
||||
def header_topic_description(self):
|
||||
def header_description(self):
|
||||
"""Get the topic description displayed by the page header"""
|
||||
return self.q(css=TEAMS_HEADER_CSS + ' .page-description')[0].text
|
||||
|
||||
@property
|
||||
def team_cards(self):
|
||||
"""Get all the team cards on the page."""
|
||||
return self.q(css='.team-card')
|
||||
def sort_order(self):
|
||||
"""Return the current sort order on the page."""
|
||||
return self.q(
|
||||
css='#paging-header-select option'
|
||||
).filter(
|
||||
lambda e: e.is_selected()
|
||||
).results[0].text.strip()
|
||||
|
||||
def click_create_team_link(self):
|
||||
""" Click on create team link."""
|
||||
@@ -204,6 +223,55 @@ class BrowseTeamsPage(CoursePage, PaginatedUIMixin):
|
||||
query.first.click()
|
||||
self.wait_for_ajax()
|
||||
|
||||
def sort_teams_by(self, sort_order):
|
||||
"""Sort the list of teams by the given `sort_order`."""
|
||||
self.q(
|
||||
css='#paging-header-select option[value={sort_order}]'.format(sort_order=sort_order)
|
||||
).click()
|
||||
self.wait_for_ajax()
|
||||
|
||||
@property
|
||||
def _showing_search_results(self):
|
||||
"""
|
||||
Returns true if showing search results.
|
||||
"""
|
||||
return self.header_description.startswith(u"Showing results for")
|
||||
|
||||
def search(self, string):
|
||||
"""
|
||||
Searches for the specified string, and returns a SearchTeamsPage
|
||||
representing the search results page.
|
||||
"""
|
||||
self.q(css='.search-field').first.fill(string)
|
||||
self.q(css='.action-search').first.click()
|
||||
self.wait_for(
|
||||
lambda: self._showing_search_results,
|
||||
description="Showing search results"
|
||||
)
|
||||
page = SearchTeamsPage(self.browser, self.course_id, self.topic)
|
||||
page.wait_for_page()
|
||||
return page
|
||||
|
||||
|
||||
class BrowseTeamsPage(BaseTeamsPage):
|
||||
"""
|
||||
The paginated UI for browsing teams within a Topic on the Teams
|
||||
page.
|
||||
"""
|
||||
def __init__(self, browser, course_id, topic):
|
||||
super(BrowseTeamsPage, self).__init__(browser, course_id, topic)
|
||||
self.url_path = "teams/#topics/{topic_id}".format(topic_id=self.topic['id'])
|
||||
|
||||
|
||||
class SearchTeamsPage(BaseTeamsPage):
|
||||
"""
|
||||
The paginated UI for showing team search results.
|
||||
page.
|
||||
"""
|
||||
def __init__(self, browser, course_id, topic):
|
||||
super(SearchTeamsPage, self).__init__(browser, course_id, topic)
|
||||
self.url_path = "teams/#topics/{topic_id}/search".format(topic_id=self.topic['id'])
|
||||
|
||||
|
||||
class CreateOrEditTeamPage(CoursePage, FieldsMixin):
|
||||
"""
|
||||
|
||||
@@ -305,7 +305,7 @@ class ContainerPage(PageObject):
|
||||
Returns:
|
||||
list
|
||||
"""
|
||||
css = '#tab{tab_index} a[data-category={category_type}] span'.format(
|
||||
css = '#tab{tab_index} button[data-category={category_type}] span'.format(
|
||||
tab_index=tab_index,
|
||||
category_type=category_type
|
||||
)
|
||||
|
||||
@@ -27,6 +27,12 @@ class CertificatesPage(CoursePage):
|
||||
# Helpers
|
||||
################
|
||||
|
||||
def refresh(self):
|
||||
"""
|
||||
Refresh the certificate page
|
||||
"""
|
||||
self.browser.refresh()
|
||||
|
||||
def is_browser_on_page(self):
|
||||
"""
|
||||
Verify that the browser is on the page and it is not still loading.
|
||||
@@ -434,11 +440,8 @@ class Signatory(object):
|
||||
"""
|
||||
Save signatory.
|
||||
"""
|
||||
# Move focus from input to save button and then click it
|
||||
self.certificate.page.browser.execute_script(
|
||||
"$('{} .signatory-panel-save').focus()".format(self.get_selector())
|
||||
)
|
||||
self.find_css('.signatory-panel-save').first.click()
|
||||
# Click on the save button.
|
||||
self.certificate.page.q(css='button.signatory-panel-save').click()
|
||||
self.mode = 'details'
|
||||
self.certificate.page.wait_for_ajax()
|
||||
self.wait_for_signatory_detail_view()
|
||||
@@ -447,7 +450,7 @@ class Signatory(object):
|
||||
"""
|
||||
Cancel signatory editing.
|
||||
"""
|
||||
self.find_css('.signatory-panel-close').first.click()
|
||||
self.certificate.page.q(css='button.signatory-panel-close').click()
|
||||
self.mode = 'details'
|
||||
self.wait_for_signatory_detail_view()
|
||||
|
||||
|
||||
@@ -33,9 +33,9 @@ class UsersPageMixin(PageObject):
|
||||
|
||||
def is_browser_on_page(self):
|
||||
"""
|
||||
Returns True iff the browser has loaded the page.
|
||||
Returns True if the browser has loaded the page.
|
||||
"""
|
||||
return self.q(css='body.view-team').present
|
||||
return self.q(css='body.view-team').present and not self.q(css='.ui-loading').present
|
||||
|
||||
@property
|
||||
def users(self):
|
||||
|
||||
@@ -72,7 +72,7 @@ def add_discussion(page, menu_index=0):
|
||||
placement within the page).
|
||||
"""
|
||||
page.wait_for_component_menu()
|
||||
click_css(page, 'a>span.large-discussion-icon', menu_index)
|
||||
click_css(page, 'button>span.large-discussion-icon', menu_index)
|
||||
|
||||
|
||||
def add_advanced_component(page, menu_index, name):
|
||||
@@ -84,7 +84,7 @@ def add_advanced_component(page, menu_index, name):
|
||||
"""
|
||||
# Click on the Advanced icon.
|
||||
page.wait_for_component_menu()
|
||||
click_css(page, 'a>span.large-advanced-icon', menu_index, require_notification=False)
|
||||
click_css(page, 'button>span.large-advanced-icon', menu_index, require_notification=False)
|
||||
|
||||
# This does an animation to hide the first level of buttons
|
||||
# and instead show the Advanced buttons that are available.
|
||||
@@ -95,7 +95,7 @@ def add_advanced_component(page, menu_index, name):
|
||||
page.wait_for_element_visibility('.new-component-advanced', 'Advanced component menu is visible')
|
||||
|
||||
# Now click on the component to add it.
|
||||
component_css = 'a[data-category={}]'.format(name)
|
||||
component_css = 'button[data-category={}]'.format(name)
|
||||
page.wait_for_element_visibility(component_css, 'Advanced component {} is visible'.format(name))
|
||||
|
||||
# Adding some components, e.g. the Discussion component, will make an ajax call
|
||||
@@ -123,7 +123,7 @@ def add_component(page, item_type, specific_type):
|
||||
'Wait for the add component menu to disappear'
|
||||
)
|
||||
|
||||
all_options = page.q(css='.new-component-{} ul.new-component-template li a span'.format(item_type))
|
||||
all_options = page.q(css='.new-component-{} ul.new-component-template li button span'.format(item_type))
|
||||
chosen_option = all_options.filter(lambda el: el.text == specific_type).first
|
||||
chosen_option.click()
|
||||
wait_for_notification(page)
|
||||
@@ -139,13 +139,13 @@ def add_html_component(page, menu_index, boilerplate=None):
|
||||
"""
|
||||
# Click on the HTML icon.
|
||||
page.wait_for_component_menu()
|
||||
click_css(page, 'a>span.large-html-icon', menu_index, require_notification=False)
|
||||
click_css(page, 'button>span.large-html-icon', menu_index, require_notification=False)
|
||||
|
||||
# Make sure that the menu of HTML components is visible before clicking
|
||||
page.wait_for_element_visibility('.new-component-html', 'HTML component menu is visible')
|
||||
|
||||
# Now click on the component to add it.
|
||||
component_css = 'a[data-category=html]'
|
||||
component_css = 'button[data-category=html]'
|
||||
if boilerplate:
|
||||
component_css += '[data-boilerplate={}]'.format(boilerplate)
|
||||
else:
|
||||
|
||||
@@ -30,7 +30,7 @@ CLASS_SELECTORS = {
|
||||
}
|
||||
|
||||
BUTTON_SELECTORS = {
|
||||
'create_video': 'a[data-category="video"]',
|
||||
'create_video': 'button[data-category="video"]',
|
||||
'handout_download': '.video-handout.video-download-button a',
|
||||
'handout_download_editor': '.wrapper-comp-setting.file-uploader .download-action',
|
||||
'upload_asset': '.upload-action',
|
||||
|
||||
@@ -109,7 +109,7 @@ class LoginFromCombinedPageTest(UniqueCourseTest):
|
||||
self.login_page.visit().toggle_form()
|
||||
self.assertEqual(self.login_page.current_form, "register")
|
||||
|
||||
@flaky # TODO fix this, see ECOM-1165
|
||||
@flaky # ECOM-1165
|
||||
def test_password_reset_success(self):
|
||||
# Create a user account
|
||||
email, password = self._create_unique_user() # pylint: disable=unused-variable
|
||||
|
||||
@@ -168,32 +168,12 @@ class ProctoredExamsTest(BaseInstructorDashboardTest):
|
||||
# Auto-auth register for the course.
|
||||
self._auto_auth(self.USERNAME, self.EMAIL, False)
|
||||
|
||||
def _auto_auth(self, username, email, staff):
|
||||
def _auto_auth(self, username, email, staff, enrollment_mode="honor"):
|
||||
"""
|
||||
Logout and login with given credentials.
|
||||
"""
|
||||
AutoAuthPage(self.browser, username=username, email=email,
|
||||
course_id=self.course_id, staff=staff).visit()
|
||||
|
||||
def _login_as_a_verified_user(self):
|
||||
"""
|
||||
login as a verififed user
|
||||
"""
|
||||
|
||||
self._auto_auth(self.USERNAME, self.EMAIL, False)
|
||||
|
||||
# the track selection page cannot be visited. see the other tests to see if any prereq is there.
|
||||
# Navigate to the track selection page
|
||||
self.track_selection_page.visit()
|
||||
|
||||
# Enter the payment and verification flow by choosing to enroll as verified
|
||||
self.track_selection_page.enroll('verified')
|
||||
|
||||
# Proceed to the fake payment page
|
||||
self.payment_and_verification_flow.proceed_to_payment()
|
||||
|
||||
# Submit payment
|
||||
self.fake_payment_page.submit_payment()
|
||||
course_id=self.course_id, staff=staff, enrollment_mode=enrollment_mode).visit()
|
||||
|
||||
def _create_a_proctored_exam_and_attempt(self):
|
||||
"""
|
||||
@@ -212,7 +192,7 @@ class ProctoredExamsTest(BaseInstructorDashboardTest):
|
||||
|
||||
# login as a verified student and visit the courseware.
|
||||
LogoutPage(self.browser).visit()
|
||||
self._login_as_a_verified_user()
|
||||
self._auto_auth(self.USERNAME, self.EMAIL, False, enrollment_mode="verified")
|
||||
self.courseware_page.visit()
|
||||
|
||||
# Start the proctored exam.
|
||||
@@ -235,7 +215,7 @@ class ProctoredExamsTest(BaseInstructorDashboardTest):
|
||||
|
||||
# login as a verified student and visit the courseware.
|
||||
LogoutPage(self.browser).visit()
|
||||
self._login_as_a_verified_user()
|
||||
self._auto_auth(self.USERNAME, self.EMAIL, False, enrollment_mode="verified")
|
||||
self.courseware_page.visit()
|
||||
|
||||
# Start the proctored exam.
|
||||
|
||||
@@ -5,6 +5,7 @@ Bok choy acceptance tests for problems in the LMS
|
||||
See also old lettuce tests in lms/djangoapps/courseware/features/problems.feature
|
||||
"""
|
||||
from textwrap import dedent
|
||||
from flaky import flaky
|
||||
|
||||
from ..helpers import UniqueCourseTest
|
||||
from ...pages.studio.auto_auth import AutoAuthPage
|
||||
@@ -191,6 +192,7 @@ class ProblemHintWithHtmlTest(ProblemsTest, EventsTestMixin):
|
||||
""")
|
||||
return XBlockFixtureDesc('problem', 'PROBLEM HTML HINT TEST', data=xml)
|
||||
|
||||
@flaky # TODO fix this, see TNL-3183
|
||||
def test_check_hint(self):
|
||||
"""
|
||||
Test clicking Check shows the extended hint in the problem message.
|
||||
|
||||
@@ -3,13 +3,16 @@ Acceptance tests for the teams feature.
|
||||
"""
|
||||
import json
|
||||
import random
|
||||
import time
|
||||
|
||||
from dateutil.parser import parse
|
||||
import ddt
|
||||
from flaky import flaky
|
||||
from nose.plugins.attrib import attr
|
||||
from uuid import uuid4
|
||||
from unittest import skip
|
||||
|
||||
from ..helpers import UniqueCourseTest
|
||||
from ..helpers import UniqueCourseTest, EventsTestMixin
|
||||
from ...fixtures import LMS_BASE_URL
|
||||
from ...fixtures.course import CourseFixture
|
||||
from ...fixtures.discussion import (
|
||||
@@ -26,7 +29,7 @@ from ...pages.lms.teams import TeamsPage, MyTeamsPage, BrowseTopicsPage, BrowseT
|
||||
TOPICS_PER_PAGE = 12
|
||||
|
||||
|
||||
class TeamsTabBase(UniqueCourseTest):
|
||||
class TeamsTabBase(EventsTestMixin, UniqueCourseTest):
|
||||
"""Base class for Teams Tab tests"""
|
||||
def setUp(self):
|
||||
super(TeamsTabBase, self).setUp()
|
||||
@@ -38,7 +41,7 @@ class TeamsTabBase(UniqueCourseTest):
|
||||
"""Create `num_topics` test topics."""
|
||||
return [{u"description": i, u"name": i, u"id": i} for i in map(str, xrange(num_topics))]
|
||||
|
||||
def create_teams(self, topic, num_teams):
|
||||
def create_teams(self, topic, num_teams, time_between_creation=0):
|
||||
"""Create `num_teams` teams belonging to `topic`."""
|
||||
teams = []
|
||||
for i in xrange(num_teams):
|
||||
@@ -55,6 +58,10 @@ class TeamsTabBase(UniqueCourseTest):
|
||||
data=json.dumps(team),
|
||||
headers=self.course_fixture.headers
|
||||
)
|
||||
# Sadly, this sleep is necessary in order to ensure that
|
||||
# sorting by last_activity_at works correctly when running
|
||||
# in Jenkins.
|
||||
time.sleep(time_between_creation)
|
||||
teams.append(json.loads(response.text))
|
||||
return teams
|
||||
|
||||
@@ -107,15 +114,8 @@ class TeamsTabBase(UniqueCourseTest):
|
||||
self.assertEqual(expected_team['name'], team_card_name)
|
||||
self.assertEqual(expected_team['description'], team_card_description)
|
||||
|
||||
team_cards = page.team_cards
|
||||
team_card_names = [
|
||||
team_card.find_element_by_css_selector('.card-title').text
|
||||
for team_card in team_cards.results
|
||||
]
|
||||
team_card_descriptions = [
|
||||
team_card.find_element_by_css_selector('.card-description').text
|
||||
for team_card in team_cards.results
|
||||
]
|
||||
team_card_names = page.team_names
|
||||
team_card_descriptions = page.team_descriptions
|
||||
map(assert_team_equal, expected_teams, team_card_names, team_card_descriptions)
|
||||
|
||||
def verify_my_team_count(self, expected_number_of_teams):
|
||||
@@ -124,6 +124,10 @@ class TeamsTabBase(UniqueCourseTest):
|
||||
# We are doing these operations on this top-level page object to avoid reloading the page.
|
||||
self.teams_page.verify_my_team_count(expected_number_of_teams)
|
||||
|
||||
def only_team_events(self, event):
|
||||
"""Filter out all non-team events."""
|
||||
return event['event_type'].startswith('edx.team.')
|
||||
|
||||
|
||||
@ddt.ddt
|
||||
@attr('shard_5')
|
||||
@@ -445,7 +449,7 @@ class BrowseTopicsTest(TeamsTabBase):
|
||||
{u"max_team_size": 1, u"topics": [{"name": "", "id": "", "description": initial_description}]}
|
||||
)
|
||||
self.topics_page.visit()
|
||||
truncated_description = self.topics_page.topic_cards[0].text
|
||||
truncated_description = self.topics_page.topic_descriptions[0]
|
||||
self.assertLess(len(truncated_description), len(initial_description))
|
||||
self.assertTrue(truncated_description.endswith('...'))
|
||||
self.assertIn(truncated_description.split('...')[0], initial_description)
|
||||
@@ -468,11 +472,12 @@ class BrowseTopicsTest(TeamsTabBase):
|
||||
self.topics_page.browse_teams_for_topic('Example Topic')
|
||||
browse_teams_page = BrowseTeamsPage(self.browser, self.course_id, topic)
|
||||
self.assertTrue(browse_teams_page.is_browser_on_page())
|
||||
self.assertEqual(browse_teams_page.header_topic_name, 'Example Topic')
|
||||
self.assertEqual(browse_teams_page.header_topic_description, 'Description')
|
||||
self.assertEqual(browse_teams_page.header_name, 'Example Topic')
|
||||
self.assertEqual(browse_teams_page.header_description, 'Description')
|
||||
|
||||
|
||||
@attr('shard_5')
|
||||
@ddt.ddt
|
||||
class BrowseTeamsWithinTopicTest(TeamsTabBase):
|
||||
"""
|
||||
Tests for browsing Teams within a Topic on the Teams page.
|
||||
@@ -482,21 +487,45 @@ class BrowseTeamsWithinTopicTest(TeamsTabBase):
|
||||
def setUp(self):
|
||||
super(BrowseTeamsWithinTopicTest, self).setUp()
|
||||
self.topic = {u"name": u"Example Topic", u"id": "example_topic", u"description": "Description"}
|
||||
self.set_team_configuration({'course_id': self.course_id, 'max_team_size': 10, 'topics': [self.topic]})
|
||||
self.max_team_size = 10
|
||||
self.set_team_configuration({
|
||||
'course_id': self.course_id,
|
||||
'max_team_size': self.max_team_size,
|
||||
'topics': [self.topic]
|
||||
})
|
||||
self.browse_teams_page = BrowseTeamsPage(self.browser, self.course_id, self.topic)
|
||||
self.topics_page = BrowseTopicsPage(self.browser, self.course_id)
|
||||
|
||||
def teams_with_default_sort_order(self, teams):
|
||||
"""Return a list of teams sorted according to the default ordering
|
||||
(last_activity_at, with a secondary sort by open slots).
|
||||
"""
|
||||
return sorted(
|
||||
sorted(teams, key=lambda t: len(t['membership']), reverse=True),
|
||||
key=lambda t: parse(t['last_activity_at']).replace(microsecond=0),
|
||||
reverse=True
|
||||
)
|
||||
|
||||
def verify_page_header(self):
|
||||
"""Verify that the page header correctly reflects the current topic's name and description."""
|
||||
self.assertEqual(self.browse_teams_page.header_topic_name, self.topic['name'])
|
||||
self.assertEqual(self.browse_teams_page.header_topic_description, self.topic['description'])
|
||||
self.assertEqual(self.browse_teams_page.header_name, self.topic['name'])
|
||||
self.assertEqual(self.browse_teams_page.header_description, self.topic['description'])
|
||||
|
||||
def verify_on_page(self, page_num, total_teams, pagination_header_text, footer_visible):
|
||||
def verify_search_header(self, search_results_page, search_query):
|
||||
"""Verify that the page header correctly reflects the current topic's name and description."""
|
||||
self.assertEqual(search_results_page.header_name, 'Team Search')
|
||||
self.assertEqual(
|
||||
search_results_page.header_description,
|
||||
'Showing results for "{search_query}"'.format(search_query=search_query)
|
||||
)
|
||||
|
||||
def verify_on_page(self, teams_page, page_num, total_teams, pagination_header_text, footer_visible):
|
||||
"""
|
||||
Verify that we are on the correct team list page.
|
||||
|
||||
Arguments:
|
||||
page_num (int): The one-indexed page we expect to be on
|
||||
teams_page (BaseTeamsPage): The teams page object that should be the current page.
|
||||
page_num (int): The one-indexed page number that we expect to be on
|
||||
total_teams (list): An unsorted list of all the teams for the
|
||||
current topic
|
||||
pagination_header_text (str): Text we expect to see in the
|
||||
@@ -504,18 +533,75 @@ class BrowseTeamsWithinTopicTest(TeamsTabBase):
|
||||
footer_visible (bool): Whether we expect to see the pagination
|
||||
footer controls.
|
||||
"""
|
||||
alphabetized_teams = sorted(total_teams, key=lambda team: team['name'])
|
||||
self.assertEqual(self.browse_teams_page.get_pagination_header_text(), pagination_header_text)
|
||||
sorted_teams = self.teams_with_default_sort_order(total_teams)
|
||||
self.assertTrue(teams_page.get_pagination_header_text().startswith(pagination_header_text))
|
||||
self.verify_teams(
|
||||
self.browse_teams_page,
|
||||
alphabetized_teams[(page_num - 1) * self.TEAMS_PAGE_SIZE:page_num * self.TEAMS_PAGE_SIZE]
|
||||
teams_page,
|
||||
sorted_teams[(page_num - 1) * self.TEAMS_PAGE_SIZE:page_num * self.TEAMS_PAGE_SIZE]
|
||||
)
|
||||
self.assertEqual(
|
||||
self.browse_teams_page.pagination_controls_visible(),
|
||||
teams_page.pagination_controls_visible(),
|
||||
footer_visible,
|
||||
msg='Expected paging footer to be ' + 'visible' if footer_visible else 'invisible'
|
||||
)
|
||||
|
||||
@ddt.data(
|
||||
('open_slots', 'last_activity_at', True),
|
||||
('last_activity_at', 'open_slots', True)
|
||||
)
|
||||
@ddt.unpack
|
||||
def test_sort_teams(self, sort_order, secondary_sort_order, reverse):
|
||||
"""
|
||||
Scenario: the user should be able to sort the list of teams by open slots or last activity
|
||||
Given I am enrolled in a course with team configuration and topics
|
||||
When I visit the Teams page
|
||||
And I browse teams within a topic
|
||||
Then I should see a list of teams for that topic
|
||||
When I choose a sort order
|
||||
Then I should see the paginated list of teams in that order
|
||||
"""
|
||||
teams = self.create_teams(self.topic, self.TEAMS_PAGE_SIZE + 1)
|
||||
for i, team in enumerate(random.sample(teams, len(teams))):
|
||||
for _ in range(i):
|
||||
user_info = AutoAuthPage(self.browser, course_id=self.course_id).visit().user_info
|
||||
self.create_membership(user_info['username'], team['id'])
|
||||
team['open_slots'] = self.max_team_size - i
|
||||
# Parse last activity date, removing microseconds because
|
||||
# the Django ORM does not support them. Will be fixed in
|
||||
# Django 1.8.
|
||||
team['last_activity_at'] = parse(team['last_activity_at']).replace(microsecond=0)
|
||||
# Re-authenticate as staff after creating users
|
||||
AutoAuthPage(
|
||||
self.browser,
|
||||
course_id=self.course_id,
|
||||
staff=True
|
||||
).visit()
|
||||
self.browse_teams_page.visit()
|
||||
self.browse_teams_page.sort_teams_by(sort_order)
|
||||
team_names = self.browse_teams_page.team_names
|
||||
self.assertEqual(len(team_names), self.TEAMS_PAGE_SIZE)
|
||||
sorted_teams = [
|
||||
team['name']
|
||||
for team in sorted(
|
||||
sorted(teams, key=lambda t: t[secondary_sort_order], reverse=reverse),
|
||||
key=lambda t: t[sort_order],
|
||||
reverse=reverse
|
||||
)
|
||||
][:self.TEAMS_PAGE_SIZE]
|
||||
self.assertEqual(team_names, sorted_teams)
|
||||
|
||||
def test_default_sort_order(self):
|
||||
"""
|
||||
Scenario: the list of teams should be sorted by last activity by default
|
||||
Given I am enrolled in a course with team configuration and topics
|
||||
When I visit the Teams page
|
||||
And I browse teams within a topic
|
||||
Then I should see a list of teams for that topic, sorted by last activity
|
||||
"""
|
||||
self.create_teams(self.topic, self.TEAMS_PAGE_SIZE + 1)
|
||||
self.browse_teams_page.visit()
|
||||
self.assertEqual(self.browse_teams_page.sort_order, 'last activity')
|
||||
|
||||
def test_no_teams(self):
|
||||
"""
|
||||
Scenario: Visiting a topic with no teams should not display any teams.
|
||||
@@ -529,7 +615,7 @@ class BrowseTeamsWithinTopicTest(TeamsTabBase):
|
||||
"""
|
||||
self.browse_teams_page.visit()
|
||||
self.verify_page_header()
|
||||
self.assertEqual(self.browse_teams_page.get_pagination_header_text(), 'Showing 0 out of 0 total')
|
||||
self.assertTrue(self.browse_teams_page.get_pagination_header_text().startswith('Showing 0 out of 0 total'))
|
||||
self.assertEqual(len(self.browse_teams_page.team_cards), 0, msg='Expected to see no team cards')
|
||||
self.assertFalse(
|
||||
self.browse_teams_page.pagination_controls_visible(),
|
||||
@@ -548,10 +634,12 @@ class BrowseTeamsWithinTopicTest(TeamsTabBase):
|
||||
And I should see a button to add a team
|
||||
And I should not see a pagination footer
|
||||
"""
|
||||
teams = self.create_teams(self.topic, self.TEAMS_PAGE_SIZE)
|
||||
teams = self.teams_with_default_sort_order(
|
||||
self.create_teams(self.topic, self.TEAMS_PAGE_SIZE, time_between_creation=1)
|
||||
)
|
||||
self.browse_teams_page.visit()
|
||||
self.verify_page_header()
|
||||
self.assertEqual(self.browse_teams_page.get_pagination_header_text(), 'Showing 1-10 out of 10 total')
|
||||
self.assertTrue(self.browse_teams_page.get_pagination_header_text().startswith('Showing 1-10 out of 10 total'))
|
||||
self.verify_teams(self.browse_teams_page, teams)
|
||||
self.assertFalse(
|
||||
self.browse_teams_page.pagination_controls_visible(),
|
||||
@@ -571,14 +659,14 @@ class BrowseTeamsWithinTopicTest(TeamsTabBase):
|
||||
And when I click on the previous page button
|
||||
Then I should see that I am on the first page of results
|
||||
"""
|
||||
teams = self.create_teams(self.topic, self.TEAMS_PAGE_SIZE + 1)
|
||||
teams = self.create_teams(self.topic, self.TEAMS_PAGE_SIZE + 1, time_between_creation=1)
|
||||
self.browse_teams_page.visit()
|
||||
self.verify_page_header()
|
||||
self.verify_on_page(1, teams, 'Showing 1-10 out of 11 total', True)
|
||||
self.verify_on_page(self.browse_teams_page, 1, teams, 'Showing 1-10 out of 11 total', True)
|
||||
self.browse_teams_page.press_next_page_button()
|
||||
self.verify_on_page(2, teams, 'Showing 11-11 out of 11 total', True)
|
||||
self.verify_on_page(self.browse_teams_page, 2, teams, 'Showing 11-11 out of 11 total', True)
|
||||
self.browse_teams_page.press_previous_page_button()
|
||||
self.verify_on_page(1, teams, 'Showing 1-10 out of 11 total', True)
|
||||
self.verify_on_page(self.browse_teams_page, 1, teams, 'Showing 1-10 out of 11 total', True)
|
||||
|
||||
def test_teams_page_input(self):
|
||||
"""
|
||||
@@ -593,28 +681,24 @@ class BrowseTeamsWithinTopicTest(TeamsTabBase):
|
||||
When I input the first page
|
||||
Then I should see that I am on the first page of results
|
||||
"""
|
||||
teams = self.create_teams(self.topic, self.TEAMS_PAGE_SIZE + 10)
|
||||
teams = self.create_teams(self.topic, self.TEAMS_PAGE_SIZE + 10, time_between_creation=1)
|
||||
self.browse_teams_page.visit()
|
||||
self.verify_page_header()
|
||||
self.verify_on_page(1, teams, 'Showing 1-10 out of 20 total', True)
|
||||
self.verify_on_page(self.browse_teams_page, 1, teams, 'Showing 1-10 out of 20 total', True)
|
||||
self.browse_teams_page.go_to_page(2)
|
||||
self.verify_on_page(2, teams, 'Showing 11-20 out of 20 total', True)
|
||||
self.verify_on_page(self.browse_teams_page, 2, teams, 'Showing 11-20 out of 20 total', True)
|
||||
self.browse_teams_page.go_to_page(1)
|
||||
self.verify_on_page(1, teams, 'Showing 1-10 out of 20 total', True)
|
||||
self.verify_on_page(self.browse_teams_page, 1, teams, 'Showing 1-10 out of 20 total', True)
|
||||
|
||||
def test_navigation_links(self):
|
||||
def test_browse_team_topics(self):
|
||||
"""
|
||||
Scenario: User should be able to navigate to "browse all teams" and "search team description" links.
|
||||
Given I am enrolled in a course with a team configuration and a topic
|
||||
containing one team
|
||||
When I visit the Teams page for that topic
|
||||
Given I am enrolled in a course with teams enabled
|
||||
When I visit the Teams page for a topic
|
||||
Then I should see the correct page header
|
||||
And I should see the link to "browse all team"
|
||||
And I should navigate to that link
|
||||
And I see the relevant page loaded
|
||||
And I should see the link to "search teams"
|
||||
And I should navigate to that link
|
||||
And I see the relevant page loaded
|
||||
And I should see the link to "browse teams in other topics"
|
||||
When I should navigate to that link
|
||||
Then I should see the topic browse page
|
||||
"""
|
||||
self.browse_teams_page.visit()
|
||||
self.verify_page_header()
|
||||
@@ -622,10 +706,24 @@ class BrowseTeamsWithinTopicTest(TeamsTabBase):
|
||||
self.browse_teams_page.click_browse_all_teams_link()
|
||||
self.assertTrue(self.topics_page.is_browser_on_page())
|
||||
|
||||
@skip('Disabled until search connectivity issues are resolved, see TNL-3206')
|
||||
def test_search(self):
|
||||
"""
|
||||
Scenario: User should be able to search for a team
|
||||
Given I am enrolled in a course with teams enabled
|
||||
When I visit the Teams page for that topic
|
||||
And I search for 'banana'
|
||||
Then I should see the search result page
|
||||
And the search header should be shown
|
||||
And 0 results should be shown
|
||||
"""
|
||||
# Note: all searches will return 0 results with the mock search server
|
||||
# used by Bok Choy.
|
||||
self.create_teams(self.topic, 5)
|
||||
self.browse_teams_page.visit()
|
||||
self.verify_page_header()
|
||||
self.browse_teams_page.click_search_team_link()
|
||||
# TODO Add search page expectation once that implemented.
|
||||
search_results_page = self.browse_teams_page.search('banana')
|
||||
self.verify_search_header(search_results_page, 'banana')
|
||||
self.assertTrue(search_results_page.get_pagination_header_text().startswith('Showing 0 out of 0 total'))
|
||||
|
||||
|
||||
@attr('shard_5')
|
||||
@@ -652,8 +750,8 @@ class TeamFormActions(TeamsTabBase):
|
||||
self.browse_teams_page.click_create_team_link()
|
||||
self.verify_page_header(
|
||||
title='Create a New Team',
|
||||
description='Create a new team if you can\'t find existing teams to '
|
||||
'join, or if you would like to learn with friends you know.',
|
||||
description='Create a new team if you can\'t find an existing team to join, '
|
||||
'or if you would like to learn with friends you know.',
|
||||
breadcrumbs='All Topics {topic_name}'.format(topic_name=self.topic['name'])
|
||||
)
|
||||
|
||||
@@ -807,7 +905,8 @@ class CreateTeamTest(TeamFormActions):
|
||||
Then I should see the Create Team header and form
|
||||
When I fill all the fields present with appropriate data
|
||||
And I click Create button
|
||||
Then I should see the page for my team
|
||||
Then I expect analytics events to be emitted
|
||||
And I should see the page for my team
|
||||
And I should see the message that says "You are member of this team"
|
||||
And the new team should be added to the list of teams within the topic
|
||||
And the number of teams should be updated on the topic card
|
||||
@@ -819,7 +918,24 @@ class CreateTeamTest(TeamFormActions):
|
||||
self.verify_and_navigate_to_create_team_page()
|
||||
|
||||
self.fill_create_or_edit_form()
|
||||
self.create_or_edit_team_page.submit_form()
|
||||
|
||||
expected_events = [
|
||||
{
|
||||
'event_type': 'edx.team.created',
|
||||
'event': {
|
||||
'course_id': self.course_id,
|
||||
}
|
||||
},
|
||||
{
|
||||
'event_type': 'edx.team.learner_added',
|
||||
'event': {
|
||||
'course_id': self.course_id,
|
||||
'add_method': 'added_on_create',
|
||||
}
|
||||
}
|
||||
]
|
||||
with self.assert_events_match_during(event_filter=self.only_team_events, expected_events=expected_events):
|
||||
self.create_or_edit_team_page.submit_form()
|
||||
|
||||
# Verify that the page is shown for the new team
|
||||
team_page = TeamPage(self.browser, self.course_id)
|
||||
@@ -848,13 +964,13 @@ class CreateTeamTest(TeamFormActions):
|
||||
Then I should see teams list page without any new team.
|
||||
And if I switch to "My Team", it shows no teams
|
||||
"""
|
||||
self.assertEqual(self.browse_teams_page.get_pagination_header_text(), 'Showing 0 out of 0 total')
|
||||
self.assertTrue(self.browse_teams_page.get_pagination_header_text().startswith('Showing 0 out of 0 total'))
|
||||
|
||||
self.verify_and_navigate_to_create_team_page()
|
||||
self.create_or_edit_team_page.cancel_team()
|
||||
|
||||
self.assertTrue(self.browse_teams_page.is_browser_on_page())
|
||||
self.assertEqual(self.browse_teams_page.get_pagination_header_text(), 'Showing 0 out of 0 total')
|
||||
self.assertTrue(self.browse_teams_page.get_pagination_header_text().startswith('Showing 0 out of 0 total'))
|
||||
|
||||
self.teams_page.click_all_topics()
|
||||
self.teams_page.verify_team_count_in_first_topic(0)
|
||||
@@ -1238,6 +1354,7 @@ class TeamPageTest(TeamsTabBase):
|
||||
And I should not see New Post button
|
||||
When I click on Join Team button
|
||||
Then there should be no Join Team button and no message
|
||||
And an analytics event should be emitted
|
||||
And I should see the updated information under Team Details
|
||||
And I should see New Post button
|
||||
And if I switch to "My Team", the team I have joined is displayed
|
||||
@@ -1245,7 +1362,17 @@ class TeamPageTest(TeamsTabBase):
|
||||
self._set_team_configuration_and_membership(create_membership=False)
|
||||
self.team_page.visit()
|
||||
self.assertTrue(self.team_page.join_team_button_present)
|
||||
self.team_page.click_join_team_button()
|
||||
expected_events = [
|
||||
{
|
||||
'event_type': 'edx.team.learner_added',
|
||||
'event': {
|
||||
'course_id': self.course_id,
|
||||
'add_method': 'joined_from_team_view'
|
||||
}
|
||||
}
|
||||
]
|
||||
with self.assert_events_match_during(event_filter=self.only_team_events, expected_events=expected_events):
|
||||
self.team_page.click_join_team_button()
|
||||
self.assertFalse(self.team_page.join_team_button_present)
|
||||
self.assertFalse(self.team_page.join_team_message_present)
|
||||
self.assert_team_details(num_members=1, is_member=True)
|
||||
@@ -1305,6 +1432,7 @@ class TeamPageTest(TeamsTabBase):
|
||||
Then I should see Leave Team link
|
||||
When I click on Leave Team link
|
||||
Then user should be removed from team
|
||||
And an analytics event should be emitted
|
||||
And I should see Join Team button
|
||||
And I should not see New Post button
|
||||
And if I switch to "My Team", the team I have left is not displayed
|
||||
@@ -1313,7 +1441,17 @@ class TeamPageTest(TeamsTabBase):
|
||||
self.team_page.visit()
|
||||
self.assertFalse(self.team_page.join_team_button_present)
|
||||
self.assert_team_details(num_members=1)
|
||||
self.team_page.click_leave_team_link()
|
||||
expected_events = [
|
||||
{
|
||||
'event_type': 'edx.team.learner_removed',
|
||||
'event': {
|
||||
'course_id': self.course_id,
|
||||
'remove_method': 'self_removal'
|
||||
}
|
||||
}
|
||||
]
|
||||
with self.assert_events_match_during(event_filter=self.only_team_events, expected_events=expected_events):
|
||||
self.team_page.click_leave_team_link()
|
||||
self.assert_team_details(num_members=0, is_member=False)
|
||||
self.assertTrue(self.team_page.join_team_button_present)
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
Acceptance tests for Studio related to the asset index page.
|
||||
"""
|
||||
|
||||
from flaky import flaky
|
||||
|
||||
from ...pages.studio.asset_index import AssetIndexPage
|
||||
|
||||
from .base_studio_test import StudioCourseTest
|
||||
@@ -35,6 +37,7 @@ class AssetIndexTest(StudioCourseTest):
|
||||
"""
|
||||
self.asset_page.visit()
|
||||
|
||||
@flaky # TODO fix this, see SOL-1160
|
||||
def test_type_filter_exists(self):
|
||||
"""
|
||||
Make sure type filter is on the page.
|
||||
|
||||
@@ -522,9 +522,7 @@ class LibraryUsersPageTest(StudioLibraryTest):
|
||||
"""
|
||||
self.page = LibraryUsersPage(self.browser, self.library_key)
|
||||
self.page.visit()
|
||||
self.page.wait_until_no_loading_indicator()
|
||||
|
||||
@flaky # TODO fix this; see TNL-2647
|
||||
def test_user_management(self):
|
||||
"""
|
||||
Scenario: Ensure that we can edit the permissions of users.
|
||||
|
||||
@@ -170,6 +170,8 @@ class CertificatesTest(StudioCourseTest):
|
||||
|
||||
self.assertEqual(len(self.certificates_page.certificates), 1)
|
||||
|
||||
#Refreshing the page, So page have the updated certificate object.
|
||||
self.certificates_page.refresh()
|
||||
signatory = self.certificates_page.certificates[0].signatories[0]
|
||||
self.assertIn("Updated signatory name", signatory.name)
|
||||
self.assertIn("Update signatory title", signatory.title)
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import datetime
|
||||
import json
|
||||
import ddt
|
||||
import unittest
|
||||
|
||||
from ..helpers import EventsTestMixin
|
||||
from .test_video_module import VideoBaseTest
|
||||
@@ -60,6 +61,7 @@ class VideoEventsTestMixin(EventsTestMixin, VideoBaseTest):
|
||||
class VideoEventsTest(VideoEventsTestMixin):
|
||||
""" Test video player event emission """
|
||||
|
||||
@unittest.skip('AN-5867')
|
||||
def test_video_control_events(self):
|
||||
"""
|
||||
Scenario: Video component is rendered in the LMS in Youtube mode without HTML5 sources
|
||||
|
||||
Binary file not shown.
@@ -129,7 +129,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: edx-platform\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2015-08-21 14:18+0000\n"
|
||||
"POT-Creation-Date: 2015-09-04 14:07+0000\n"
|
||||
"PO-Revision-Date: 2015-08-12 08:13+0000\n"
|
||||
"Last-Translator: Ahmed Jazzar <ajazzar@edraak.org>\n"
|
||||
"Language-Team: Arabic (http://www.transifex.com/open-edx/edx-platform/language/ar/)\n"
|
||||
@@ -1381,10 +1381,6 @@ msgstr "صحيح"
|
||||
msgid "incorrect"
|
||||
msgstr "غير صحيح"
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "partially correct"
|
||||
msgstr ""
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "incomplete"
|
||||
msgstr "ناقص"
|
||||
@@ -1407,10 +1403,6 @@ msgstr "هذا صحيح"
|
||||
msgid "This is incorrect."
|
||||
msgstr "هذا خطأ"
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "This is partially correct."
|
||||
msgstr ""
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "This is unanswered."
|
||||
msgstr "هذا غير مجاب عليه"
|
||||
@@ -5190,8 +5182,15 @@ msgid "{month} {day}, {year}"
|
||||
msgstr "{month} {day}، {year}"
|
||||
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid "a course of study offered by {partner_name}, through {platform_name}."
|
||||
msgstr "مساق دروس يقدِّمه {partner_name}، عبر {platform_name}."
|
||||
msgid ""
|
||||
"a course of study offered by {partner_short_name}, an online learning "
|
||||
"initiative of {partner_long_name} through {platform_name}."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid ""
|
||||
"a course of study offered by {partner_short_name}, through {platform_name}."
|
||||
msgstr ""
|
||||
|
||||
#. Translators: Accomplishments describe the awards/certifications obtained by
|
||||
#. students on this platform
|
||||
@@ -5302,16 +5301,14 @@ msgstr "تُقِرّ {platform_name} بإنجازات الطالب التالي
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid ""
|
||||
"This is a valid {platform_name} certificate for {user_name}, who "
|
||||
"participated in {partner_name} {course_number}"
|
||||
"participated in {partner_short_name} {course_number}"
|
||||
msgstr ""
|
||||
"هذه شهادة صالحة من {platform_name} للمستخدم {user_name} الذي شارك في "
|
||||
"{partner_name} {course_number}"
|
||||
|
||||
#. Translators: This text is bound to the HTML 'title' element of the page
|
||||
#. and appears in the browser title bar
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid "{partner_name} {course_number} Certificate | {platform_name}"
|
||||
msgstr "شهادة {partner_name} {course_number} | {platform_name}"
|
||||
msgid "{partner_short_name} {course_number} Certificate | {platform_name}"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This text fragment appears after the student's name
|
||||
#. (displayed in a large font) on the certificate
|
||||
@@ -5478,6 +5475,14 @@ msgstr ""
|
||||
"إذا لم يظهر مساقك على لوحة معلوماتك، يُرجى الاتصال بـ "
|
||||
"{payment_support_link}."
|
||||
|
||||
#: lms/djangoapps/commerce/api/v1/serializers.py
|
||||
msgid "{course_id} is not a valid course key."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/commerce/api/v1/serializers.py
|
||||
msgid "Course {course_id} does not exist."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/course_wiki/tab.py lms/djangoapps/course_wiki/views.py
|
||||
#: lms/templates/wiki/base.html
|
||||
msgid "Wiki"
|
||||
@@ -6032,6 +6037,23 @@ msgstr "اسم المستخدم {user} موجود مسبقًا."
|
||||
msgid "File is not attached."
|
||||
msgstr "الملف غير مُرفَق. "
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid "Could not find problem with this location."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid ""
|
||||
"The problem responses report is being created. To view the status of the "
|
||||
"report, see Pending Tasks below."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid ""
|
||||
"A problem responses report generation task is already in progress. Check the"
|
||||
" 'Pending Tasks' table for the status of the task. When completed, the "
|
||||
"report will be available for download in the table below."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid "Invoice number '{num}' does not exist."
|
||||
msgstr " الفاتورة رقم '{num}' غير موجودة."
|
||||
@@ -6451,6 +6473,10 @@ msgstr "لا توجد وضعية للمساق CourseMode باسم ({mode_slug})
|
||||
msgid "CourseMode price updated successfully"
|
||||
msgstr "تمّ عملية تحديث سعر CourseMode بنجاح"
|
||||
|
||||
#: lms/djangoapps/instructor/views/instructor_dashboard.py
|
||||
msgid "No end date set"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/instructor_dashboard.py
|
||||
msgid "Enrollment data is now available in {dashboard_link}."
|
||||
msgstr "تتوافر بيانات التسجيل الآن على {dashboard_link}."
|
||||
@@ -6557,18 +6583,6 @@ msgstr "بريد إلكتروني خارجي"
|
||||
msgid "Grades for assignment \"{name}\""
|
||||
msgstr "درجات الواجب \"{name}\""
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Found {num} records to dump."
|
||||
msgstr "وُجدت {num} سجلّات للتخلّص منها."
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Couldn't find module with that urlname."
|
||||
msgstr "نأسف لتعذّر إيجاد وحدة بذلك الرابط."
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Student state for problem {problem}"
|
||||
msgstr "حالة الطالب بالنسبة للمسألة {problem}"
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Grades from {course_id}"
|
||||
msgstr "الدرجات من المساق رقم {course_id}"
|
||||
@@ -6736,6 +6750,12 @@ msgstr "جرى الحذف"
|
||||
msgid "emailed"
|
||||
msgstr "الإرسال بالبريد الإلكتروني"
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
msgid "generated"
|
||||
msgstr "الاستحداث"
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
@@ -6748,12 +6768,6 @@ msgstr "التقييم "
|
||||
msgid "problem distribution graded"
|
||||
msgstr "تقييم توزيع المسائل "
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
msgid "generated"
|
||||
msgstr "الاستحداث"
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
@@ -8382,12 +8396,12 @@ msgid "course_id must be provided"
|
||||
msgstr "يجب توفير الرقم التغريفي للمساق course_id."
|
||||
|
||||
#: lms/djangoapps/teams/views.py
|
||||
msgid "The supplied topic id {topic_id} is not valid"
|
||||
msgstr "الرقم التعريفي الذي جرى توفيره حول الموضوع {topic_id} غير صالح."
|
||||
msgid "text_search and order_by cannot be provided together"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/views.py
|
||||
msgid "text_search is not yet supported."
|
||||
msgstr "إنّ خاصّية البحث في النصّ text_search غير مدعومة بعد."
|
||||
msgid "The supplied topic id {topic_id} is not valid"
|
||||
msgstr "الرقم التعريفي الذي جرى توفيره حول الموضوع {topic_id} غير صالح."
|
||||
|
||||
#. Translators: 'ordering' is a string describing a way
|
||||
#. of ordering a list. For example, {ordering} may be
|
||||
@@ -10195,6 +10209,10 @@ msgstr "المساعدة"
|
||||
msgid "Sign Out"
|
||||
msgstr "تسجيل الخروج"
|
||||
|
||||
#: common/lib/capa/capa/templates/codeinput.html
|
||||
msgid "{programming_language} editor"
|
||||
msgstr ""
|
||||
|
||||
#: common/templates/license.html
|
||||
msgid "All Rights Reserved"
|
||||
msgstr "جميع الحقوق محفوظة"
|
||||
@@ -12862,8 +12880,10 @@ msgid "Section:"
|
||||
msgstr "القسم:"
|
||||
|
||||
#: lms/templates/courseware/legacy_instructor_dashboard.html
|
||||
msgid "Problem urlname:"
|
||||
msgstr "اسم الرابط urlname الخاص بالمسألة: "
|
||||
msgid ""
|
||||
"To download a CSV listing student responses to a given problem, visit the "
|
||||
"Data Download section of the Instructor Dashboard."
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/courseware/legacy_instructor_dashboard.html
|
||||
msgid ""
|
||||
@@ -14860,6 +14880,20 @@ msgstr ""
|
||||
msgid "Generate Proctored Exam Results Report"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid ""
|
||||
"To generate a CSV file that lists all student answers to a given problem, "
|
||||
"enter the location of the problem (from its Staff Debug Info)."
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid "Problem location: "
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid "Download a CSV of problem responses"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid ""
|
||||
"For smaller courses, click to list profile information for enrolled students"
|
||||
@@ -17396,60 +17430,51 @@ msgid "This module is not enabled."
|
||||
msgstr "هذه الوحدة غير مفعَّلة."
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"Upon successful completion of your course, learners receive a certificate to"
|
||||
" acknowledge their accomplishment. If you are a course team member with the "
|
||||
"Admin role in Studio, you can configure your course certificate."
|
||||
msgid "Working with Certificates"
|
||||
msgstr ""
|
||||
"عند استكمال الطلّاب لمساقك بنجاح، يحصلون على شهادة تُثبِت إنجازهم. وإذا كنت "
|
||||
"عضوًا في فريق المساق بدور مشرِف في الاستوديو، يمكنك إعداد شهادة مساقك."
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"Click {em_start}Add your first certificate{em_end} to add a certificate "
|
||||
"configuration. Upload the organization logo to be used on the certificate, "
|
||||
"and specify at least one signatory. You can include up to four signatories "
|
||||
"for a certificate. You can also upload a signature image file for each "
|
||||
"signatory. {em_start}Note:{em_end} Signature images are used only for "
|
||||
"verified certificates. Optionally, specify a different course title to use "
|
||||
"on your course certificate. You might want to use a different title if, for "
|
||||
"example, the official course name is too long to display well on a "
|
||||
"certificate."
|
||||
"Specify a course title to use on the certificate if the course's official "
|
||||
"title is too long to be displayed well."
|
||||
msgstr ""
|
||||
"يُرجى النقر على {em_start}أَضِف شهادتك الأولى{em_end} لتُضيف إعدادات "
|
||||
"الشهادة. ثمّ حَمِّل شعار المؤسّسة لوضعه على الشهادة وحدِّد موقِّعًا واحدًا "
|
||||
"على الأقلّ وأربعة على الأكثر لكل شهادة. ويمكنك أيضًا تحميل صورة التوقيع لكل "
|
||||
"موقّع. {em_start}ملاحظة:{em_end} تُستخدَم صور التواقيع فقط للشهادات "
|
||||
"الموثَّقة. أو إذا أردت، يمكنك أن تحدِّد اسمًا مختلفًا للمساق لوضعه على "
|
||||
"شهادتك. وقد ترغب في استخدام اسم مختلف إذا كان، مثلًا، الاسم الرسمي للمساق "
|
||||
"طويلًا جدًّا إلى درجة أنّه لن يبدو واضحًا على الشهادة."
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"Select a course mode and click {em_start}Preview Certificate{em_end} to "
|
||||
"preview the certificate that a learner in the selected enrollment track "
|
||||
"would receive. When the certificate is ready for issuing, click "
|
||||
"{em_start}Activate.{em_end} To stop issuing an active certificate, click "
|
||||
"{em_start}Deactivate{em_end}."
|
||||
"For verified certificates, specify between one and four signatories and "
|
||||
"upload the associated images."
|
||||
msgstr ""
|
||||
"يُرجى اختيار وضعية للمساق ثمّ النقر على {em_start}معاينة الشهادة{em_end} "
|
||||
"لمعاينة الشهادة التي سيحصل عليها المتعلّم في مسار التسجيل المُنتقى. وعندما "
|
||||
"تَجهَز الشهادة للإصدار، يُرجى النقر على {em_start}تفعيل.{em_end}. ولإيقاف "
|
||||
"إصدار شهادة مفعَّلة، يُرجى النقر على {em_start}إبطال التفعيل{em_end}."
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
" To edit the certificate configuration, hover over the top right corner of "
|
||||
"the form and click {em_start}Edit{em_end}. To delete a certificate, hover "
|
||||
"over the top right corner of the form and click the delete icon. In general,"
|
||||
" do not delete certificates after a course has started, because some "
|
||||
"certificates might already have been issued to learners."
|
||||
"To edit or delete a certificate before it is activated, hover over the top "
|
||||
"right corner of the form and select {em_start}Edit{em_end} or the delete "
|
||||
"icon."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"To view a sample certificate, choose a course mode and select "
|
||||
"{em_start}Preview Certificate{em_end}."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid "Issuing Certificates to Learners"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"To begin issuing certificates, a course team member with the Admin role "
|
||||
"selects {em_start}Activate{em_end}. Course team members without the Admin "
|
||||
"role cannot edit or delete an activated certificate."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"{em_start}Do not{em_end} delete certificates after a course has started; "
|
||||
"learners who have already earned certificates will no longer be able to "
|
||||
"access them."
|
||||
msgstr ""
|
||||
"لتعديل إعدادات الشهادة، يُرجى تحريك الماوس إلى الزاوية العليا اليمنى من "
|
||||
"الاستمارة والنقر على {em_start}تعديل{em_end}. ولحذف إحدى الشهادات، يُرجى "
|
||||
"تحريك الماوس إلى الزاوية العليا اليمنى من الاستمارة والنقر على رمز الحذف. "
|
||||
"وبشكل عام، لا تحذف الشهادات بعد بدء المساق، لأنّ بعض الشهادات قد تكون "
|
||||
"أُصدِرت مسبقًا للمتعلِّمين."
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid "Learn more about certificates"
|
||||
|
||||
Binary file not shown.
@@ -57,6 +57,7 @@
|
||||
# Translators:
|
||||
# Abdelghani Gadiri <wh.gnu.linux@gmail.com>, 2014
|
||||
# qrfahasan <ahasan@qrf.org>, 2014
|
||||
# Ahmad <reload_cobra2@yahoo.com>, 2015
|
||||
# Ahmed Jazzar <ajazzar@edraak.org>, 2015
|
||||
# mohammad hamdi <babrica@hotmail.com>, 2014
|
||||
# may <may@qordoba.com>, 2014
|
||||
@@ -80,8 +81,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: edx-platform\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2015-08-21 14:17+0000\n"
|
||||
"PO-Revision-Date: 2015-08-21 02:41+0000\n"
|
||||
"POT-Creation-Date: 2015-09-04 14:06+0000\n"
|
||||
"PO-Revision-Date: 2015-09-04 14:08+0000\n"
|
||||
"Last-Translator: Sarina Canelake <sarina@edx.org>\n"
|
||||
"Language-Team: Arabic (http://www.transifex.com/open-edx/edx-platform/language/ar/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -127,8 +128,8 @@ msgstr "موافق"
|
||||
#: cms/static/js/views/show_textbook.js cms/static/js/views/validation.js
|
||||
#: cms/static/js/views/modals/base_modal.js
|
||||
#: cms/static/js/views/modals/course_outline_modals.js
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
#: cms/templates/js/add-xblock-component-menu-problem.underscore
|
||||
#: cms/templates/js/add-xblock-component-menu.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
@@ -139,6 +140,11 @@ msgstr "موافق"
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
#: cms/templates/js/section-name-edit.underscore
|
||||
#: cms/templates/js/xblock-string-field-editor.underscore
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
#: common/static/common/templates/discussion/response-comment-edit.underscore
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
#: common/static/common/templates/discussion/thread-response-edit.underscore
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
#: lms/templates/instructor/instructor_dashboard_2/cohort-form.underscore
|
||||
msgid "Cancel"
|
||||
msgstr "إلغاء"
|
||||
@@ -148,17 +154,6 @@ msgstr "إلغاء"
|
||||
#: cms/static/js/views/manage_users_and_roles.js
|
||||
#: cms/static/js/views/show_textbook.js
|
||||
#: common/static/js/vendor/ova/catch/js/catch.js
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
#: cms/templates/js/content-group-details.underscore
|
||||
#: cms/templates/js/content-group-editor.underscore
|
||||
#: cms/templates/js/course-outline.underscore
|
||||
#: cms/templates/js/course_grade_policy.underscore
|
||||
#: cms/templates/js/group-configuration-details.underscore
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
#: cms/templates/js/show-textbook.underscore
|
||||
#: cms/templates/js/signatory-editor.underscore
|
||||
#: cms/templates/js/xblock-outline.underscore
|
||||
msgid "Delete"
|
||||
msgstr "حذف"
|
||||
|
||||
@@ -233,14 +228,12 @@ msgstr "خطأ"
|
||||
msgid "Save"
|
||||
msgstr "حفظ"
|
||||
|
||||
#. #-#-#-#-# djangojs-partial.po (edx-platform) #-#-#-#-#
|
||||
#. Translators: this is a message from the raw HTML editor displayed in the
|
||||
#. browser when a user needs to edit HTML
|
||||
#: cms/static/js/views/modals/edit_xblock.js
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: cms/templates/js/signatory-editor.underscore
|
||||
msgid "Close"
|
||||
msgstr "إغلاق"
|
||||
msgstr "إغلاق "
|
||||
|
||||
#: common/lib/xmodule/xmodule/js/src/annotatable/display.js
|
||||
msgid "Show Annotations"
|
||||
@@ -336,6 +329,8 @@ msgstr "لم يلبِّ مجموع نقاطك المعيار المطلوب لل
|
||||
|
||||
#: common/lib/xmodule/xmodule/js/src/combinedopenended/display.js
|
||||
#: lms/static/coffee/src/staff_grading/staff_grading.js
|
||||
#: common/static/common/templates/discussion/thread-response.underscore
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
#: lms/templates/verify_student/incourse_reverify.underscore
|
||||
msgid "Submit"
|
||||
msgstr "تقديم"
|
||||
@@ -765,18 +760,10 @@ msgstr "خصائص المستند"
|
||||
msgid "Edit HTML"
|
||||
msgstr "تعديل لغة HTML"
|
||||
|
||||
#. #-#-#-#-# djangojs-partial.po (edx-platform) #-#-#-#-#
|
||||
#. Translators: this is a message from the raw HTML editor displayed in the
|
||||
#. browser when a user needs to edit HTML
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: common/static/js/vendor/ova/catch/js/catch.js
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/content-group-details.underscore
|
||||
#: cms/templates/js/course_info_handouts.underscore
|
||||
#: cms/templates/js/group-configuration-details.underscore
|
||||
#: cms/templates/js/show-textbook.underscore
|
||||
#: cms/templates/js/signatory-details.underscore
|
||||
#: cms/templates/js/xblock-string-field-editor.underscore
|
||||
msgid "Edit"
|
||||
msgstr "تعديل"
|
||||
|
||||
@@ -1177,11 +1164,9 @@ msgstr "مستند جديد"
|
||||
msgid "New window"
|
||||
msgstr "نافذة جديدة"
|
||||
|
||||
#. #-#-#-#-# djangojs-partial.po (edx-platform) #-#-#-#-#
|
||||
#. Translators: this is a message from the raw HTML editor displayed in the
|
||||
#. browser when a user needs to edit HTML
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: cms/templates/js/paging-header.underscore
|
||||
msgid "Next"
|
||||
msgstr "التالي"
|
||||
|
||||
@@ -1531,12 +1516,9 @@ msgstr ""
|
||||
"يبدو أن الرابط الذي أدخلته عبارة عن رابط خارجي، هل تريد إضافة البادئة "
|
||||
"http:// اللازمة؟"
|
||||
|
||||
#. #-#-#-#-# djangojs-partial.po (edx-platform) #-#-#-#-#
|
||||
#. Translators: this is a message from the raw HTML editor displayed in the
|
||||
#. browser when a user needs to edit HTML
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: cms/templates/js/signatory-details.underscore
|
||||
#: cms/templates/js/signatory-editor.underscore
|
||||
msgid "Title"
|
||||
msgstr "العنوان"
|
||||
|
||||
@@ -2161,6 +2143,18 @@ msgstr "نأسف لحدوث مشكلة في حذف هذا التعليق. يُر
|
||||
msgid "Are you sure you want to delete this response?"
|
||||
msgstr "هل أنت واثق من أنّك تودّ حذف هذا الرد؟"
|
||||
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
msgid "Required field."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
msgid "Please do not use any spaces in this field."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
msgid "Please do not use any spaces or special characters in this field."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/js/components/views/paging_header.js
|
||||
msgid "Showing %(first_index)s out of %(num_items)s total"
|
||||
msgstr "إظهار %(first_index)s من أصل %(num_items)s."
|
||||
@@ -2360,6 +2354,7 @@ msgstr "تاريخ النشر"
|
||||
|
||||
#: common/static/js/vendor/ova/catch/js/catch.js
|
||||
#: lms/static/js/courseware/credit_progress.js
|
||||
#: common/static/common/templates/discussion/forum-actions.underscore
|
||||
#: lms/templates/discovery/facet.underscore
|
||||
#: lms/templates/edxnotes/note-item.underscore
|
||||
msgid "More"
|
||||
@@ -2439,21 +2434,34 @@ msgid "An unexpected error occurred. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/team.js
|
||||
msgid "last activity"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/team.js
|
||||
msgid "open slots"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/topic.js
|
||||
#: lms/templates/edxnotes/tab-item.underscore
|
||||
msgid "name"
|
||||
msgstr "الاسم "
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/team.js
|
||||
msgid "open_slots"
|
||||
msgstr "open_slots"
|
||||
|
||||
#. Translators: This refers to the number of teams (a count of how many teams
|
||||
#. there are)
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/topic.js
|
||||
msgid "team count"
|
||||
msgstr "عدد أعضاء الفريق"
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
#: cms/templates/js/content-group-editor.underscore
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
msgid "Create"
|
||||
msgstr "إنشاء "
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
msgid "Update"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
msgid "Team Name (Required) *"
|
||||
msgstr ""
|
||||
@@ -2478,6 +2486,7 @@ msgid "Language"
|
||||
msgstr "اللغة"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid ""
|
||||
"The language that team members primarily use to communicate with each other."
|
||||
msgstr ""
|
||||
@@ -2488,6 +2497,7 @@ msgid "Country"
|
||||
msgstr "البلد"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "The country that team members primarily identify with."
|
||||
msgstr ""
|
||||
|
||||
@@ -2520,20 +2530,48 @@ msgstr ""
|
||||
msgid "You are not currently a member of any team."
|
||||
msgstr ""
|
||||
|
||||
#. Translators: "and others" refers to fact that additional members of a team
|
||||
#. exist that are not displayed.
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_card.js
|
||||
msgid "and others"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: 'date' is a placeholder for a fuzzy, relative timestamp (see:
|
||||
#. https://github.com/rmm5t/jquery-timeago)
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_card.js
|
||||
msgid "Last Activity %(date)s"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_card.js
|
||||
msgid "View %(span_start)s %(team_name)s %(span_end)s"
|
||||
msgstr "مشاهدة %(span_start)s %(team_name)s %(span_end)s"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_join.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile_header_actions.js
|
||||
msgid "An error occurred. Try again."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_join.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
msgid "Leave this team?"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
msgid ""
|
||||
"If you leave, you can no longer post in this team's discussions. Your place "
|
||||
"will be available to another learner."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
#: lms/static/js/verify_student/views/reverify_view.js
|
||||
#: lms/templates/verify_student/review_photos_step.underscore
|
||||
msgid "Confirm"
|
||||
msgstr "تأكيد"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile_header_actions.js
|
||||
msgid "You already belong to another team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_join.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile_header_actions.js
|
||||
msgid "This team is full."
|
||||
msgstr ""
|
||||
|
||||
@@ -2555,6 +2593,10 @@ msgstr ""
|
||||
msgid "teams"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Teams"
|
||||
msgstr "الفِرَق"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"See all teams in your course, organized by topic. Join a team to collaborate"
|
||||
@@ -2563,31 +2605,52 @@ msgstr ""
|
||||
"تفضّل بالاطّلاع على جميع الفرق في مساقك، مرتّبةً بحسب الموضوع. وانضم إلى "
|
||||
"أحدها للتعاون مع المتعلّمين الآخرين المهتمّين بالمجال نفسه مثلك."
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Teams"
|
||||
msgstr "الفِرَق"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "My Team"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: sr_start and sr_end surround text meant only for screen
|
||||
#. readers. The whole string will be shown to users as "Browse teams" if they
|
||||
#. are using a screenreader, and "Browse" otherwise.
|
||||
#. readers.
|
||||
#. The whole string will be shown to users as "Browse teams" if they are using
|
||||
#. a
|
||||
#. screenreader, and "Browse" otherwise.
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Browse %(sr_start)s teams %(sr_end)s"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"Create a new team if you can't find existing teams to join, or if you would "
|
||||
"like to learn with friends you know."
|
||||
msgid "Team Search"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Showing results for \"%(searchString)s\""
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Create a New Team"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"Create a new team if you can't find an existing team to join, or if you "
|
||||
"would like to learn with friends you know."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile-header-actions.underscore
|
||||
msgid "Edit Team"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"If you make significant changes, make sure you notify members of the team "
|
||||
"before making these changes."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Search teams"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "All Topics"
|
||||
msgstr ""
|
||||
@@ -2614,15 +2677,27 @@ msgstr[3] "%(team_count)s فِرق"
|
||||
msgstr[4] "%(team_count)s فِرق"
|
||||
msgstr[5] "%(team_count)s فريقاً"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topic_card.js
|
||||
msgid "Topic"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topic_card.js
|
||||
msgid "View Teams in the %(topic_name)s Topic"
|
||||
msgstr "استعراض الفِرق في موضوع %(topic_name)s"
|
||||
|
||||
#. Translators: this string is shown at the bottom of the teams page
|
||||
#. to find a team to join or else to create a new one. There are three
|
||||
#. links that need to be included in the message:
|
||||
#. 1. Browse teams in other topics
|
||||
#. 2. search teams
|
||||
#. 3. create a new team
|
||||
#. Be careful to start each link with the appropriate start indicator
|
||||
#. (e.g. {browse_span_start} for #1) and finish it with {span_end}.
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topic_teams.js
|
||||
msgid ""
|
||||
"Try {browse_span_start}browsing all teams{span_end} or "
|
||||
"{search_span_start}searching team descriptions{span_end}. If you still can't"
|
||||
" find a team to join, {create_span_start}create a new team in this "
|
||||
"{browse_span_start}Browse teams in other topics{span_end} or "
|
||||
"{search_span_start}search teams{span_end} in this topic. If you still can't "
|
||||
"find a team to join, {create_span_start}create a new team in this "
|
||||
"topic{span_end}."
|
||||
msgstr ""
|
||||
|
||||
@@ -4098,11 +4173,6 @@ msgstr "التقاط صورة لبطاقتك الشخصية"
|
||||
msgid "Review your info"
|
||||
msgstr "مراجعة معلوماتك"
|
||||
|
||||
#: lms/static/js/verify_student/views/reverify_view.js
|
||||
#: lms/templates/verify_student/review_photos_step.underscore
|
||||
msgid "Confirm"
|
||||
msgstr "تأكيد"
|
||||
|
||||
#: lms/static/js/verify_student/views/step_view.js
|
||||
msgid "An error has occurred. Please try reloading the page."
|
||||
msgstr "نأسف لحدوث خطأ. يُرجى محاولة إعادة تحميل الصفحة."
|
||||
@@ -4690,7 +4760,7 @@ msgstr "جرى حذف ملفّك."
|
||||
msgid "Date Added"
|
||||
msgstr "تاريخ الإضافة "
|
||||
|
||||
#: cms/static/js/views/assets.js cms/templates/js/asset-library.underscore
|
||||
#: cms/static/js/views/assets.js
|
||||
msgid "Type"
|
||||
msgstr "النوع"
|
||||
|
||||
@@ -5304,18 +5374,6 @@ msgstr ""
|
||||
"لا يمكن أن يزيد مجموع الأحرف في حقلي المؤسسة ورمز المكتبة عن <%=limit%> "
|
||||
"حرفًا."
|
||||
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
msgid "Required field."
|
||||
msgstr "حقل مطلوب."
|
||||
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
msgid "Please do not use any spaces in this field."
|
||||
msgstr "يُرجى عدم إدخال أي مسافات في هذا الحقل."
|
||||
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
msgid "Please do not use any spaces or special characters in this field."
|
||||
msgstr "يُرجى عدم إدخال أي مسافات أو أحرف خاصة في هذا الحقل."
|
||||
|
||||
#: cms/static/js/views/utils/xblock_utils.js
|
||||
msgid "component"
|
||||
msgstr "مكوِّن"
|
||||
@@ -5408,11 +5466,526 @@ msgstr "الإجراءات"
|
||||
msgid "Due Date"
|
||||
msgstr "تاريخ الاستحقاق"
|
||||
|
||||
#: cms/templates/js/paging-header.underscore
|
||||
#: common/static/common/templates/components/paging-footer.underscore
|
||||
#: common/static/common/templates/discussion/pagination.underscore
|
||||
msgid "Previous"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/previous-video-upload-list.underscore
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
#: lms/templates/verify_student/enrollment_confirmation_step.underscore
|
||||
msgid "Status"
|
||||
msgstr "الحالة"
|
||||
|
||||
#: common/static/common/templates/image-modal.underscore
|
||||
msgid "Large"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/image-modal.underscore
|
||||
msgid "Zoom In"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/image-modal.underscore
|
||||
msgid "Zoom Out"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/paging-footer.underscore
|
||||
msgid "Page number"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/paging-footer.underscore
|
||||
msgid "Enter the page number you'd like to quickly navigate to."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/paging-header.underscore
|
||||
msgid "Sorted by"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/search-field.underscore
|
||||
msgid "Clear search"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "DISCUSSION HOME:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
#: lms/templates/commerce/provider.underscore
|
||||
#: lms/templates/commerce/receipt.underscore
|
||||
#: lms/templates/discovery/course_card.underscore
|
||||
msgid "gettext("
|
||||
msgstr "gettext("
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Find discussions"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Focus in on specific topics"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Search for specific posts"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Sort by date, vote, or comments"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Engage with posts"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Upvote posts and good responses"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Report Forum Misuse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Follow posts for updates"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Receive updates"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Toggle Notifications Setting"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid ""
|
||||
"Check this box to receive an email digest once a day notifying you about "
|
||||
"new, unread activity from posts you are following."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-answer.underscore
|
||||
msgid "Mark as Answer"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-answer.underscore
|
||||
msgid "Unmark as Answer"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-close.underscore
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-endorse.underscore
|
||||
msgid "Endorse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-endorse.underscore
|
||||
msgid "Unendorse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-follow.underscore
|
||||
msgid "Follow"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-follow.underscore
|
||||
msgid "Unfollow"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-pin.underscore
|
||||
msgid "Pin"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-pin.underscore
|
||||
msgid "Unpin"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-report.underscore
|
||||
msgid "Report abuse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-report.underscore
|
||||
msgid "Report"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-report.underscore
|
||||
msgid "Unreport"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-vote.underscore
|
||||
msgid "Vote for this post,"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Visible To:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "All Groups"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid ""
|
||||
"Discussion admins, moderators, and TAs can make their posts visible to all "
|
||||
"students or specify a single cohort."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Title:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Add a clear and descriptive title to encourage participation."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Enter your question or comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "follow this post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "post anonymously"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "post anonymously to classmates"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Add Post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/post-user-display.underscore
|
||||
msgid "Community TA"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/profile-thread.underscore
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "This thread is closed."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/profile-thread.underscore
|
||||
msgid "View discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-edit.underscore
|
||||
msgid "Editing comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-edit.underscore
|
||||
msgid "Update comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-show.underscore
|
||||
#, python-format
|
||||
msgid "posted %(time_ago)s by %(author)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-show.underscore
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "Reported"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
msgid "Editing post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
msgid "Edit post title"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
msgid "Update post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "answered question"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "unanswered question"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "Pinned"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "Following"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "By: Staff"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "By: Community TA"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
msgid "fmt"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(comments_count)s %(span_sr_open)scomments (%(unread_comments_count)s "
|
||||
"unread comments)%(span_close)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#, python-format
|
||||
msgid "%(comments_count)s %(span_sr_open)scomments %(span_close)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-edit.underscore
|
||||
msgid "Editing response"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-edit.underscore
|
||||
msgid "Update response"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "marked as answer %(time_ago)s by %(user)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "marked as answer %(time_ago)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "endorsed %(time_ago)s by %(user)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "endorsed %(time_ago)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response.underscore
|
||||
msgid "fmts"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response.underscore
|
||||
msgid "Add a comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
#, python-format
|
||||
msgid "This post is visible only to %(group_name)s."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "This post is visible to everyone."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
#, python-format
|
||||
msgid "%(post_type)s posted %(time_ago)s by %(author)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "Closed"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
#, python-format
|
||||
msgid "Related to: %(courseware_title_linked)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid "Post type:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid "Question"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid "Discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid ""
|
||||
"Questions raise issues that need answers. Discussions share ideas and start "
|
||||
"conversations."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Add a Response"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Post a response:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Expand discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Collapse discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Topic Area:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Discussion topics; current selection is:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Filter topics"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Add your post to a relevant topic to help others find it."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/user-profile.underscore
|
||||
msgid "Active Threads"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates.underscore
|
||||
msgid "username or email"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "No results"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Course Key"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Download URL"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Grade"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Last Updated"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Download the user's certificate"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Not available"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Regenerate"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Regenerate the user's certificate"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Your team could not be created."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Your team could not be updated."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid ""
|
||||
"Enter information to describe your team. You cannot change these details "
|
||||
"after you create the team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Optional Characteristics"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid ""
|
||||
"Help other learners decide whether to join your team by specifying some "
|
||||
"characteristics for your team. Choose carefully, because fewer people might "
|
||||
"be interested in joining your team if it seems too restrictive."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Create team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Update team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Cancel team creating."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Cancel team updating."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-actions.underscore
|
||||
msgid "Are you having trouble finding a team to join?"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile-header-actions.underscore
|
||||
msgid "Join Team"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "New Post"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Team Details"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "You are a member of this team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Team member profiles"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Team capacity"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "country"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "language"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Leave Team"
|
||||
msgstr ""
|
||||
|
||||
#: lms/static/js/fixtures/donation.underscore
|
||||
#: lms/templates/dashboard/donation.underscore
|
||||
msgid "Donate"
|
||||
msgstr "تبرَّع"
|
||||
|
||||
#: lms/templates/ccx/schedule.underscore
|
||||
msgid "Expand All"
|
||||
msgstr ""
|
||||
@@ -5453,12 +6026,6 @@ msgstr ""
|
||||
msgid "Subsection"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/commerce/provider.underscore
|
||||
#: lms/templates/commerce/receipt.underscore
|
||||
#: lms/templates/discovery/course_card.underscore
|
||||
msgid "gettext("
|
||||
msgstr "gettext("
|
||||
|
||||
#: lms/templates/commerce/provider.underscore
|
||||
#, python-format
|
||||
msgid "<img src='%s' alt='%s'></image>"
|
||||
@@ -5554,10 +6121,6 @@ msgstr ""
|
||||
msgid "End My Exam"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/dashboard/donation.underscore
|
||||
msgid "Donate"
|
||||
msgstr "تبرَّع"
|
||||
|
||||
#: lms/templates/discovery/course_card.underscore
|
||||
msgid "LEARN MORE"
|
||||
msgstr "اعرف المزيد"
|
||||
@@ -6566,6 +7129,16 @@ msgstr "استخدم خاصية السحب والإفلات أو اضغط هنا
|
||||
msgid "status"
|
||||
msgstr "الحالة"
|
||||
|
||||
#: cms/templates/js/add-xblock-component-button.underscore
|
||||
msgid "Add Component:"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/add-xblock-component-menu-problem.underscore
|
||||
#: cms/templates/js/add-xblock-component-menu.underscore
|
||||
#, python-format
|
||||
msgid "%(type)s Component Template Menu"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/add-xblock-component-menu-problem.underscore
|
||||
msgid "Common Problem Types"
|
||||
msgstr "المسائل الشائعة"
|
||||
@@ -6640,6 +7213,11 @@ msgstr "الرمز التعريفي"
|
||||
msgid "Certificate Details"
|
||||
msgstr "تفاصيل الشهادة"
|
||||
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "Course Title"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "Course Title Override"
|
||||
@@ -6686,19 +7264,13 @@ msgstr ""
|
||||
"الحقل فارغًا لاستخدام العنوان الرسمي للمساق."
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "Add Signatory"
|
||||
msgstr "إضافة مُوَقّع"
|
||||
msgid "Add Additional Signatory"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "(Up to 4 signatories are allowed for a certificate)"
|
||||
msgstr "(يمكن إضافة 4 موقِّعين كحد أقصى لكل شهادة)"
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
#: cms/templates/js/content-group-editor.underscore
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
msgid "Create"
|
||||
msgstr "إنشاء "
|
||||
|
||||
#: cms/templates/js/certificate-web-preview.underscore
|
||||
msgid "Choose mode"
|
||||
msgstr "اختر الوضع"
|
||||
@@ -7132,10 +7704,6 @@ msgstr "لم تُضِف بعد أي كتب إلى هذا المساق."
|
||||
msgid "Add your first textbook"
|
||||
msgstr "أضِف أوّل كتاب لك."
|
||||
|
||||
#: cms/templates/js/paging-header.underscore
|
||||
msgid "Previous"
|
||||
msgstr "السابق"
|
||||
|
||||
#: cms/templates/js/previous-video-upload-list.underscore
|
||||
msgid "Previous Uploads"
|
||||
msgstr "تحميلات سابقة"
|
||||
|
||||
Binary file not shown.
@@ -37,8 +37,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2015-08-24 22:03+0000\n"
|
||||
"PO-Revision-Date: 2015-08-24 22:03:48.240461\n"
|
||||
"POT-Creation-Date: 2015-09-04 14:15+0000\n"
|
||||
"PO-Revision-Date: 2015-09-04 14:15:47.324123\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: openedx-translation <openedx-translation@googlegroups.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -1418,10 +1418,6 @@ msgstr "çörréçt Ⱡ'σяєм ιρѕυм #"
|
||||
msgid "incorrect"
|
||||
msgstr "ïnçörréçt Ⱡ'σяєм ιρѕυм ∂σł#"
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "partially correct"
|
||||
msgstr "pärtïällý çörréçt Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмє#"
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "incomplete"
|
||||
msgstr "ïnçömplété Ⱡ'σяєм ιρѕυм ∂σłσ#"
|
||||
@@ -1444,10 +1440,6 @@ msgstr "Thïs ïs çörréçt. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
|
||||
msgid "This is incorrect."
|
||||
msgstr "Thïs ïs ïnçörréçt. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт#"
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "This is partially correct."
|
||||
msgstr "Thïs ïs pärtïällý çörréçt. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "This is unanswered."
|
||||
msgstr "Thïs ïs ünänswéréd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,#"
|
||||
@@ -5858,10 +5850,20 @@ msgid "{month} {day}, {year}"
|
||||
msgstr "{month} {day}, {year} Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
|
||||
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid "a course of study offered by {partner_name}, through {platform_name}."
|
||||
msgid ""
|
||||
"a course of study offered by {partner_short_name}, an online learning "
|
||||
"initiative of {partner_long_name} through {platform_name}."
|
||||
msgstr ""
|
||||
"ä çöürsé öf stüdý öfféréd ßý {partner_name}, thröügh {platform_name}. Ⱡ'σяєм"
|
||||
" ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
|
||||
"ä çöürsé öf stüdý öfféréd ßý {partner_short_name}, än önlïné léärnïng "
|
||||
"ïnïtïätïvé öf {partner_long_name} thröügh {platform_name}. Ⱡ'σяєм ιρѕυм "
|
||||
"∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
|
||||
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid ""
|
||||
"a course of study offered by {partner_short_name}, through {platform_name}."
|
||||
msgstr ""
|
||||
"ä çöürsé öf stüdý öfféréd ßý {partner_short_name}, thröügh {platform_name}. "
|
||||
"Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
|
||||
|
||||
#. Translators: Accomplishments describe the awards/certifications obtained by
|
||||
#. students on this platform
|
||||
@@ -5995,19 +5997,19 @@ msgstr ""
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid ""
|
||||
"This is a valid {platform_name} certificate for {user_name}, who "
|
||||
"participated in {partner_name} {course_number}"
|
||||
"participated in {partner_short_name} {course_number}"
|
||||
msgstr ""
|
||||
"Thïs ïs ä välïd {platform_name} çértïfïçäté för {user_name}, whö "
|
||||
"pärtïçïpätéd ïn {partner_name} {course_number} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
|
||||
"¢σηѕє¢тєтυя #"
|
||||
"pärtïçïpätéd ïn {partner_short_name} {course_number} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт "
|
||||
"αмєт, ¢σηѕє¢тєтυя #"
|
||||
|
||||
#. Translators: This text is bound to the HTML 'title' element of the page
|
||||
#. and appears in the browser title bar
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid "{partner_name} {course_number} Certificate | {platform_name}"
|
||||
msgid "{partner_short_name} {course_number} Certificate | {platform_name}"
|
||||
msgstr ""
|
||||
"{partner_name} {course_number} Çértïfïçäté | {platform_name} Ⱡ'σяєм ιρѕυм "
|
||||
"∂σłσя ѕιт αмєт, ¢σηѕ#"
|
||||
"{partner_short_name} {course_number} Çértïfïçäté | {platform_name} Ⱡ'σяєм "
|
||||
"ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
|
||||
|
||||
#. Translators: This text fragment appears after the student's name
|
||||
#. (displayed in a large font) on the certificate
|
||||
@@ -6194,6 +6196,15 @@ msgstr ""
|
||||
"Ìf ýöür çöürsé döés nöt äppéär ön ýöür däshßöärd, çöntäçt "
|
||||
"{payment_support_link}. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
|
||||
|
||||
#: lms/djangoapps/commerce/api/v1/serializers.py
|
||||
msgid "{course_id} is not a valid course key."
|
||||
msgstr ""
|
||||
"{course_id} ïs nöt ä välïd çöürsé kéý. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
|
||||
|
||||
#: lms/djangoapps/commerce/api/v1/serializers.py
|
||||
msgid "Course {course_id} does not exist."
|
||||
msgstr "Çöürsé {course_id} döés nöt éxïst. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
|
||||
|
||||
#: lms/djangoapps/course_wiki/tab.py lms/djangoapps/course_wiki/views.py
|
||||
#: lms/templates/wiki/base.html
|
||||
msgid "Wiki"
|
||||
@@ -6804,6 +6815,35 @@ msgstr "Ûsérnämé {user} älréädý éxïsts. Ⱡ'σяєм ιρѕυм ∂σ
|
||||
msgid "File is not attached."
|
||||
msgstr "Fïlé ïs nöt ättäçhéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid "Could not find problem with this location."
|
||||
msgstr ""
|
||||
"Çöüld nöt fïnd prößlém wïth thïs löçätïön. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
|
||||
"¢σηѕє¢тєтυя #"
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid ""
|
||||
"The problem responses report is being created. To view the status of the "
|
||||
"report, see Pending Tasks below."
|
||||
msgstr ""
|
||||
"Thé prößlém réspönsés répört ïs ßéïng çréätéd. Tö vïéw thé stätüs öf thé "
|
||||
"répört, séé Péndïng Täsks ßélöw. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт #"
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid ""
|
||||
"A problem responses report generation task is already in progress. Check the"
|
||||
" 'Pending Tasks' table for the status of the task. When completed, the "
|
||||
"report will be available for download in the table below."
|
||||
msgstr ""
|
||||
"À prößlém réspönsés répört générätïön täsk ïs älréädý ïn prögréss. Çhéçk thé"
|
||||
" 'Péndïng Täsks' täßlé för thé stätüs öf thé täsk. Whén çömplétéd, thé "
|
||||
"répört wïll ßé äväïläßlé för döwnlöäd ïn thé täßlé ßélöw. Ⱡ'σяєм ιρѕυм ∂σłσя"
|
||||
" ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ тємρσя ιη¢ι∂ι∂υηт υт"
|
||||
" łαвσяє єт ∂σłσяє мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм, qυιѕ ησѕтяυ∂ "
|
||||
"єχєя¢ιтαтιση υłłαм¢σ łαвσяιѕ ηιѕι υт αłιqυιρ єχ єα ¢σммσ∂σ ¢σηѕєqυαт. ∂υιѕ "
|
||||
"αυтє ιяυяє ∂σłσя ιη яєρяєнєη∂єяιт ιη νσłυρтαтє νєłιт єѕѕє ¢ιłłυм ∂σłσяє єυ "
|
||||
"ƒυgιαт ηυłłα ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢#"
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid "Invoice number '{num}' does not exist."
|
||||
msgstr ""
|
||||
@@ -7334,6 +7374,10 @@ msgstr ""
|
||||
"ÇöürséMödé prïçé üpdätéd süççéssfüllý Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
|
||||
"¢σηѕє¢тєтυ#"
|
||||
|
||||
#: lms/djangoapps/instructor/views/instructor_dashboard.py
|
||||
msgid "No end date set"
|
||||
msgstr "Nö énd däté sét Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт α#"
|
||||
|
||||
#: lms/djangoapps/instructor/views/instructor_dashboard.py
|
||||
msgid "Enrollment data is now available in {dashboard_link}."
|
||||
msgstr ""
|
||||
@@ -7439,21 +7483,6 @@ msgstr "Éxtérnäl émäïl Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт#"
|
||||
msgid "Grades for assignment \"{name}\""
|
||||
msgstr "Grädés för ässïgnmént \"{name}\" Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє#"
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Found {num} records to dump."
|
||||
msgstr "Föünd {num} réçörds tö dümp. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Couldn't find module with that urlname."
|
||||
msgstr ""
|
||||
"Çöüldn't fïnd mödülé wïth thät ürlnämé. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
|
||||
"¢σηѕє¢тєтυя#"
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Student state for problem {problem}"
|
||||
msgstr ""
|
||||
"Stüdént stäté för prößlém {problem} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢#"
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Grades from {course_id}"
|
||||
msgstr "Grädés fröm {course_id} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт α#"
|
||||
@@ -7656,6 +7685,12 @@ msgstr "délétéd Ⱡ'σяєм ιρѕυм #"
|
||||
msgid "emailed"
|
||||
msgstr "émäïléd Ⱡ'σяєм ιρѕυм #"
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
msgid "generated"
|
||||
msgstr "générätéd Ⱡ'σяєм ιρѕυм ∂σł#"
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
@@ -7668,12 +7703,6 @@ msgstr "grädéd Ⱡ'σяєм ιρѕυ#"
|
||||
msgid "problem distribution graded"
|
||||
msgstr "prößlém dïstrïßütïön grädéd Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє#"
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
msgid "generated"
|
||||
msgstr "générätéd Ⱡ'σяєм ιρѕυм ∂σł#"
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
@@ -10900,18 +10929,6 @@ msgstr ""
|
||||
"Nö dätä prövïdéd för üsér préférénçé üpdäté Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
|
||||
"¢σηѕє¢тєтυя #"
|
||||
|
||||
#: openedx/core/lib/api/paginators.py
|
||||
msgid "Page is not 'last', nor can it be converted to an int."
|
||||
msgstr ""
|
||||
"Pägé ïs nöt 'läst', nör çän ït ßé çönvértéd tö än ïnt. Ⱡ'σяєм ιρѕυм ∂σłσя "
|
||||
"ѕιт αмєт, ¢σηѕє¢тєтυя α#"
|
||||
|
||||
#: openedx/core/lib/api/paginators.py
|
||||
#, python-format
|
||||
msgid "Invalid page (%(page_number)s): %(message)s"
|
||||
msgstr ""
|
||||
"Ìnvälïd pägé (%(page_number)s): %(message)s Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σ#"
|
||||
|
||||
#: openedx/core/lib/api/view_utils.py
|
||||
msgid "This value is invalid."
|
||||
msgstr "Thïs välüé ïs ïnvälïd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢#"
|
||||
@@ -14596,8 +14613,12 @@ msgid "Section:"
|
||||
msgstr "Séçtïön: Ⱡ'σяєм ιρѕυм ∂#"
|
||||
|
||||
#: lms/templates/courseware/legacy_instructor_dashboard.html
|
||||
msgid "Problem urlname:"
|
||||
msgstr "Prößlém ürlnämé: Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
|
||||
msgid ""
|
||||
"To download a CSV listing student responses to a given problem, visit the "
|
||||
"Data Download section of the Instructor Dashboard."
|
||||
msgstr ""
|
||||
"Tö döwnlöäd ä ÇSV lïstïng stüdént réspönsés tö ä gïvén prößlém, vïsït thé "
|
||||
"Dätä Döwnlöäd séçtïön öf thé Ìnstrüçtör Däshßöärd. Ⱡ'σяєм ι#"
|
||||
|
||||
#: lms/templates/courseware/legacy_instructor_dashboard.html
|
||||
msgid ""
|
||||
@@ -16947,6 +16968,29 @@ msgstr ""
|
||||
"Généräté Pröçtöréd Éxäm Résülts Répört Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
|
||||
"¢σηѕє¢тєтυя#"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid ""
|
||||
"To generate a CSV file that lists all student answers to a given problem, "
|
||||
"enter the location of the problem (from its Staff Debug Info)."
|
||||
msgstr ""
|
||||
"Tö généräté ä ÇSV fïlé thät lïsts äll stüdént änswérs tö ä gïvén prößlém, "
|
||||
"éntér thé löçätïön öf thé prößlém (fröm ïts Stäff Déßüg Ìnfö). Ⱡ'σяєм ιρѕυм "
|
||||
"∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, ѕє∂ ∂σ єιυѕмσ∂ тємρσя "
|
||||
"ιη¢ι∂ι∂υηт υт łαвσяє єт ∂σłσяє мαgηα αłιqυα. υт єηιм α∂ мιηιм νєηιαм, qυιѕ "
|
||||
"ησѕтяυ∂ єχєя¢ιтαтιση υłłαм¢σ łαвσяιѕ ηιѕι υт αłιqυιρ єχ єα ¢σммσ∂σ "
|
||||
"¢σηѕєqυαт. ∂υιѕ αυтє ιяυяє ∂σłσя ιη яєρяєнєη∂єяιт ιη νσłυρтαтє νєłιт єѕѕє "
|
||||
"¢ιłłυм ∂σłσяє єυ ƒυgιαт ηυłłα ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢αт ¢υρι∂αтαт "
|
||||
"ηση ρяσι∂єηт, ѕυηт ιη ¢υłρα qυι σƒƒι¢ια ∂єѕєяυηт мσłłιт αηιм ι∂ єѕт łαвσя#"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid "Problem location: "
|
||||
msgstr "Prößlém löçätïön: Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт#"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid "Download a CSV of problem responses"
|
||||
msgstr ""
|
||||
"Döwnlöäd ä ÇSV öf prößlém réspönsés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєт#"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid ""
|
||||
"For smaller courses, click to list profile information for enrolled students"
|
||||
|
||||
Binary file not shown.
@@ -26,8 +26,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: 0.1a\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2015-08-24 22:03+0000\n"
|
||||
"PO-Revision-Date: 2015-08-24 22:03:48.948707\n"
|
||||
"POT-Creation-Date: 2015-09-04 14:15+0000\n"
|
||||
"PO-Revision-Date: 2015-09-04 14:15:47.640544\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: openedx-translation <openedx-translation@googlegroups.com>\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -73,8 +73,8 @@ msgstr "ÖK Ⱡ'σя#"
|
||||
#: cms/static/js/views/show_textbook.js cms/static/js/views/validation.js
|
||||
#: cms/static/js/views/modals/base_modal.js
|
||||
#: cms/static/js/views/modals/course_outline_modals.js
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
#: cms/templates/js/add-xblock-component-menu-problem.underscore
|
||||
#: cms/templates/js/add-xblock-component-menu.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
@@ -89,6 +89,7 @@ msgstr "ÖK Ⱡ'σя#"
|
||||
#: common/static/common/templates/discussion/response-comment-edit.underscore
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
#: common/static/common/templates/discussion/thread-response-edit.underscore
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
#: lms/templates/instructor/instructor_dashboard_2/cohort-form.underscore
|
||||
msgid "Cancel"
|
||||
msgstr "Çänçél Ⱡ'σяєм ιρѕυ#"
|
||||
@@ -2160,6 +2161,22 @@ msgstr ""
|
||||
"Àré ýöü süré ýöü wänt tö délété thïs réspönsé? Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
|
||||
"¢σηѕє¢тєтυя α#"
|
||||
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
msgid "Required field."
|
||||
msgstr "Réqüïréd fïéld. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт α#"
|
||||
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
msgid "Please do not use any spaces in this field."
|
||||
msgstr ""
|
||||
"Pléäsé dö nöt üsé äný späçés ïn thïs fïéld. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
|
||||
"¢σηѕє¢тєтυя #"
|
||||
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
msgid "Please do not use any spaces or special characters in this field."
|
||||
msgstr ""
|
||||
"Pléäsé dö nöt üsé äný späçés ör spéçïäl çhäräçtérs ïn thïs fïéld. Ⱡ'σяєм "
|
||||
"ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
|
||||
|
||||
#: common/static/common/js/components/views/paging_header.js
|
||||
msgid "Showing %(first_index)s out of %(num_items)s total"
|
||||
msgstr ""
|
||||
@@ -2365,6 +2382,7 @@ msgid "Public"
|
||||
msgstr "Püßlïç Ⱡ'σяєм ιρѕυ#"
|
||||
|
||||
#: common/static/js/vendor/ova/catch/js/catch.js
|
||||
#: common/static/common/templates/components/search-field.underscore
|
||||
#: lms/djangoapps/support/static/support/templates/certificates.underscore
|
||||
msgid "Search"
|
||||
msgstr "Séärçh Ⱡ'σяєм ιρѕυ#"
|
||||
@@ -2429,21 +2447,35 @@ msgstr ""
|
||||
"αмєт, ¢σηѕє¢тєтυя α#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/team.js
|
||||
msgid "last activity"
|
||||
msgstr "läst äçtïvïtý Ⱡ'σяєм ιρѕυм ∂σłσя ѕι#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/team.js
|
||||
msgid "open slots"
|
||||
msgstr "öpén slöts Ⱡ'σяєм ιρѕυм ∂σłσ#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/topic.js
|
||||
#: lms/templates/edxnotes/tab-item.underscore
|
||||
msgid "name"
|
||||
msgstr "nämé Ⱡ'σяєм ι#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/team.js
|
||||
msgid "open_slots"
|
||||
msgstr "öpén_slöts Ⱡ'σяєм ιρѕυм ∂σłσ#"
|
||||
|
||||
#. Translators: This refers to the number of teams (a count of how many teams
|
||||
#. there are)
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/topic.js
|
||||
msgid "team count"
|
||||
msgstr "téäm çöünt Ⱡ'σяєм ιρѕυм ∂σłσ#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
#: cms/templates/js/content-group-editor.underscore
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
msgid "Create"
|
||||
msgstr "Çréäté Ⱡ'σяєм ιρѕυ#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
msgid "Update"
|
||||
msgstr "Ûpdäté Ⱡ'σяєм ιρѕυ#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
msgid "Team Name (Required) *"
|
||||
msgstr "Téäm Nämé (Réqüïréd) * Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢#"
|
||||
@@ -2530,22 +2562,52 @@ msgstr ""
|
||||
"Ýöü äré nöt çürréntlý ä mémßér öf äný téäm. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
|
||||
"¢σηѕє¢тєтυя #"
|
||||
|
||||
#. Translators: "and others" refers to fact that additional members of a team
|
||||
#. exist that are not displayed.
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_card.js
|
||||
msgid "and others"
|
||||
msgstr "änd öthérs Ⱡ'σяєм ιρѕυм ∂σłσ#"
|
||||
|
||||
#. Translators: 'date' is a placeholder for a fuzzy, relative timestamp (see:
|
||||
#. https://github.com/rmm5t/jquery-timeago)
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_card.js
|
||||
msgid "Last Activity %(date)s"
|
||||
msgstr "Läst Àçtïvïtý %(date)s Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмє#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_card.js
|
||||
msgid "View %(span_start)s %(team_name)s %(span_end)s"
|
||||
msgstr ""
|
||||
"Vïéw %(span_start)s %(team_name)s %(span_end)s Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_join.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile_header_actions.js
|
||||
msgid "An error occurred. Try again."
|
||||
msgstr "Àn érrör öççürréd. Trý ägäïn. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_join.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
msgid "Leave this team?"
|
||||
msgstr "Léävé thïs téäm? Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
msgid ""
|
||||
"If you leave, you can no longer post in this team's discussions. Your place "
|
||||
"will be available to another learner."
|
||||
msgstr ""
|
||||
"Ìf ýöü léävé, ýöü çän nö löngér pöst ïn thïs téäm's dïsçüssïöns. Ýöür pläçé "
|
||||
"wïll ßé äväïläßlé tö änöthér léärnér. Ⱡ'σяєм ιρѕυм ∂σłσ#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
#: lms/static/js/verify_student/views/reverify_view.js
|
||||
#: lms/templates/verify_student/review_photos_step.underscore
|
||||
msgid "Confirm"
|
||||
msgstr "Çönfïrm Ⱡ'σяєм ιρѕυм #"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile_header_actions.js
|
||||
msgid "You already belong to another team."
|
||||
msgstr ""
|
||||
"Ýöü älréädý ßélöng tö änöthér téäm. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєт#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_join.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile_header_actions.js
|
||||
msgid "This team is full."
|
||||
msgstr "Thïs téäm ïs füll. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт#"
|
||||
|
||||
@@ -2565,6 +2627,10 @@ msgstr "Àll téäms Ⱡ'σяєм ιρѕυм ∂σł#"
|
||||
msgid "teams"
|
||||
msgstr "téäms Ⱡ'σяєм ιρѕ#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Teams"
|
||||
msgstr "Téäms Ⱡ'σяєм ιρѕ#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"See all teams in your course, organized by topic. Join a team to collaborate"
|
||||
@@ -2579,33 +2645,57 @@ msgstr ""
|
||||
"¢ιłłυм ∂σłσяє єυ ƒυgιαт ηυłłα ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢αт ¢υρι∂αтαт "
|
||||
"ηση ρяσι∂єηт, ѕυηт ιη ¢υłρα qυι σƒƒι¢ια ∂єѕєяυηт мσłłιт αηιм ι∂#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Teams"
|
||||
msgstr "Téäms Ⱡ'σяєм ιρѕ#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "My Team"
|
||||
msgstr "Mý Téäm Ⱡ'σяєм ιρѕυм #"
|
||||
|
||||
#. Translators: sr_start and sr_end surround text meant only for screen
|
||||
#. readers. The whole string will be shown to users as "Browse teams" if they
|
||||
#. are using a screenreader, and "Browse" otherwise.
|
||||
#. readers.
|
||||
#. The whole string will be shown to users as "Browse teams" if they are using
|
||||
#. a
|
||||
#. screenreader, and "Browse" otherwise.
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Browse %(sr_start)s teams %(sr_end)s"
|
||||
msgstr "Bröwsé %(sr_start)s téäms %(sr_end)s Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"Create a new team if you can't find existing teams to join, or if you would "
|
||||
"like to learn with friends you know."
|
||||
msgid "Team Search"
|
||||
msgstr "Téäm Séärçh Ⱡ'σяєм ιρѕυм ∂σłσя #"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Showing results for \"%(searchString)s\""
|
||||
msgstr ""
|
||||
"Çréäté ä néw téäm ïf ýöü çän't fïnd éxïstïng téäms tö jöïn, ör ïf ýöü wöüld "
|
||||
"lïké tö léärn wïth frïénds ýöü knöw. Ⱡ'σяєм ιρѕυм ∂σłσя#"
|
||||
"Shöwïng résülts för \"%(searchString)s\" Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Create a New Team"
|
||||
msgstr "Çréäté ä Néw Téäm Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмє#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"Create a new team if you can't find an existing team to join, or if you "
|
||||
"would like to learn with friends you know."
|
||||
msgstr ""
|
||||
"Çréäté ä néw téäm ïf ýöü çän't fïnd än éxïstïng téäm tö jöïn, ör ïf ýöü "
|
||||
"wöüld lïké tö léärn wïth frïénds ýöü knöw. Ⱡ'σяєм ιρѕυм ∂σł#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile-header-actions.underscore
|
||||
msgid "Edit Team"
|
||||
msgstr "Édït Téäm Ⱡ'σяєм ιρѕυм ∂σł#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"If you make significant changes, make sure you notify members of the team "
|
||||
"before making these changes."
|
||||
msgstr ""
|
||||
"Ìf ýöü mäké sïgnïfïçänt çhängés, mäké süré ýöü nötïfý mémßérs öf thé téäm "
|
||||
"ßéföré mäkïng thésé çhängés. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Search teams"
|
||||
msgstr "Séärçh téäms Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "All Topics"
|
||||
msgstr "Àll Töpïçs Ⱡ'σяєм ιρѕυм ∂σłσ#"
|
||||
@@ -2634,27 +2724,39 @@ msgid_plural "%(team_count)s Teams"
|
||||
msgstr[0] "%(team_count)s Téäm Ⱡ'σяєм ιρѕυм ∂#"
|
||||
msgstr[1] "%(team_count)s Téäms Ⱡ'σяєм ιρѕυм ∂σł#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topic_card.js
|
||||
msgid "Topic"
|
||||
msgstr "Töpïç Ⱡ'σяєм ιρѕ#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topic_card.js
|
||||
msgid "View Teams in the %(topic_name)s Topic"
|
||||
msgstr ""
|
||||
"Vïéw Téäms ïn thé %(topic_name)s Töpïç Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє#"
|
||||
|
||||
#. Translators: this string is shown at the bottom of the teams page
|
||||
#. to find a team to join or else to create a new one. There are three
|
||||
#. links that need to be included in the message:
|
||||
#. 1. Browse teams in other topics
|
||||
#. 2. search teams
|
||||
#. 3. create a new team
|
||||
#. Be careful to start each link with the appropriate start indicator
|
||||
#. (e.g. {browse_span_start} for #1) and finish it with {span_end}.
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topic_teams.js
|
||||
msgid ""
|
||||
"Try {browse_span_start}browsing all teams{span_end} or "
|
||||
"{search_span_start}searching team descriptions{span_end}. If you still can't"
|
||||
" find a team to join, {create_span_start}create a new team in this "
|
||||
"{browse_span_start}Browse teams in other topics{span_end} or "
|
||||
"{search_span_start}search teams{span_end} in this topic. If you still can't "
|
||||
"find a team to join, {create_span_start}create a new team in this "
|
||||
"topic{span_end}."
|
||||
msgstr ""
|
||||
"Trý {browse_span_start}ßröwsïng äll téäms{span_end} ör "
|
||||
"{search_span_start}séärçhïng téäm désçrïptïöns{span_end}. Ìf ýöü stïll çän't"
|
||||
" fïnd ä téäm tö jöïn, {create_span_start}çréäté ä néw téäm ïn thïs "
|
||||
"{browse_span_start}Bröwsé téäms ïn öthér töpïçs{span_end} ör "
|
||||
"{search_span_start}séärçh téäms{span_end} ïn thïs töpïç. Ìf ýöü stïll çän't "
|
||||
"fïnd ä téäm tö jöïn, {create_span_start}çréäté ä néw téäm ïn thïs "
|
||||
"töpïç{span_end}. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α∂ιριѕι¢ιηg єłιт, "
|
||||
"ѕє∂ ∂σ єιυѕмσ∂ тємρσя ιη¢ι∂ι∂υηт υт łαвσяє єт ∂σłσяє мαgηα αłιqυα. υт єηιм "
|
||||
"α∂ мιηιм νєηιαм, qυιѕ ησѕтяυ∂ єχєя¢ιтαтιση υłłαм¢σ łαвσяιѕ ηιѕι υт αłιqυιρ "
|
||||
"єχ єα ¢σммσ∂σ ¢σηѕєqυαт. ∂υιѕ αυтє ιяυяє ∂σłσя ιη яєρяєнєη∂єяιт ιη νσłυρтαтє"
|
||||
" νєłιт єѕѕє ¢ιłłυм ∂σłσяє єυ ƒυgιαт ηυłłα ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢αт "
|
||||
"¢υρι∂αтαт ηση ρяσι∂єηт, ѕυηт ιη ¢υłρα qυι σƒƒι¢ια ∂єѕєяυηт мσłłιт αηιм ι∂#"
|
||||
"¢υρι∂αтαт ηση ρяσι∂єηт, ѕυηт ιη ¢υłρα qυι σƒƒι¢ια ∂єѕєяυηт мσłłιт αη#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topics.js
|
||||
msgid "All topics"
|
||||
@@ -4343,11 +4445,6 @@ msgstr "Täké ä phötö öf ýöür ÌD Ⱡ'σяєм ιρѕυм ∂σłσя ѕ
|
||||
msgid "Review your info"
|
||||
msgstr "Révïéw ýöür ïnfö Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
|
||||
|
||||
#: lms/static/js/verify_student/views/reverify_view.js
|
||||
#: lms/templates/verify_student/review_photos_step.underscore
|
||||
msgid "Confirm"
|
||||
msgstr "Çönfïrm Ⱡ'σяєм ιρѕυм #"
|
||||
|
||||
#: lms/static/js/verify_student/views/step_view.js
|
||||
msgid "An error has occurred. Please try reloading the page."
|
||||
msgstr ""
|
||||
@@ -5730,22 +5827,6 @@ msgstr ""
|
||||
"Thé çömßïnéd léngth öf thé örgänïzätïön änd lïßrärý çödé fïélds çännöt ßé "
|
||||
"möré thän <%=limit%> çhäräçtérs. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт#"
|
||||
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
msgid "Required field."
|
||||
msgstr "Réqüïréd fïéld. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт α#"
|
||||
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
msgid "Please do not use any spaces in this field."
|
||||
msgstr ""
|
||||
"Pléäsé dö nöt üsé äný späçés ïn thïs fïéld. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
|
||||
"¢σηѕє¢тєтυя #"
|
||||
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
msgid "Please do not use any spaces or special characters in this field."
|
||||
msgstr ""
|
||||
"Pléäsé dö nöt üsé äný späçés ör spéçïäl çhäräçtérs ïn thïs fïéld. Ⱡ'σяєм "
|
||||
"ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тєтυя α#"
|
||||
|
||||
#: cms/static/js/views/utils/xblock_utils.js
|
||||
msgid "component"
|
||||
msgstr "çömpönént Ⱡ'σяєм ιρѕυм ∂σł#"
|
||||
@@ -5877,6 +5958,14 @@ msgstr ""
|
||||
"Éntér thé pägé nümßér ýöü'd lïké tö qüïçklý nävïgäté tö. Ⱡ'σяєм ιρѕυм ∂σłσя "
|
||||
"ѕιт αмєт, ¢σηѕє¢тєтυя α#"
|
||||
|
||||
#: common/static/common/templates/components/paging-header.underscore
|
||||
msgid "Sorted by"
|
||||
msgstr "Sörtéd ßý Ⱡ'σяєм ιρѕυм ∂σł#"
|
||||
|
||||
#: common/static/common/templates/components/search-field.underscore
|
||||
msgid "Clear search"
|
||||
msgstr "Çléär séärçh Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "DISCUSSION HOME:"
|
||||
msgstr "DÌSÇÛSSÌÖN HÖMÉ: Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αм#"
|
||||
@@ -6296,8 +6385,12 @@ msgstr ""
|
||||
"Régénéräté thé üsér's çértïfïçäté Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Your team could not be created!"
|
||||
msgstr "Ýöür téäm çöüld nöt ßé çréätéd! Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
|
||||
msgid "Your team could not be created."
|
||||
msgstr "Ýöür téäm çöüld nöt ßé çréätéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Your team could not be updated."
|
||||
msgstr "Ýöür téäm çöüld nöt ßé üpdätéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid ""
|
||||
@@ -6327,15 +6420,20 @@ msgstr ""
|
||||
"¢ιłłυм ∂σłσяє єυ ƒυgιαт ηυłłα ραяιαтυя. єχ¢єρт#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "{primaryButtonTitle} {span_start}a new team{span_end}"
|
||||
msgstr ""
|
||||
"{primaryButtonTitle} {span_start}ä néw téäm{span_end} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт"
|
||||
" αмєт, #"
|
||||
msgid "Create team."
|
||||
msgstr "Çréäté téäm. Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Cancel {span_start}a new team{span_end}"
|
||||
msgstr ""
|
||||
"Çänçél {span_start}ä néw téäm{span_end} Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σ#"
|
||||
msgid "Update team."
|
||||
msgstr "Ûpdäté téäm. Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Cancel team creating."
|
||||
msgstr "Çänçél téäm çréätïng. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Cancel team updating."
|
||||
msgstr "Çänçél téäm üpdätïng. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-actions.underscore
|
||||
msgid "Are you having trouble finding a team to join?"
|
||||
@@ -6343,7 +6441,7 @@ msgstr ""
|
||||
"Àré ýöü hävïng tröüßlé fïndïng ä téäm tö jöïn? Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
|
||||
"¢σηѕє¢тєтυя α#"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-join.underscore
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile-header-actions.underscore
|
||||
msgid "Join Team"
|
||||
msgstr "Jöïn Téäm Ⱡ'σяєм ιρѕυм ∂σł#"
|
||||
|
||||
@@ -7683,6 +7781,16 @@ msgstr ""
|
||||
msgid "status"
|
||||
msgstr "stätüs Ⱡ'σяєм ιρѕυ#"
|
||||
|
||||
#: cms/templates/js/add-xblock-component-button.underscore
|
||||
msgid "Add Component:"
|
||||
msgstr "Àdd Çömpönént: Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт#"
|
||||
|
||||
#: cms/templates/js/add-xblock-component-menu-problem.underscore
|
||||
#: cms/templates/js/add-xblock-component-menu.underscore
|
||||
#, python-format
|
||||
msgid "%(type)s Component Template Menu"
|
||||
msgstr "%(type)s Çömpönént Témpläté Ménü Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє#"
|
||||
|
||||
#: cms/templates/js/add-xblock-component-menu-problem.underscore
|
||||
msgid "Common Problem Types"
|
||||
msgstr "Çömmön Prößlém Týpés Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
|
||||
@@ -7761,6 +7869,11 @@ msgstr "ÌD Ⱡ'σя#"
|
||||
msgid "Certificate Details"
|
||||
msgstr "Çértïfïçäté Détäïls Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,#"
|
||||
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "Course Title"
|
||||
msgstr "Çöürsé Tïtlé Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
|
||||
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "Course Title Override"
|
||||
@@ -7807,8 +7920,8 @@ msgstr ""
|
||||
"çértïfïçätés. Léävé ßlänk tö üsé thé öffïçïäl çöürsé tïtlé. Ⱡ'σяєм #"
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "Add Signatory"
|
||||
msgstr "Àdd Sïgnätörý Ⱡ'σяєм ιρѕυм ∂σłσя ѕι#"
|
||||
msgid "Add Additional Signatory"
|
||||
msgstr "Àdd Àddïtïönäl Sïgnätörý Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢ση#"
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "(Up to 4 signatories are allowed for a certificate)"
|
||||
@@ -7816,12 +7929,6 @@ msgstr ""
|
||||
"(Ûp tö 4 sïgnätörïés äré ällöwéd för ä çértïfïçäté) Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт "
|
||||
"αмєт, ¢σηѕє¢тєтυя α#"
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
#: cms/templates/js/content-group-editor.underscore
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
msgid "Create"
|
||||
msgstr "Çréäté Ⱡ'σяєм ιρѕυ#"
|
||||
|
||||
#: cms/templates/js/certificate-web-preview.underscore
|
||||
msgid "Choose mode"
|
||||
msgstr "Çhöösé mödé Ⱡ'σяєм ιρѕυм ∂σłσя #"
|
||||
|
||||
Binary file not shown.
@@ -172,7 +172,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: edx-platform\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2015-08-21 14:18+0000\n"
|
||||
"POT-Creation-Date: 2015-09-04 14:07+0000\n"
|
||||
"PO-Revision-Date: 2015-06-29 17:10+0000\n"
|
||||
"Last-Translator: Cristian Salamea <ovnicraft@gmail.com>\n"
|
||||
"Language-Team: Spanish (Latin America) (http://www.transifex.com/open-edx/edx-platform/language/es_419/)\n"
|
||||
@@ -1413,10 +1413,6 @@ msgstr "Correcto"
|
||||
msgid "incorrect"
|
||||
msgstr "incorrecto"
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "partially correct"
|
||||
msgstr "parcialmente correcto"
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "incomplete"
|
||||
msgstr "Incompleto"
|
||||
@@ -1439,10 +1435,6 @@ msgstr "Esto es correcto."
|
||||
msgid "This is incorrect."
|
||||
msgstr "Esto es incorrecto."
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "This is partially correct."
|
||||
msgstr "Esto es parcialmente correcto."
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "This is unanswered."
|
||||
msgstr "Esto no ha sido respondido."
|
||||
@@ -5325,8 +5317,15 @@ msgid "{month} {day}, {year}"
|
||||
msgstr "{day} de {month}, {year}"
|
||||
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid "a course of study offered by {partner_name}, through {platform_name}."
|
||||
msgstr "curso ofrecido por {partner_name}, a través de {platform_name}."
|
||||
msgid ""
|
||||
"a course of study offered by {partner_short_name}, an online learning "
|
||||
"initiative of {partner_long_name} through {platform_name}."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid ""
|
||||
"a course of study offered by {partner_short_name}, through {platform_name}."
|
||||
msgstr ""
|
||||
|
||||
#. Translators: Accomplishments describe the awards/certifications obtained by
|
||||
#. students on this platform
|
||||
@@ -5440,16 +5439,14 @@ msgstr "{platform_name} reconoce el siguiente logro al estudiante"
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid ""
|
||||
"This is a valid {platform_name} certificate for {user_name}, who "
|
||||
"participated in {partner_name} {course_number}"
|
||||
"participated in {partner_short_name} {course_number}"
|
||||
msgstr ""
|
||||
"Este es un certificado válido de {platform_name} para el usuario "
|
||||
"{user_name}, quién participó en el curso {partner_name} {course_number}"
|
||||
|
||||
#. Translators: This text is bound to the HTML 'title' element of the page
|
||||
#. and appears in the browser title bar
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid "{partner_name} {course_number} Certificate | {platform_name}"
|
||||
msgstr "Certificado para {partner_name} {course_number} en {platform_name}"
|
||||
msgid "{partner_short_name} {course_number} Certificate | {platform_name}"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This text fragment appears after the student's name
|
||||
#. (displayed in a large font) on the certificate
|
||||
@@ -5616,6 +5613,14 @@ msgstr ""
|
||||
"Si su curso no aparece en el panel de control, contacte a "
|
||||
"{payment_support_link}."
|
||||
|
||||
#: lms/djangoapps/commerce/api/v1/serializers.py
|
||||
msgid "{course_id} is not a valid course key."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/commerce/api/v1/serializers.py
|
||||
msgid "Course {course_id} does not exist."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/course_wiki/tab.py lms/djangoapps/course_wiki/views.py
|
||||
#: lms/templates/wiki/base.html
|
||||
msgid "Wiki"
|
||||
@@ -6170,6 +6175,23 @@ msgstr "Nombre de usuario {user} ya existe."
|
||||
msgid "File is not attached."
|
||||
msgstr "Archivo no adjuntado."
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid "Could not find problem with this location."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid ""
|
||||
"The problem responses report is being created. To view the status of the "
|
||||
"report, see Pending Tasks below."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid ""
|
||||
"A problem responses report generation task is already in progress. Check the"
|
||||
" 'Pending Tasks' table for the status of the task. When completed, the "
|
||||
"report will be available for download in the table below."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid "Invoice number '{num}' does not exist."
|
||||
msgstr "La factura número '{num}' no existe."
|
||||
@@ -6613,6 +6635,10 @@ msgstr "El modo de curso con slug ({mode_slug}) no existe."
|
||||
msgid "CourseMode price updated successfully"
|
||||
msgstr "Se actualizó correctamente el precio para el modo de curso."
|
||||
|
||||
#: lms/djangoapps/instructor/views/instructor_dashboard.py
|
||||
msgid "No end date set"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/instructor_dashboard.py
|
||||
msgid "Enrollment data is now available in {dashboard_link}."
|
||||
msgstr "Los datos de inscripciones ya están disponibles en {dashboard_link}."
|
||||
@@ -6712,18 +6738,6 @@ msgstr "email externo"
|
||||
msgid "Grades for assignment \"{name}\""
|
||||
msgstr "Calificaciones para la tarea \"{name}\""
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Found {num} records to dump."
|
||||
msgstr "Se encontraron {num} registros para exportar."
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Couldn't find module with that urlname."
|
||||
msgstr "No se ha encontrado ningún módulo con esa url."
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Student state for problem {problem}"
|
||||
msgstr "Estado del estudiante para el problema {problem}"
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Grades from {course_id}"
|
||||
msgstr "Calificaciones de {course_id}"
|
||||
@@ -6903,6 +6917,12 @@ msgstr "borrado"
|
||||
msgid "emailed"
|
||||
msgstr "enviado al correo electrónico"
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
msgid "generated"
|
||||
msgstr "generado"
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
@@ -6915,12 +6935,6 @@ msgstr "calificado"
|
||||
msgid "problem distribution graded"
|
||||
msgstr "Distribución de calificaciones del problema"
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
msgid "generated"
|
||||
msgstr "generado"
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
@@ -8607,12 +8621,12 @@ msgid "course_id must be provided"
|
||||
msgstr "Debe suministrar un ID de curso"
|
||||
|
||||
#: lms/djangoapps/teams/views.py
|
||||
msgid "The supplied topic id {topic_id} is not valid"
|
||||
msgstr "El ID de tema proporcionado {topic_id} no es válido"
|
||||
msgid "text_search and order_by cannot be provided together"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/views.py
|
||||
msgid "text_search is not yet supported."
|
||||
msgstr "text_search actualmente no está soportado"
|
||||
msgid "The supplied topic id {topic_id} is not valid"
|
||||
msgstr "El ID de tema proporcionado {topic_id} no es válido"
|
||||
|
||||
#. Translators: 'ordering' is a string describing a way
|
||||
#. of ordering a list. For example, {ordering} may be
|
||||
@@ -10466,6 +10480,10 @@ msgstr "Ayuda"
|
||||
msgid "Sign Out"
|
||||
msgstr "Cerrar sesión"
|
||||
|
||||
#: common/lib/capa/capa/templates/codeinput.html
|
||||
msgid "{programming_language} editor"
|
||||
msgstr ""
|
||||
|
||||
#: common/templates/license.html
|
||||
msgid "All Rights Reserved"
|
||||
msgstr "Todos los Derechos Reservados"
|
||||
@@ -13181,8 +13199,10 @@ msgid "Section:"
|
||||
msgstr "Sección:"
|
||||
|
||||
#: lms/templates/courseware/legacy_instructor_dashboard.html
|
||||
msgid "Problem urlname:"
|
||||
msgstr "urlname del problema:"
|
||||
msgid ""
|
||||
"To download a CSV listing student responses to a given problem, visit the "
|
||||
"Data Download section of the Instructor Dashboard."
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/courseware/legacy_instructor_dashboard.html
|
||||
msgid ""
|
||||
@@ -15244,6 +15264,20 @@ msgstr ""
|
||||
msgid "Generate Proctored Exam Results Report"
|
||||
msgstr "Generar reporte de resultados para examenes supervisados"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid ""
|
||||
"To generate a CSV file that lists all student answers to a given problem, "
|
||||
"enter the location of the problem (from its Staff Debug Info)."
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid "Problem location: "
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid "Download a CSV of problem responses"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid ""
|
||||
"For smaller courses, click to list profile information for enrolled students"
|
||||
@@ -17851,67 +17885,51 @@ msgid "This module is not enabled."
|
||||
msgstr "Este módulo no está habilitado."
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"Upon successful completion of your course, learners receive a certificate to"
|
||||
" acknowledge their accomplishment. If you are a course team member with the "
|
||||
"Admin role in Studio, you can configure your course certificate."
|
||||
msgid "Working with Certificates"
|
||||
msgstr ""
|
||||
"Al completar con éxito el curso, los alumnos reciben un certificado para "
|
||||
"reconocer su logro. Si usted es un miembro del equipo de curso con el rol de"
|
||||
" administrador en Studio, puede configurar los certificados del curso."
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"Click {em_start}Add your first certificate{em_end} to add a certificate "
|
||||
"configuration. Upload the organization logo to be used on the certificate, "
|
||||
"and specify at least one signatory. You can include up to four signatories "
|
||||
"for a certificate. You can also upload a signature image file for each "
|
||||
"signatory. {em_start}Note:{em_end} Signature images are used only for "
|
||||
"verified certificates. Optionally, specify a different course title to use "
|
||||
"on your course certificate. You might want to use a different title if, for "
|
||||
"example, the official course name is too long to display well on a "
|
||||
"certificate."
|
||||
"Specify a course title to use on the certificate if the course's official "
|
||||
"title is too long to be displayed well."
|
||||
msgstr ""
|
||||
"Haga clic en {em_start}Agregar su primer certificado{em_end} para agregar "
|
||||
"una configuración de certificados. Cargue el logotipo de la organización "
|
||||
"para ser utilizado en el certificado, y especifique al menos un signatario. "
|
||||
"Puede incluir hasta cuatro firmantes de un certificado. También puede cargar"
|
||||
" un archivo de imagen de la firma de cada signatario. "
|
||||
"{em_start}Nota:{em_end} Las imágenes de la firma sólo se utilizan para los "
|
||||
"certificados verificados. Opcionalmente, especifique un título de curso "
|
||||
"diferente a utilizar en su certificado. Es posible que desee utilizar un "
|
||||
"título diferente si, por ejemplo, el nombre oficial del curso es demasiado "
|
||||
"largo para que aparezca completo en el certificado."
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"Select a course mode and click {em_start}Preview Certificate{em_end} to "
|
||||
"preview the certificate that a learner in the selected enrollment track "
|
||||
"would receive. When the certificate is ready for issuing, click "
|
||||
"{em_start}Activate.{em_end} To stop issuing an active certificate, click "
|
||||
"{em_start}Deactivate{em_end}."
|
||||
"For verified certificates, specify between one and four signatories and "
|
||||
"upload the associated images."
|
||||
msgstr ""
|
||||
"Seleccione un modo de curso y haga clic en {em_start}Vista previa de "
|
||||
"Certificado{em_end} para previsualizar el certificado que un estudiante en "
|
||||
"el modo de curso seleccionado recibiría. Cuando el certificado esté listo "
|
||||
"para la expedición, haga clic {em_start}Activar{em_end}. Para detener la "
|
||||
"emisión de un certificado activo, haga clic en {em_start}Desactivar{em_end}."
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
" To edit the certificate configuration, hover over the top right corner of "
|
||||
"the form and click {em_start}Edit{em_end}. To delete a certificate, hover "
|
||||
"over the top right corner of the form and click the delete icon. In general,"
|
||||
" do not delete certificates after a course has started, because some "
|
||||
"certificates might already have been issued to learners."
|
||||
"To edit or delete a certificate before it is activated, hover over the top "
|
||||
"right corner of the form and select {em_start}Edit{em_end} or the delete "
|
||||
"icon."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"To view a sample certificate, choose a course mode and select "
|
||||
"{em_start}Preview Certificate{em_end}."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid "Issuing Certificates to Learners"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"To begin issuing certificates, a course team member with the Admin role "
|
||||
"selects {em_start}Activate{em_end}. Course team members without the Admin "
|
||||
"role cannot edit or delete an activated certificate."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"{em_start}Do not{em_end} delete certificates after a course has started; "
|
||||
"learners who have already earned certificates will no longer be able to "
|
||||
"access them."
|
||||
msgstr ""
|
||||
"Para editar la configuración del certificado, pase el puntero sobre la "
|
||||
"esquina superior derecha del formulario y haga clic en "
|
||||
"{em_start}Editar{em_end}. Para eliminar un certificado, pase el puntero "
|
||||
"sobre la esquina superior derecha del formulario y haga clic en el icono de "
|
||||
"eliminación. En general, no elimine los certificados después de que un curso"
|
||||
" haya iniciado, debido a que algunos certificados pueden ya haber sido "
|
||||
"emitidos a los alumnos."
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid "Learn more about certificates"
|
||||
|
||||
Binary file not shown.
@@ -25,6 +25,7 @@
|
||||
# Lalo Cabrera <laloogcabrera@yahoo.com.mx>, 2014
|
||||
# Luis Ricardo Ruiz <luislicardo1307@gmail.com>, 2013
|
||||
# Luis Ricardo Ruiz <luislicardo1307@gmail.com>, 2013
|
||||
# Mecabotware <mecabotware.ideas@gmail.com>, 2015
|
||||
# Natalia, 2013
|
||||
# Natalia, 2013-2014
|
||||
# Nuri Plans Toral <nplans@gmail.com>, 2015
|
||||
@@ -63,6 +64,7 @@
|
||||
# This file is distributed under the GNU AFFERO GENERAL PUBLIC LICENSE.
|
||||
#
|
||||
# Translators:
|
||||
# Claudio Anibal Barahona Flores <claudio.barahona@unah.edu.hn>, 2015
|
||||
# Cristian Salamea <ovnicraft@gmail.com>, 2014-2015
|
||||
# Giancarlo De Agostini <giancarlo.deagostini@iaen.edu.ec>, 2015
|
||||
# Jonathan Amaya <jonathan.amaya88@yahoo.com>, 2014
|
||||
@@ -70,6 +72,7 @@
|
||||
# Juan Camilo Montoya Franco <juan.montoya@edunext.co>, 2014
|
||||
# Juan Fernando Villa <elite.linux@gmail.com>, 2015
|
||||
# Juan <juan.marrero@utec.edu.uy>, 2015
|
||||
# Mecabotware <mecabotware.ideas@gmail.com>, 2015
|
||||
# Nuri Plans Toral <nplans@gmail.com>, 2014
|
||||
# Patricia Colmenares <patrusca38@hotmail.com>, 2015
|
||||
# paul ochoa <palichis@solid-ec.org>, 2015
|
||||
@@ -89,14 +92,15 @@
|
||||
# Juan Camilo Montoya Franco <juan.montoya@edunext.co>, 2014
|
||||
# Juan <juan.marrero@utec.edu.uy>, 2015
|
||||
# karlman72 <karlman72@gmail.com>, 2014
|
||||
# Leandro Bohnhoff <leandro.bohnhoff@gmail.com>, 2015
|
||||
# Patricia Colmenares <patrusca38@hotmail.com>, 2015
|
||||
# UAbierta Universidad de Chile <uabierta@u.uchile.cl>, 2015
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: edx-platform\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2015-08-21 14:17+0000\n"
|
||||
"PO-Revision-Date: 2015-08-21 02:41+0000\n"
|
||||
"POT-Creation-Date: 2015-09-04 14:06+0000\n"
|
||||
"PO-Revision-Date: 2015-09-04 14:08+0000\n"
|
||||
"Last-Translator: Sarina Canelake <sarina@edx.org>\n"
|
||||
"Language-Team: Spanish (Latin America) (http://www.transifex.com/open-edx/edx-platform/language/es_419/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -142,8 +146,8 @@ msgstr "Aceptar"
|
||||
#: cms/static/js/views/show_textbook.js cms/static/js/views/validation.js
|
||||
#: cms/static/js/views/modals/base_modal.js
|
||||
#: cms/static/js/views/modals/course_outline_modals.js
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
#: cms/templates/js/add-xblock-component-menu-problem.underscore
|
||||
#: cms/templates/js/add-xblock-component-menu.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
@@ -154,6 +158,11 @@ msgstr "Aceptar"
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
#: cms/templates/js/section-name-edit.underscore
|
||||
#: cms/templates/js/xblock-string-field-editor.underscore
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
#: common/static/common/templates/discussion/response-comment-edit.underscore
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
#: common/static/common/templates/discussion/thread-response-edit.underscore
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
#: lms/templates/instructor/instructor_dashboard_2/cohort-form.underscore
|
||||
msgid "Cancel"
|
||||
msgstr "Cancelar"
|
||||
@@ -163,17 +172,6 @@ msgstr "Cancelar"
|
||||
#: cms/static/js/views/manage_users_and_roles.js
|
||||
#: cms/static/js/views/show_textbook.js
|
||||
#: common/static/js/vendor/ova/catch/js/catch.js
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
#: cms/templates/js/content-group-details.underscore
|
||||
#: cms/templates/js/content-group-editor.underscore
|
||||
#: cms/templates/js/course-outline.underscore
|
||||
#: cms/templates/js/course_grade_policy.underscore
|
||||
#: cms/templates/js/group-configuration-details.underscore
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
#: cms/templates/js/show-textbook.underscore
|
||||
#: cms/templates/js/signatory-editor.underscore
|
||||
#: cms/templates/js/xblock-outline.underscore
|
||||
msgid "Delete"
|
||||
msgstr "Borrar"
|
||||
|
||||
@@ -248,12 +246,10 @@ msgstr "Error"
|
||||
msgid "Save"
|
||||
msgstr "Guardar"
|
||||
|
||||
#. #-#-#-#-# djangojs-partial.po (edx-platform) #-#-#-#-#
|
||||
#. Translators: this is a message from the raw HTML editor displayed in the
|
||||
#. browser when a user needs to edit HTML
|
||||
#: cms/static/js/views/modals/edit_xblock.js
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: cms/templates/js/signatory-editor.underscore
|
||||
msgid "Close"
|
||||
msgstr "Cerrar"
|
||||
|
||||
@@ -346,6 +342,8 @@ msgstr ""
|
||||
|
||||
#: common/lib/xmodule/xmodule/js/src/combinedopenended/display.js
|
||||
#: lms/static/coffee/src/staff_grading/staff_grading.js
|
||||
#: common/static/common/templates/discussion/thread-response.underscore
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
#: lms/templates/verify_student/incourse_reverify.underscore
|
||||
msgid "Submit"
|
||||
msgstr "Enviar"
|
||||
@@ -780,18 +778,10 @@ msgstr "Propiedades del documento"
|
||||
msgid "Edit HTML"
|
||||
msgstr "Editar HTML"
|
||||
|
||||
#. #-#-#-#-# djangojs-partial.po (edx-platform) #-#-#-#-#
|
||||
#. Translators: this is a message from the raw HTML editor displayed in the
|
||||
#. browser when a user needs to edit HTML
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: common/static/js/vendor/ova/catch/js/catch.js
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/content-group-details.underscore
|
||||
#: cms/templates/js/course_info_handouts.underscore
|
||||
#: cms/templates/js/group-configuration-details.underscore
|
||||
#: cms/templates/js/show-textbook.underscore
|
||||
#: cms/templates/js/signatory-details.underscore
|
||||
#: cms/templates/js/xblock-string-field-editor.underscore
|
||||
msgid "Edit"
|
||||
msgstr "Editar"
|
||||
|
||||
@@ -1192,11 +1182,9 @@ msgstr "Documento nuevo"
|
||||
msgid "New window"
|
||||
msgstr "Nueva ventana"
|
||||
|
||||
#. #-#-#-#-# djangojs-partial.po (edx-platform) #-#-#-#-#
|
||||
#. Translators: this is a message from the raw HTML editor displayed in the
|
||||
#. browser when a user needs to edit HTML
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: cms/templates/js/paging-header.underscore
|
||||
msgid "Next"
|
||||
msgstr "Siguiente"
|
||||
|
||||
@@ -1546,12 +1534,9 @@ msgstr ""
|
||||
"La URL que introdujo parece ser un vínculo externo. ¿Desea agregarle el "
|
||||
"prefijo requerido http://?"
|
||||
|
||||
#. #-#-#-#-# djangojs-partial.po (edx-platform) #-#-#-#-#
|
||||
#. Translators: this is a message from the raw HTML editor displayed in the
|
||||
#. browser when a user needs to edit HTML
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: cms/templates/js/signatory-details.underscore
|
||||
#: cms/templates/js/signatory-editor.underscore
|
||||
msgid "Title"
|
||||
msgstr "Título"
|
||||
|
||||
@@ -2163,6 +2148,18 @@ msgstr ""
|
||||
msgid "Are you sure you want to delete this response?"
|
||||
msgstr "¿Está seguro de que desea borrar esta respuesta?"
|
||||
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
msgid "Required field."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
msgid "Please do not use any spaces in this field."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
msgid "Please do not use any spaces or special characters in this field."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/js/components/views/paging_header.js
|
||||
msgid "Showing %(first_index)s out of %(num_items)s total"
|
||||
msgstr "Mostrando %(first_index)s de un total de %(num_items)s "
|
||||
@@ -2329,6 +2326,7 @@ msgstr "Fecha de publicación"
|
||||
|
||||
#: common/static/js/vendor/ova/catch/js/catch.js
|
||||
#: lms/static/js/courseware/credit_progress.js
|
||||
#: common/static/common/templates/discussion/forum-actions.underscore
|
||||
#: lms/templates/discovery/facet.underscore
|
||||
#: lms/templates/edxnotes/note-item.underscore
|
||||
msgid "More"
|
||||
@@ -2408,21 +2406,34 @@ msgid "An unexpected error occurred. Please try again."
|
||||
msgstr "Se produjo un error inesperado. Por favor, inténtelo nuevamente."
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/team.js
|
||||
msgid "last activity"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/team.js
|
||||
msgid "open slots"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/topic.js
|
||||
#: lms/templates/edxnotes/tab-item.underscore
|
||||
msgid "name"
|
||||
msgstr "nombre"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/team.js
|
||||
msgid "open_slots"
|
||||
msgstr "open_slots"
|
||||
|
||||
#. Translators: This refers to the number of teams (a count of how many teams
|
||||
#. there are)
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/topic.js
|
||||
msgid "team count"
|
||||
msgstr "Cantidad de equipos"
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
#: cms/templates/js/content-group-editor.underscore
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
msgid "Create"
|
||||
msgstr "Crear"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
msgid "Update"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
msgid "Team Name (Required) *"
|
||||
msgstr "Nombre del equipo (Requerido) *"
|
||||
@@ -2491,20 +2502,48 @@ msgstr "La descripción no puede tener más de 300 caracteres."
|
||||
msgid "You are not currently a member of any team."
|
||||
msgstr "Usted no es actualmente miembro de ningún equipo."
|
||||
|
||||
#. Translators: "and others" refers to fact that additional members of a team
|
||||
#. exist that are not displayed.
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_card.js
|
||||
msgid "and others"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: 'date' is a placeholder for a fuzzy, relative timestamp (see:
|
||||
#. https://github.com/rmm5t/jquery-timeago)
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_card.js
|
||||
msgid "Last Activity %(date)s"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_card.js
|
||||
msgid "View %(span_start)s %(team_name)s %(span_end)s"
|
||||
msgstr "Ver %(span_start)s %(team_name)s %(span_end)s"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_join.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile_header_actions.js
|
||||
msgid "An error occurred. Try again."
|
||||
msgstr "Ocurrió un error. Intente nuevamente."
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_join.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
msgid "Leave this team?"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
msgid ""
|
||||
"If you leave, you can no longer post in this team's discussions. Your place "
|
||||
"will be available to another learner."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
#: lms/static/js/verify_student/views/reverify_view.js
|
||||
#: lms/templates/verify_student/review_photos_step.underscore
|
||||
msgid "Confirm"
|
||||
msgstr "Confirmar"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile_header_actions.js
|
||||
msgid "You already belong to another team."
|
||||
msgstr "Usted ya pertenece a otro equipo."
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_join.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile_header_actions.js
|
||||
msgid "This team is full."
|
||||
msgstr "Este equipo está lleno."
|
||||
|
||||
@@ -2522,6 +2561,10 @@ msgstr "Todos los equipos"
|
||||
msgid "teams"
|
||||
msgstr "equipos"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Teams"
|
||||
msgstr "Equipos"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"See all teams in your course, organized by topic. Join a team to collaborate"
|
||||
@@ -2530,33 +2573,52 @@ msgstr ""
|
||||
"Revise los equipos de su curso, organizados por tema. Únase a un equipo para"
|
||||
" colaborar con otros que estén interesados en los mismos temas."
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Teams"
|
||||
msgstr "Equipos"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "My Team"
|
||||
msgstr "Mi equipo"
|
||||
|
||||
#. Translators: sr_start and sr_end surround text meant only for screen
|
||||
#. readers. The whole string will be shown to users as "Browse teams" if they
|
||||
#. are using a screenreader, and "Browse" otherwise.
|
||||
#. readers.
|
||||
#. The whole string will be shown to users as "Browse teams" if they are using
|
||||
#. a
|
||||
#. screenreader, and "Browse" otherwise.
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Browse %(sr_start)s teams %(sr_end)s"
|
||||
msgstr "Explorar %(sr_start)s equpos %(sr_end)s"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"Create a new team if you can't find existing teams to join, or if you would "
|
||||
"like to learn with friends you know."
|
||||
msgid "Team Search"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Showing results for \"%(searchString)s\""
|
||||
msgstr ""
|
||||
"Cree un nuevo equipo si no puede encontrar uno existente para unirse o si "
|
||||
"desea aprender con personas que ya conoce."
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Create a New Team"
|
||||
msgstr "Crear un nuevo equipo"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"Create a new team if you can't find an existing team to join, or if you "
|
||||
"would like to learn with friends you know."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile-header-actions.underscore
|
||||
msgid "Edit Team"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"If you make significant changes, make sure you notify members of the team "
|
||||
"before making these changes."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Search teams"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "All Topics"
|
||||
msgstr "Todos los temas"
|
||||
@@ -2579,21 +2641,29 @@ msgid_plural "%(team_count)s Teams"
|
||||
msgstr[0] "%(team_count)s Equipo"
|
||||
msgstr[1] "%(team_count)s Equipos"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topic_card.js
|
||||
msgid "Topic"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topic_card.js
|
||||
msgid "View Teams in the %(topic_name)s Topic"
|
||||
msgstr "Ver equipos en el tema %(topic_name)s"
|
||||
|
||||
#. Translators: this string is shown at the bottom of the teams page
|
||||
#. to find a team to join or else to create a new one. There are three
|
||||
#. links that need to be included in the message:
|
||||
#. 1. Browse teams in other topics
|
||||
#. 2. search teams
|
||||
#. 3. create a new team
|
||||
#. Be careful to start each link with the appropriate start indicator
|
||||
#. (e.g. {browse_span_start} for #1) and finish it with {span_end}.
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topic_teams.js
|
||||
msgid ""
|
||||
"Try {browse_span_start}browsing all teams{span_end} or "
|
||||
"{search_span_start}searching team descriptions{span_end}. If you still can't"
|
||||
" find a team to join, {create_span_start}create a new team in this "
|
||||
"{browse_span_start}Browse teams in other topics{span_end} or "
|
||||
"{search_span_start}search teams{span_end} in this topic. If you still can't "
|
||||
"find a team to join, {create_span_start}create a new team in this "
|
||||
"topic{span_end}."
|
||||
msgstr ""
|
||||
"Intente {browse_span_start}explorar todos los equipos{span_end} o "
|
||||
"{search_span_start}buscar descripciones de equipos{span_end}. Sí aún no "
|
||||
"puede encontrar un equipo para unirse, {create_span_start}cree un nuevo "
|
||||
"equipo en este tema{span_end}."
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topics.js
|
||||
msgid "All topics"
|
||||
@@ -4082,11 +4152,6 @@ msgstr "Tome una foto de su ID"
|
||||
msgid "Review your info"
|
||||
msgstr "Revise su información"
|
||||
|
||||
#: lms/static/js/verify_student/views/reverify_view.js
|
||||
#: lms/templates/verify_student/review_photos_step.underscore
|
||||
msgid "Confirm"
|
||||
msgstr "Confirmar"
|
||||
|
||||
#: lms/static/js/verify_student/views/step_view.js
|
||||
msgid "An error has occurred. Please try reloading the page."
|
||||
msgstr "Ocurrió un error. Por favor, intente recargar la página."
|
||||
@@ -4680,7 +4745,7 @@ msgstr "Su archivo ha sido borrado."
|
||||
msgid "Date Added"
|
||||
msgstr "Fecha añadida"
|
||||
|
||||
#: cms/static/js/views/assets.js cms/templates/js/asset-library.underscore
|
||||
#: cms/static/js/views/assets.js
|
||||
msgid "Type"
|
||||
msgstr "Escribir"
|
||||
|
||||
@@ -5291,19 +5356,6 @@ msgstr ""
|
||||
"La longitud combinada de los campos para la organización y código de la "
|
||||
"librería no puede superar los <%=limit%> caracteres."
|
||||
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
msgid "Required field."
|
||||
msgstr "Campo requerido."
|
||||
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
msgid "Please do not use any spaces in this field."
|
||||
msgstr "Por favor, no usar espacios o caracteres especiales en este campo."
|
||||
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
msgid "Please do not use any spaces or special characters in this field."
|
||||
msgstr ""
|
||||
"Por favor, no utilizar espacios o caracteres especiales en este campo."
|
||||
|
||||
#: cms/static/js/views/utils/xblock_utils.js
|
||||
msgid "component"
|
||||
msgstr "componente"
|
||||
@@ -5396,11 +5448,526 @@ msgstr "Acciones"
|
||||
msgid "Due Date"
|
||||
msgstr "Fecha límite de entrega"
|
||||
|
||||
#: cms/templates/js/paging-header.underscore
|
||||
#: common/static/common/templates/components/paging-footer.underscore
|
||||
#: common/static/common/templates/discussion/pagination.underscore
|
||||
msgid "Previous"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/previous-video-upload-list.underscore
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
#: lms/templates/verify_student/enrollment_confirmation_step.underscore
|
||||
msgid "Status"
|
||||
msgstr "Estado"
|
||||
|
||||
#: common/static/common/templates/image-modal.underscore
|
||||
msgid "Large"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/image-modal.underscore
|
||||
msgid "Zoom In"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/image-modal.underscore
|
||||
msgid "Zoom Out"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/paging-footer.underscore
|
||||
msgid "Page number"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/paging-footer.underscore
|
||||
msgid "Enter the page number you'd like to quickly navigate to."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/paging-header.underscore
|
||||
msgid "Sorted by"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/search-field.underscore
|
||||
msgid "Clear search"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "DISCUSSION HOME:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
#: lms/templates/commerce/provider.underscore
|
||||
#: lms/templates/commerce/receipt.underscore
|
||||
#: lms/templates/discovery/course_card.underscore
|
||||
msgid "gettext("
|
||||
msgstr "gettext("
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Find discussions"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Focus in on specific topics"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Search for specific posts"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Sort by date, vote, or comments"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Engage with posts"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Upvote posts and good responses"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Report Forum Misuse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Follow posts for updates"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Receive updates"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Toggle Notifications Setting"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid ""
|
||||
"Check this box to receive an email digest once a day notifying you about "
|
||||
"new, unread activity from posts you are following."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-answer.underscore
|
||||
msgid "Mark as Answer"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-answer.underscore
|
||||
msgid "Unmark as Answer"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-close.underscore
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-endorse.underscore
|
||||
msgid "Endorse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-endorse.underscore
|
||||
msgid "Unendorse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-follow.underscore
|
||||
msgid "Follow"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-follow.underscore
|
||||
msgid "Unfollow"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-pin.underscore
|
||||
msgid "Pin"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-pin.underscore
|
||||
msgid "Unpin"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-report.underscore
|
||||
msgid "Report abuse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-report.underscore
|
||||
msgid "Report"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-report.underscore
|
||||
msgid "Unreport"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-vote.underscore
|
||||
msgid "Vote for this post,"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Visible To:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "All Groups"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid ""
|
||||
"Discussion admins, moderators, and TAs can make their posts visible to all "
|
||||
"students or specify a single cohort."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Title:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Add a clear and descriptive title to encourage participation."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Enter your question or comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "follow this post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "post anonymously"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "post anonymously to classmates"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Add Post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/post-user-display.underscore
|
||||
msgid "Community TA"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/profile-thread.underscore
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "This thread is closed."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/profile-thread.underscore
|
||||
msgid "View discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-edit.underscore
|
||||
msgid "Editing comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-edit.underscore
|
||||
msgid "Update comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-show.underscore
|
||||
#, python-format
|
||||
msgid "posted %(time_ago)s by %(author)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-show.underscore
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "Reported"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
msgid "Editing post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
msgid "Edit post title"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
msgid "Update post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "answered question"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "unanswered question"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "Pinned"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "Following"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "By: Staff"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "By: Community TA"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
msgid "fmt"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(comments_count)s %(span_sr_open)scomments (%(unread_comments_count)s "
|
||||
"unread comments)%(span_close)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#, python-format
|
||||
msgid "%(comments_count)s %(span_sr_open)scomments %(span_close)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-edit.underscore
|
||||
msgid "Editing response"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-edit.underscore
|
||||
msgid "Update response"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "marked as answer %(time_ago)s by %(user)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "marked as answer %(time_ago)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "endorsed %(time_ago)s by %(user)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "endorsed %(time_ago)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response.underscore
|
||||
msgid "fmts"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response.underscore
|
||||
msgid "Add a comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
#, python-format
|
||||
msgid "This post is visible only to %(group_name)s."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "This post is visible to everyone."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
#, python-format
|
||||
msgid "%(post_type)s posted %(time_ago)s by %(author)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "Closed"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
#, python-format
|
||||
msgid "Related to: %(courseware_title_linked)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid "Post type:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid "Question"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid "Discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid ""
|
||||
"Questions raise issues that need answers. Discussions share ideas and start "
|
||||
"conversations."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Add a Response"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Post a response:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Expand discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Collapse discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Topic Area:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Discussion topics; current selection is:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Filter topics"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Add your post to a relevant topic to help others find it."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/user-profile.underscore
|
||||
msgid "Active Threads"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates.underscore
|
||||
msgid "username or email"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "No results"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Course Key"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Download URL"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Grade"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Last Updated"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Download the user's certificate"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Not available"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Regenerate"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Regenerate the user's certificate"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Your team could not be created."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Your team could not be updated."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid ""
|
||||
"Enter information to describe your team. You cannot change these details "
|
||||
"after you create the team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Optional Characteristics"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid ""
|
||||
"Help other learners decide whether to join your team by specifying some "
|
||||
"characteristics for your team. Choose carefully, because fewer people might "
|
||||
"be interested in joining your team if it seems too restrictive."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Create team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Update team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Cancel team creating."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Cancel team updating."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-actions.underscore
|
||||
msgid "Are you having trouble finding a team to join?"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile-header-actions.underscore
|
||||
msgid "Join Team"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "New Post"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Team Details"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "You are a member of this team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Team member profiles"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Team capacity"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "country"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "language"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Leave Team"
|
||||
msgstr ""
|
||||
|
||||
#: lms/static/js/fixtures/donation.underscore
|
||||
#: lms/templates/dashboard/donation.underscore
|
||||
msgid "Donate"
|
||||
msgstr "Donar"
|
||||
|
||||
#: lms/templates/ccx/schedule.underscore
|
||||
msgid "Expand All"
|
||||
msgstr "Expandir todo"
|
||||
@@ -5441,12 +6008,6 @@ msgstr "Mover Subsección"
|
||||
msgid "Subsection"
|
||||
msgstr "Subsección"
|
||||
|
||||
#: lms/templates/commerce/provider.underscore
|
||||
#: lms/templates/commerce/receipt.underscore
|
||||
#: lms/templates/discovery/course_card.underscore
|
||||
msgid "gettext("
|
||||
msgstr "gettext("
|
||||
|
||||
#: lms/templates/commerce/provider.underscore
|
||||
#, python-format
|
||||
msgid "<img src='%s' alt='%s'></image>"
|
||||
@@ -5543,10 +6104,6 @@ msgstr "Marcar el examen como completado"
|
||||
msgid "End My Exam"
|
||||
msgstr "Terminar mi examen"
|
||||
|
||||
#: lms/templates/dashboard/donation.underscore
|
||||
msgid "Donate"
|
||||
msgstr "Donar"
|
||||
|
||||
#: lms/templates/discovery/course_card.underscore
|
||||
msgid "LEARN MORE"
|
||||
msgstr "APRENDER MAS"
|
||||
@@ -6572,6 +7129,16 @@ msgstr "Arrastre y suelte o pulse aquí para subir ficheros de vídeo."
|
||||
msgid "status"
|
||||
msgstr "estado"
|
||||
|
||||
#: cms/templates/js/add-xblock-component-button.underscore
|
||||
msgid "Add Component:"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/add-xblock-component-menu-problem.underscore
|
||||
#: cms/templates/js/add-xblock-component-menu.underscore
|
||||
#, python-format
|
||||
msgid "%(type)s Component Template Menu"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/add-xblock-component-menu-problem.underscore
|
||||
msgid "Common Problem Types"
|
||||
msgstr "Tipos de problemas comunes"
|
||||
@@ -6646,6 +7213,11 @@ msgstr "ID"
|
||||
msgid "Certificate Details"
|
||||
msgstr "Detalles del certificado"
|
||||
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "Course Title"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "Course Title Override"
|
||||
@@ -6692,19 +7264,13 @@ msgstr ""
|
||||
" en los certificados. Dejar vacío para utilizar el título oficial del curso."
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "Add Signatory"
|
||||
msgstr "Añadir signatario"
|
||||
msgid "Add Additional Signatory"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "(Up to 4 signatories are allowed for a certificate)"
|
||||
msgstr "(Se permiten hasta 4 signatarios por certificado)"
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
#: cms/templates/js/content-group-editor.underscore
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
msgid "Create"
|
||||
msgstr "Crear"
|
||||
|
||||
#: cms/templates/js/certificate-web-preview.underscore
|
||||
msgid "Choose mode"
|
||||
msgstr "Elegir modo"
|
||||
@@ -7142,10 +7708,6 @@ msgstr "No ha añadido aún ningún libro de texto a este curso."
|
||||
msgid "Add your first textbook"
|
||||
msgstr "Añada su primer libro de texto"
|
||||
|
||||
#: cms/templates/js/paging-header.underscore
|
||||
msgid "Previous"
|
||||
msgstr "Anterior"
|
||||
|
||||
#: cms/templates/js/previous-video-upload-list.underscore
|
||||
msgid "Previous Uploads"
|
||||
msgstr "Subidas anteriores"
|
||||
|
||||
Binary file not shown.
@@ -178,7 +178,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: edx-platform\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2015-08-21 14:18+0000\n"
|
||||
"POT-Creation-Date: 2015-09-04 14:07+0000\n"
|
||||
"PO-Revision-Date: 2015-06-19 17:16+0000\n"
|
||||
"Last-Translator: Xavier Antoviaque <xavier@antoviaque.org>\n"
|
||||
"Language-Team: French (http://www.transifex.com/open-edx/edx-platform/language/fr/)\n"
|
||||
@@ -340,6 +340,7 @@ msgstr "Cours"
|
||||
msgid "Display Name"
|
||||
msgstr "Nom d'affichage"
|
||||
|
||||
#: common/djangoapps/course_modes/models.py
|
||||
#: lms/templates/courseware/course_about.html
|
||||
msgid "Price"
|
||||
msgstr "Prix"
|
||||
@@ -471,7 +472,7 @@ msgstr "Message à afficher lorsque l'utilisateur est bloqué a l'inscription."
|
||||
|
||||
#: common/djangoapps/embargo/models.py
|
||||
msgid "The message to show when a user is blocked from accessing a course."
|
||||
msgstr ""
|
||||
msgstr "Message à afficher lorsqu'un utilisateur a un accès au cours bloqué."
|
||||
|
||||
#: common/djangoapps/embargo/models.py
|
||||
msgid ""
|
||||
@@ -635,7 +636,7 @@ msgstr "Diplôme de premier cycle supérieur"
|
||||
|
||||
#: common/djangoapps/student/models.py
|
||||
msgid "Associate degree"
|
||||
msgstr ""
|
||||
msgstr "Niveau associé"
|
||||
|
||||
#: common/djangoapps/student/models.py
|
||||
msgid "Secondary/high school"
|
||||
@@ -658,15 +659,15 @@ msgstr "Aucun"
|
||||
|
||||
#: common/djangoapps/student/models.py
|
||||
msgid "{platform_name} Honor Code Certificate for {course_name}"
|
||||
msgstr ""
|
||||
msgstr "{platform_name} Certificat sur l'honneur pour {course_name}"
|
||||
|
||||
#: common/djangoapps/student/models.py
|
||||
msgid "{platform_name} Verified Certificate for {course_name}"
|
||||
msgstr ""
|
||||
msgstr "{platform_name} Certificat Vérifié pour {course_name}"
|
||||
|
||||
#: common/djangoapps/student/models.py
|
||||
msgid "{platform_name} Professional Certificate for {course_name}"
|
||||
msgstr ""
|
||||
msgstr "{platform_name} Certificat professionnel {course_name}"
|
||||
|
||||
#: common/djangoapps/student/models.py
|
||||
msgid ""
|
||||
@@ -683,7 +684,7 @@ msgstr ""
|
||||
|
||||
#: common/djangoapps/student/models.py
|
||||
msgid "{platform_name} Certificate for {course_name}"
|
||||
msgstr ""
|
||||
msgstr "{platform_name} Certificat pour {course_name}"
|
||||
|
||||
#: common/djangoapps/student/models.py
|
||||
msgid "The ISO 639-1 language code for this language."
|
||||
@@ -1371,10 +1372,6 @@ msgstr "correct"
|
||||
msgid "incorrect"
|
||||
msgstr "incorrect"
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "partially correct"
|
||||
msgstr ""
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "incomplete"
|
||||
msgstr "incomplet"
|
||||
@@ -1397,10 +1394,6 @@ msgstr "Ceci est correct."
|
||||
msgid "This is incorrect."
|
||||
msgstr "Ceci est incorrect."
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "This is partially correct."
|
||||
msgstr ""
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "This is unanswered."
|
||||
msgstr ""
|
||||
@@ -1455,7 +1448,7 @@ msgstr ""
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "Error running code."
|
||||
msgstr ""
|
||||
msgstr "Erreur lors de l'exécution du code."
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "Cannot connect to the queue"
|
||||
@@ -2325,11 +2318,11 @@ msgstr ""
|
||||
|
||||
#: common/lib/xmodule/xmodule/course_module.py
|
||||
msgid "Date that enrollment for this class is opened"
|
||||
msgstr ""
|
||||
msgstr "Date de début des inscriptions pour ce cours"
|
||||
|
||||
#: common/lib/xmodule/xmodule/course_module.py
|
||||
msgid "Date that enrollment for this class is closed"
|
||||
msgstr ""
|
||||
msgstr "Date de fin des inscriptions pour ce cours"
|
||||
|
||||
#: common/lib/xmodule/xmodule/course_module.py
|
||||
msgid "Start time when this module is visible"
|
||||
@@ -2337,7 +2330,7 @@ msgstr ""
|
||||
|
||||
#: common/lib/xmodule/xmodule/course_module.py
|
||||
msgid "Date that this class ends"
|
||||
msgstr ""
|
||||
msgstr "Date à laquelle se termine ce cours"
|
||||
|
||||
#: common/lib/xmodule/xmodule/course_module.py
|
||||
msgid "Cosmetic Course Display Price"
|
||||
@@ -3148,7 +3141,7 @@ msgstr "Inscriptions sur invitation par l'équipe pédagogique uniquement."
|
||||
|
||||
#: common/lib/xmodule/xmodule/course_module.py
|
||||
msgid "Pre-Course Survey Name"
|
||||
msgstr "Nom de l’Enquête d'Avant Cours "
|
||||
msgstr "Nom de l’enquête d'avant cours "
|
||||
|
||||
#: common/lib/xmodule/xmodule/course_module.py
|
||||
msgid "Name of SurveyForm to display as a pre-course survey to the user."
|
||||
@@ -3158,7 +3151,7 @@ msgstr ""
|
||||
|
||||
#: common/lib/xmodule/xmodule/course_module.py
|
||||
msgid "Pre-Course Survey Required"
|
||||
msgstr "Enquête d'Avant Cours Requise"
|
||||
msgstr "Enquête d'avant cours requise"
|
||||
|
||||
#: common/lib/xmodule/xmodule/course_module.py
|
||||
msgid ""
|
||||
@@ -3574,11 +3567,11 @@ msgstr ""
|
||||
|
||||
#: common/lib/xmodule/xmodule/library_content_module.py
|
||||
msgid "Invalid Library"
|
||||
msgstr ""
|
||||
msgstr "Bibliothèque invalide"
|
||||
|
||||
#: common/lib/xmodule/xmodule/library_content_module.py
|
||||
msgid "No Library Selected"
|
||||
msgstr ""
|
||||
msgstr "Aucune bibliothèque sélectionnée"
|
||||
|
||||
#: common/lib/xmodule/xmodule/library_root_xblock.py
|
||||
msgid "Enter the name of the library as it should appear in Studio."
|
||||
@@ -3708,7 +3701,7 @@ msgstr ""
|
||||
|
||||
#: common/lib/xmodule/xmodule/lti_module.py
|
||||
msgid "Request user's username"
|
||||
msgstr ""
|
||||
msgstr "Demander le nom de l'utilisateur"
|
||||
|
||||
#: common/lib/xmodule/xmodule/lti_module.py
|
||||
msgid ""
|
||||
@@ -5088,7 +5081,14 @@ msgid "{month} {day}, {year}"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid "a course of study offered by {partner_name}, through {platform_name}."
|
||||
msgid ""
|
||||
"a course of study offered by {partner_short_name}, an online learning "
|
||||
"initiative of {partner_long_name} through {platform_name}."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid ""
|
||||
"a course of study offered by {partner_short_name}, through {platform_name}."
|
||||
msgstr ""
|
||||
|
||||
#. Translators: Accomplishments describe the awards/certifications obtained by
|
||||
@@ -5188,13 +5188,13 @@ msgstr ""
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid ""
|
||||
"This is a valid {platform_name} certificate for {user_name}, who "
|
||||
"participated in {partner_name} {course_number}"
|
||||
"participated in {partner_short_name} {course_number}"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This text is bound to the HTML 'title' element of the page
|
||||
#. and appears in the browser title bar
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid "{partner_name} {course_number} Certificate | {platform_name}"
|
||||
msgid "{partner_short_name} {course_number} Certificate | {platform_name}"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This text fragment appears after the student's name
|
||||
@@ -5351,6 +5351,14 @@ msgid ""
|
||||
"{payment_support_link}."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/commerce/api/v1/serializers.py
|
||||
msgid "{course_id} is not a valid course key."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/commerce/api/v1/serializers.py
|
||||
msgid "Course {course_id} does not exist."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/course_wiki/tab.py lms/djangoapps/course_wiki/views.py
|
||||
#: lms/templates/wiki/base.html
|
||||
msgid "Wiki"
|
||||
@@ -5897,6 +5905,23 @@ msgstr ""
|
||||
msgid "File is not attached."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid "Could not find problem with this location."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid ""
|
||||
"The problem responses report is being created. To view the status of the "
|
||||
"report, see Pending Tasks below."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid ""
|
||||
"A problem responses report generation task is already in progress. Check the"
|
||||
" 'Pending Tasks' table for the status of the task. When completed, the "
|
||||
"report will be available for download in the table below."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid "Invoice number '{num}' does not exist."
|
||||
msgstr ""
|
||||
@@ -6296,6 +6321,10 @@ msgstr "CourseMode en mode ralenti ({mode_slug}) n'existe pas"
|
||||
msgid "CourseMode price updated successfully"
|
||||
msgstr "Le prix du CourseMode a été correctement mis à jour"
|
||||
|
||||
#: lms/djangoapps/instructor/views/instructor_dashboard.py
|
||||
msgid "No end date set"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/instructor_dashboard.py
|
||||
msgid "Enrollment data is now available in {dashboard_link}."
|
||||
msgstr ""
|
||||
@@ -6393,18 +6422,6 @@ msgstr "Email externe"
|
||||
msgid "Grades for assignment \"{name}\""
|
||||
msgstr "Notes pour le travail \"{name}\""
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Found {num} records to dump."
|
||||
msgstr " A trouvé {num} enregistrements à jeter."
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Couldn't find module with that urlname."
|
||||
msgstr "Impossible de trouver un module avec cette URL."
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Student state for problem {problem}"
|
||||
msgstr "Etat de l’étudiant pour le problème {problem}"
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Grades from {course_id}"
|
||||
msgstr "Notes de {course_id}"
|
||||
@@ -6579,6 +6596,12 @@ msgstr "supprimé"
|
||||
msgid "emailed"
|
||||
msgstr "envoyé par e-mail"
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
msgid "generated"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
@@ -6591,12 +6614,6 @@ msgstr "noté"
|
||||
msgid "problem distribution graded"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
msgid "generated"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
@@ -8118,11 +8135,11 @@ msgid "course_id must be provided"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/views.py
|
||||
msgid "The supplied topic id {topic_id} is not valid"
|
||||
msgid "text_search and order_by cannot be provided together"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/views.py
|
||||
msgid "text_search is not yet supported."
|
||||
msgid "The supplied topic id {topic_id} is not valid"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: 'ordering' is a string describing a way
|
||||
@@ -9805,7 +9822,7 @@ msgstr "Numéro du cours"
|
||||
#: cms/templates/course_outline.html
|
||||
#: lms/templates/instructor/instructor_dashboard_2/course_info.html
|
||||
msgid "Course Start Date:"
|
||||
msgstr ""
|
||||
msgstr "Date de début du cours :"
|
||||
|
||||
#: cms/templates/html_error.html lms/templates/module-error.html
|
||||
msgid "Error:"
|
||||
@@ -9916,7 +9933,7 @@ msgstr "Menu du cours"
|
||||
#: cms/templates/widgets/header.html lms/templates/navigation-edx.html
|
||||
#: lms/templates/navigation.html
|
||||
msgid "Account"
|
||||
msgstr ""
|
||||
msgstr "Compte"
|
||||
|
||||
#: cms/templates/widgets/header.html lms/templates/help_modal.html
|
||||
#: lms/templates/static_templates/help.html wiki/plugins/help/wiki_plugin.py
|
||||
@@ -9928,6 +9945,10 @@ msgstr "Aide"
|
||||
msgid "Sign Out"
|
||||
msgstr "Se déconnecter"
|
||||
|
||||
#: common/lib/capa/capa/templates/codeinput.html
|
||||
msgid "{programming_language} editor"
|
||||
msgstr ""
|
||||
|
||||
#: common/templates/license.html
|
||||
msgid "All Rights Reserved"
|
||||
msgstr "Tous droits réservés"
|
||||
@@ -12570,8 +12591,10 @@ msgid "Section:"
|
||||
msgstr "Section :"
|
||||
|
||||
#: lms/templates/courseware/legacy_instructor_dashboard.html
|
||||
msgid "Problem urlname:"
|
||||
msgstr "url de l'exercice :"
|
||||
msgid ""
|
||||
"To download a CSV listing student responses to a given problem, visit the "
|
||||
"Data Download section of the Instructor Dashboard."
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/courseware/legacy_instructor_dashboard.html
|
||||
msgid ""
|
||||
@@ -14379,7 +14402,7 @@ msgstr "Information d'inscription"
|
||||
#. 'audit')
|
||||
#: lms/templates/instructor/instructor_dashboard_2/course_info.html
|
||||
msgid "Number of enrollees (admins, staff, and students) by track"
|
||||
msgstr ""
|
||||
msgstr "Nombre d'inscrits (admins, staff, and students) par mode"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/course_info.html
|
||||
msgid "Audit"
|
||||
@@ -14403,7 +14426,7 @@ msgstr "Nom d'affichage du cours :"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/course_info.html
|
||||
msgid "Course End Date:"
|
||||
msgstr ""
|
||||
msgstr "Date de fin du cours"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/course_info.html
|
||||
msgid "Has the course started?"
|
||||
@@ -14423,7 +14446,7 @@ msgstr "Le cours est-il terminé ?"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/course_info.html
|
||||
msgid "Number of sections:"
|
||||
msgstr ""
|
||||
msgstr "Nombre de sections:"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/course_info.html
|
||||
msgid "Grade Cutoffs:"
|
||||
@@ -14480,6 +14503,11 @@ msgid ""
|
||||
"background, meaning it is OK to navigate away from this page while your "
|
||||
"report is generating."
|
||||
msgstr ""
|
||||
"Pour les cours à grande échelle, la création des rapports peut prendre "
|
||||
"plusieurs heures. Quand la création du rapport est achevée, un lien incluant"
|
||||
" la date et l'heure de la création est affiché dans le tableau ci-dessous. "
|
||||
"Ces rapports sont créés en tâche de fond, cela signifie qu'il est possible "
|
||||
"de naviguer dans d'autres pages en parallèle de la création des rapports."
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid ""
|
||||
@@ -14519,6 +14547,20 @@ msgstr ""
|
||||
msgid "Generate Proctored Exam Results Report"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid ""
|
||||
"To generate a CSV file that lists all student answers to a given problem, "
|
||||
"enter the location of the problem (from its Staff Debug Info)."
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid "Problem location: "
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid "Download a CSV of problem responses"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid ""
|
||||
"For smaller courses, click to list profile information for enrolled students"
|
||||
@@ -15218,13 +15260,15 @@ msgstr "Importer CSV"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/membership.html
|
||||
msgid "Batch Beta Tester Addition"
|
||||
msgstr "Ajout par des bêta testeurs par lots"
|
||||
msgstr "Ajout de bêta testeurs"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/membership.html
|
||||
msgid ""
|
||||
"Note: Users must have an activated {platform_name} account before they can "
|
||||
"be enrolled as beta testers."
|
||||
msgstr ""
|
||||
"Note: Les utilisateurs doivent avoir activé leur compte {platform_name} "
|
||||
"avant de pouvoir être ajouté en bêta testeur."
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/membership.html
|
||||
msgid ""
|
||||
@@ -15252,14 +15296,14 @@ msgstr "Supprimer des bêta-testeurs"
|
||||
#. users can be added to.
|
||||
#: lms/templates/instructor/instructor_dashboard_2/membership.html
|
||||
msgid "Course Team Management"
|
||||
msgstr ""
|
||||
msgstr "Gestion de l'équipe du cours"
|
||||
|
||||
#. Translators: an "Administrator Group" is a group, such as Course Staff,
|
||||
#. that
|
||||
#. users can be added to.
|
||||
#: lms/templates/instructor/instructor_dashboard_2/membership.html
|
||||
msgid "Select a course team role:"
|
||||
msgstr ""
|
||||
msgstr "Sélectionner un rôle:"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/membership.html
|
||||
msgid "Getting available lists..."
|
||||
@@ -15279,10 +15323,16 @@ msgid ""
|
||||
"all course data. Staff also have access to your course in Studio and "
|
||||
"Insights. You can only give course team roles to enrolled users."
|
||||
msgstr ""
|
||||
"Les membres de l'équipe avec le rôle Équipe pédagogique aident à la gestion "
|
||||
"du cours. L'équipe pédagogique peut inscrire et désinscrire des "
|
||||
"participants, ainsi que modifier les notes aux exercices et accéder à "
|
||||
"l'ensemble des données du cours. L'équipe pédagogique a également accès au "
|
||||
"cours dans Studio. Vous ne pouvez affecter des rôles que pour les "
|
||||
"utilisateurs inscrits au cours."
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/membership.html
|
||||
msgid "Add Staff"
|
||||
msgstr "Ajouter à l‘équipe"
|
||||
msgstr "Ajouter à Équipe pédagogique"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/membership.html
|
||||
msgid ""
|
||||
@@ -15292,10 +15342,15 @@ msgid ""
|
||||
" to manage course team membership. You can only give course team roles to "
|
||||
"enrolled users."
|
||||
msgstr ""
|
||||
"Les membres de l'équipe avec le rôle Admin aident à la gestion du cours. Ils"
|
||||
" peuvent également effectuer toutes les actions comme l'Équipe pédagogique, "
|
||||
"mais aussi ajouter ou supprimer des membres Admin, gérer les rôles de "
|
||||
"modérations des forums, l'ajout de bêta-testeurs. Vous ne pouvez affecter "
|
||||
"des rôles que pour les utilisateurs inscrits au cours."
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/membership.html
|
||||
msgid "Add Admin"
|
||||
msgstr ""
|
||||
msgstr "Ajouter un Admin"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/membership.html
|
||||
msgid "Beta Testers"
|
||||
@@ -15307,6 +15362,10 @@ msgid ""
|
||||
"sure that the content works, but have no additional privileges. You can only"
|
||||
" give course team roles to enrolled users."
|
||||
msgstr ""
|
||||
"Les Bêta-testeurs peuvent voir le contenu du cours avant les autres "
|
||||
"participants. Ils peuvent ainsi s'assurer que le contenu fonctionne, mais ne"
|
||||
" disposent pas de permissions supplémentaires. Vous ne pouvez affecter de "
|
||||
"rôle uniquement à des utilisateurs inscrits."
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/membership.html
|
||||
msgid "Add Beta Tester"
|
||||
@@ -15324,6 +15383,12 @@ msgid ""
|
||||
"moderation roles to manage course team membership. You can only give course "
|
||||
"team roles to enrolled users."
|
||||
msgstr ""
|
||||
"Les Administrateurs de discussions peuvent modifier et supprimer tous les "
|
||||
"post, les dénonciations abusives, fermer et réouvrir des sujets, indiquer "
|
||||
"des réponses et voir les posts de toutes les cohortes. Leur posts sont "
|
||||
"marqués comme 'Équipe pédagogique'. Ils peuvent aussi modifier les rôles de "
|
||||
"modérations des utilisateurs. Vous pouvez donner un rôle d'équipe uniquement"
|
||||
" à des utilisateurs inscrits au cours."
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/membership.html
|
||||
msgid "Add Discussion Admin"
|
||||
@@ -15341,6 +15406,12 @@ msgid ""
|
||||
" by adding or removing discussion moderation roles. You can only give course"
|
||||
" team roles to enrolled users."
|
||||
msgstr ""
|
||||
"Les Modérateurs de discussions peuvent modifier et supprimer tous les post, "
|
||||
"les dénonciations abusives, fermer et réouvrir des sujets, indiquer des "
|
||||
"réponses et voir les posts de toutes les cohortes. Leur posts sont marqués "
|
||||
"comme 'Équipe pédagogique'. Ils ne peuvent pas modifier les rôles de "
|
||||
"modérations des utilisateurs. Vous pouvez donner un rôle d'équipe uniquement"
|
||||
" à des utilisateurs inscrits au cours."
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/membership.html
|
||||
msgid "Add Moderator"
|
||||
@@ -15358,10 +15429,16 @@ msgid ""
|
||||
"from all cohorts. Their posts are marked as 'Community TA'. You can only "
|
||||
"give course team roles to enrolled users."
|
||||
msgstr ""
|
||||
"Les Assistants peuvent modifier et supprimer tous les post, les "
|
||||
"dénonciations abusives, fermer et réouvrir des sujets, indiquer des réponses"
|
||||
" et voir les posts de toutes les cohortes. Leur posts sont marqués comme "
|
||||
"'Assistants'. Ils ne peuvent pas modifier les rôles de modérations des "
|
||||
"utilisateurs. Vous pouvez donner un rôle d'équipe uniquement à des "
|
||||
"utilisateurs inscrits au cours."
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/membership.html
|
||||
msgid "Add Community TA"
|
||||
msgstr "Ajouter un Community TA"
|
||||
msgstr "Ajouter un Assistant"
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/membership.html
|
||||
msgid "CCX Coaches"
|
||||
@@ -16568,7 +16645,7 @@ msgstr "Se connecter ou s'inscrire"
|
||||
|
||||
#: lms/templates/student_profile/learner_profile.html
|
||||
msgid "Learner Profile"
|
||||
msgstr ""
|
||||
msgstr "Profil de participant"
|
||||
|
||||
#. Translators: this section lists all the third-party authentication
|
||||
#. providers
|
||||
@@ -16614,7 +16691,7 @@ msgstr "Enquête Utilisateur"
|
||||
|
||||
#: lms/templates/survey/survey.html
|
||||
msgid "Pre-Course Survey"
|
||||
msgstr ""
|
||||
msgstr "Enquête d'avant-cours "
|
||||
|
||||
#: lms/templates/survey/survey.html
|
||||
msgid ""
|
||||
@@ -16623,6 +16700,9 @@ msgid ""
|
||||
" use of {platform_name} only. It will not be linked to your public profile "
|
||||
"in any way."
|
||||
msgstr ""
|
||||
"Vous pourrez démarrer votre cours une fois rempli le formulaire suivant. Les"
|
||||
" champs obligatoires sont signalés par une astérisque (*). Ces informations "
|
||||
"sont utilisées uniquement par {platform_name}."
|
||||
|
||||
#: lms/templates/survey/survey.html
|
||||
msgid "You are missing the following required fields:"
|
||||
@@ -16669,7 +16749,7 @@ msgstr ""
|
||||
|
||||
#: lms/templates/verify_student/incourse_reverify.html
|
||||
msgid "Re-Verify for {course_name}"
|
||||
msgstr ""
|
||||
msgstr "Re-Vérification pour {course_name}"
|
||||
|
||||
#: lms/templates/verify_student/missed_deadline.html
|
||||
msgid "Verification Deadline Has Passed"
|
||||
@@ -16984,41 +17064,50 @@ msgid "This module is not enabled."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"Upon successful completion of your course, learners receive a certificate to"
|
||||
" acknowledge their accomplishment. If you are a course team member with the "
|
||||
"Admin role in Studio, you can configure your course certificate."
|
||||
msgid "Working with Certificates"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"Click {em_start}Add your first certificate{em_end} to add a certificate "
|
||||
"configuration. Upload the organization logo to be used on the certificate, "
|
||||
"and specify at least one signatory. You can include up to four signatories "
|
||||
"for a certificate. You can also upload a signature image file for each "
|
||||
"signatory. {em_start}Note:{em_end} Signature images are used only for "
|
||||
"verified certificates. Optionally, specify a different course title to use "
|
||||
"on your course certificate. You might want to use a different title if, for "
|
||||
"example, the official course name is too long to display well on a "
|
||||
"certificate."
|
||||
"Specify a course title to use on the certificate if the course's official "
|
||||
"title is too long to be displayed well."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"Select a course mode and click {em_start}Preview Certificate{em_end} to "
|
||||
"preview the certificate that a learner in the selected enrollment track "
|
||||
"would receive. When the certificate is ready for issuing, click "
|
||||
"{em_start}Activate.{em_end} To stop issuing an active certificate, click "
|
||||
"{em_start}Deactivate{em_end}."
|
||||
"For verified certificates, specify between one and four signatories and "
|
||||
"upload the associated images."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
" To edit the certificate configuration, hover over the top right corner of "
|
||||
"the form and click {em_start}Edit{em_end}. To delete a certificate, hover "
|
||||
"over the top right corner of the form and click the delete icon. In general,"
|
||||
" do not delete certificates after a course has started, because some "
|
||||
"certificates might already have been issued to learners."
|
||||
"To edit or delete a certificate before it is activated, hover over the top "
|
||||
"right corner of the form and select {em_start}Edit{em_end} or the delete "
|
||||
"icon."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"To view a sample certificate, choose a course mode and select "
|
||||
"{em_start}Preview Certificate{em_end}."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid "Issuing Certificates to Learners"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"To begin issuing certificates, a course team member with the Admin role "
|
||||
"selects {em_start}Activate{em_end}. Course team members without the Admin "
|
||||
"role cannot edit or delete an activated certificate."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"{em_start}Do not{em_end} delete certificates after a course has started; "
|
||||
"learners who have already earned certificates will no longer be able to "
|
||||
"access them."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
@@ -17494,6 +17583,9 @@ msgid ""
|
||||
"date. When you configure a subsection, you can also set the grading policy "
|
||||
"and due date."
|
||||
msgstr ""
|
||||
"Sélectionnez l'icône Configuration pour une section ou une sous-section pour"
|
||||
" définir sa date de publication. Lorsque vous configurez une sous-section, "
|
||||
"vous pouvez également définir le type de devoir et la date d'échéance."
|
||||
|
||||
#: cms/templates/course_outline.html
|
||||
msgid "Changing the content students see"
|
||||
|
||||
Binary file not shown.
@@ -110,8 +110,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: edx-platform\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2015-08-21 14:17+0000\n"
|
||||
"PO-Revision-Date: 2015-08-21 02:41+0000\n"
|
||||
"POT-Creation-Date: 2015-09-04 14:06+0000\n"
|
||||
"PO-Revision-Date: 2015-09-04 14:08+0000\n"
|
||||
"Last-Translator: Sarina Canelake <sarina@edx.org>\n"
|
||||
"Language-Team: French (http://www.transifex.com/open-edx/edx-platform/language/fr/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -157,8 +157,8 @@ msgstr "OK"
|
||||
#: cms/static/js/views/show_textbook.js cms/static/js/views/validation.js
|
||||
#: cms/static/js/views/modals/base_modal.js
|
||||
#: cms/static/js/views/modals/course_outline_modals.js
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
#: cms/templates/js/add-xblock-component-menu-problem.underscore
|
||||
#: cms/templates/js/add-xblock-component-menu.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
@@ -169,6 +169,11 @@ msgstr "OK"
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
#: cms/templates/js/section-name-edit.underscore
|
||||
#: cms/templates/js/xblock-string-field-editor.underscore
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
#: common/static/common/templates/discussion/response-comment-edit.underscore
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
#: common/static/common/templates/discussion/thread-response-edit.underscore
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
#: lms/templates/instructor/instructor_dashboard_2/cohort-form.underscore
|
||||
msgid "Cancel"
|
||||
msgstr "Annuler"
|
||||
@@ -178,17 +183,6 @@ msgstr "Annuler"
|
||||
#: cms/static/js/views/manage_users_and_roles.js
|
||||
#: cms/static/js/views/show_textbook.js
|
||||
#: common/static/js/vendor/ova/catch/js/catch.js
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
#: cms/templates/js/content-group-details.underscore
|
||||
#: cms/templates/js/content-group-editor.underscore
|
||||
#: cms/templates/js/course-outline.underscore
|
||||
#: cms/templates/js/course_grade_policy.underscore
|
||||
#: cms/templates/js/group-configuration-details.underscore
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
#: cms/templates/js/show-textbook.underscore
|
||||
#: cms/templates/js/signatory-editor.underscore
|
||||
#: cms/templates/js/xblock-outline.underscore
|
||||
msgid "Delete"
|
||||
msgstr "Supprimer"
|
||||
|
||||
@@ -263,12 +257,10 @@ msgstr "Erreur"
|
||||
msgid "Save"
|
||||
msgstr "Enregistrer"
|
||||
|
||||
#. #-#-#-#-# djangojs-partial.po (edx-platform) #-#-#-#-#
|
||||
#. Translators: this is a message from the raw HTML editor displayed in the
|
||||
#. browser when a user needs to edit HTML
|
||||
#: cms/static/js/views/modals/edit_xblock.js
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: cms/templates/js/signatory-editor.underscore
|
||||
msgid "Close"
|
||||
msgstr "Fermer"
|
||||
|
||||
@@ -358,6 +350,8 @@ msgstr "Votre résultat n'est pas suffisant pour passer à l'étape suivante."
|
||||
|
||||
#: common/lib/xmodule/xmodule/js/src/combinedopenended/display.js
|
||||
#: lms/static/coffee/src/staff_grading/staff_grading.js
|
||||
#: common/static/common/templates/discussion/thread-response.underscore
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
#: lms/templates/verify_student/incourse_reverify.underscore
|
||||
msgid "Submit"
|
||||
msgstr "Soumettre"
|
||||
@@ -790,18 +784,10 @@ msgstr "Propriétés du document"
|
||||
msgid "Edit HTML"
|
||||
msgstr "Editer le code HTML"
|
||||
|
||||
#. #-#-#-#-# djangojs-partial.po (edx-platform) #-#-#-#-#
|
||||
#. Translators: this is a message from the raw HTML editor displayed in the
|
||||
#. browser when a user needs to edit HTML
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: common/static/js/vendor/ova/catch/js/catch.js
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/content-group-details.underscore
|
||||
#: cms/templates/js/course_info_handouts.underscore
|
||||
#: cms/templates/js/group-configuration-details.underscore
|
||||
#: cms/templates/js/show-textbook.underscore
|
||||
#: cms/templates/js/signatory-details.underscore
|
||||
#: cms/templates/js/xblock-string-field-editor.underscore
|
||||
msgid "Edit"
|
||||
msgstr "Éditer"
|
||||
|
||||
@@ -1555,12 +1541,9 @@ msgstr ""
|
||||
"L'URL que vous avez entrée semble être un lien externe. Voulez-vous ajouter "
|
||||
"le préfixe http:// requis ?"
|
||||
|
||||
#. #-#-#-#-# djangojs-partial.po (edx-platform) #-#-#-#-#
|
||||
#. Translators: this is a message from the raw HTML editor displayed in the
|
||||
#. browser when a user needs to edit HTML
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: cms/templates/js/signatory-details.underscore
|
||||
#: cms/templates/js/signatory-editor.underscore
|
||||
msgid "Title"
|
||||
msgstr "Titre"
|
||||
|
||||
@@ -2187,6 +2170,18 @@ msgstr ""
|
||||
msgid "Are you sure you want to delete this response?"
|
||||
msgstr "Voulez-vous vraiment supprimer cette réponse ?"
|
||||
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
msgid "Required field."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
msgid "Please do not use any spaces in this field."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
msgid "Please do not use any spaces or special characters in this field."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/js/components/views/paging_header.js
|
||||
msgid "Showing %(first_index)s out of %(num_items)s total"
|
||||
msgstr "%(first_index)s sur %(num_items)s au total"
|
||||
@@ -2352,6 +2347,7 @@ msgstr "Date de l'envoi"
|
||||
|
||||
#: common/static/js/vendor/ova/catch/js/catch.js
|
||||
#: lms/static/js/courseware/credit_progress.js
|
||||
#: common/static/common/templates/discussion/forum-actions.underscore
|
||||
#: lms/templates/discovery/facet.underscore
|
||||
#: lms/templates/edxnotes/note-item.underscore
|
||||
msgid "More"
|
||||
@@ -2431,21 +2427,34 @@ msgid "An unexpected error occurred. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/team.js
|
||||
msgid "last activity"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/team.js
|
||||
msgid "open slots"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/topic.js
|
||||
#: lms/templates/edxnotes/tab-item.underscore
|
||||
msgid "name"
|
||||
msgstr "nom"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/team.js
|
||||
msgid "open_slots"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This refers to the number of teams (a count of how many teams
|
||||
#. there are)
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/topic.js
|
||||
msgid "team count"
|
||||
msgstr "total équipe"
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
#: cms/templates/js/content-group-editor.underscore
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
msgid "Create"
|
||||
msgstr "Créer"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
msgid "Update"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
msgid "Team Name (Required) *"
|
||||
msgstr ""
|
||||
@@ -2470,6 +2479,7 @@ msgid "Language"
|
||||
msgstr "Langue"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid ""
|
||||
"The language that team members primarily use to communicate with each other."
|
||||
msgstr ""
|
||||
@@ -2480,6 +2490,7 @@ msgid "Country"
|
||||
msgstr "Pays"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "The country that team members primarily identify with."
|
||||
msgstr ""
|
||||
|
||||
@@ -2512,20 +2523,48 @@ msgstr ""
|
||||
msgid "You are not currently a member of any team."
|
||||
msgstr ""
|
||||
|
||||
#. Translators: "and others" refers to fact that additional members of a team
|
||||
#. exist that are not displayed.
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_card.js
|
||||
msgid "and others"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: 'date' is a placeholder for a fuzzy, relative timestamp (see:
|
||||
#. https://github.com/rmm5t/jquery-timeago)
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_card.js
|
||||
msgid "Last Activity %(date)s"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_card.js
|
||||
msgid "View %(span_start)s %(team_name)s %(span_end)s"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_join.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile_header_actions.js
|
||||
msgid "An error occurred. Try again."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_join.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
msgid "Leave this team?"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
msgid ""
|
||||
"If you leave, you can no longer post in this team's discussions. Your place "
|
||||
"will be available to another learner."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
#: lms/static/js/verify_student/views/reverify_view.js
|
||||
#: lms/templates/verify_student/review_photos_step.underscore
|
||||
msgid "Confirm"
|
||||
msgstr "Confirmer"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile_header_actions.js
|
||||
msgid "You already belong to another team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_join.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile_header_actions.js
|
||||
msgid "This team is full."
|
||||
msgstr ""
|
||||
|
||||
@@ -2543,37 +2582,62 @@ msgstr ""
|
||||
msgid "teams"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Teams"
|
||||
msgstr "Équipes"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"See all teams in your course, organized by topic. Join a team to collaborate"
|
||||
" with other learners who are interested in the same topic as you are."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Teams"
|
||||
msgstr "Équipes"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "My Team"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: sr_start and sr_end surround text meant only for screen
|
||||
#. readers. The whole string will be shown to users as "Browse teams" if they
|
||||
#. are using a screenreader, and "Browse" otherwise.
|
||||
#. readers.
|
||||
#. The whole string will be shown to users as "Browse teams" if they are using
|
||||
#. a
|
||||
#. screenreader, and "Browse" otherwise.
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Browse %(sr_start)s teams %(sr_end)s"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"Create a new team if you can't find existing teams to join, or if you would "
|
||||
"like to learn with friends you know."
|
||||
msgid "Team Search"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Showing results for \"%(searchString)s\""
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Create a New Team"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"Create a new team if you can't find an existing team to join, or if you "
|
||||
"would like to learn with friends you know."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile-header-actions.underscore
|
||||
msgid "Edit Team"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"If you make significant changes, make sure you notify members of the team "
|
||||
"before making these changes."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Search teams"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "All Topics"
|
||||
msgstr ""
|
||||
@@ -2596,15 +2660,27 @@ msgid_plural "%(team_count)s Teams"
|
||||
msgstr[0] "%(team_count)s Equipe"
|
||||
msgstr[1] "%(team_count)s Équipes"
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topic_card.js
|
||||
msgid "Topic"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topic_card.js
|
||||
msgid "View Teams in the %(topic_name)s Topic"
|
||||
msgstr "Voir les équipes du sujet %(topic_name)s"
|
||||
|
||||
#. Translators: this string is shown at the bottom of the teams page
|
||||
#. to find a team to join or else to create a new one. There are three
|
||||
#. links that need to be included in the message:
|
||||
#. 1. Browse teams in other topics
|
||||
#. 2. search teams
|
||||
#. 3. create a new team
|
||||
#. Be careful to start each link with the appropriate start indicator
|
||||
#. (e.g. {browse_span_start} for #1) and finish it with {span_end}.
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topic_teams.js
|
||||
msgid ""
|
||||
"Try {browse_span_start}browsing all teams{span_end} or "
|
||||
"{search_span_start}searching team descriptions{span_end}. If you still can't"
|
||||
" find a team to join, {create_span_start}create a new team in this "
|
||||
"{browse_span_start}Browse teams in other topics{span_end} or "
|
||||
"{search_span_start}search teams{span_end} in this topic. If you still can't "
|
||||
"find a team to join, {create_span_start}create a new team in this "
|
||||
"topic{span_end}."
|
||||
msgstr ""
|
||||
|
||||
@@ -4073,11 +4149,6 @@ msgstr "Prenez une photo de votre pièce d'identité"
|
||||
msgid "Review your info"
|
||||
msgstr "Vérifiez vos informations"
|
||||
|
||||
#: lms/static/js/verify_student/views/reverify_view.js
|
||||
#: lms/templates/verify_student/review_photos_step.underscore
|
||||
msgid "Confirm"
|
||||
msgstr "Confirmer"
|
||||
|
||||
#: lms/static/js/verify_student/views/step_view.js
|
||||
msgid "An error has occurred. Please try reloading the page."
|
||||
msgstr "Une erreur est survenue. Essayez de rafraîchir la page."
|
||||
@@ -4591,6 +4662,7 @@ msgstr ""
|
||||
#: cms/static/js/models/settings/course_details.js
|
||||
msgid "The course end date must be later than the course start date."
|
||||
msgstr ""
|
||||
"La date de fin du cours doit être postérieure à la date de début du cours."
|
||||
|
||||
#: cms/static/js/models/settings/course_details.js
|
||||
msgid "The course start date must be later than the enrollment start date."
|
||||
@@ -4669,7 +4741,7 @@ msgstr "Votre fichier a été supprimé."
|
||||
msgid "Date Added"
|
||||
msgstr "Date ajoutée"
|
||||
|
||||
#: cms/static/js/views/assets.js cms/templates/js/asset-library.underscore
|
||||
#: cms/static/js/views/assets.js
|
||||
msgid "Type"
|
||||
msgstr "Type"
|
||||
|
||||
@@ -5252,19 +5324,6 @@ msgstr ""
|
||||
"La longueur totale des champs organisation et codes de bibliothèque ne doit "
|
||||
"pas dépasser <%=limit%> caractères."
|
||||
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
msgid "Required field."
|
||||
msgstr "Champ requis."
|
||||
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
msgid "Please do not use any spaces in this field."
|
||||
msgstr "Merci de ne pas utiliser d'espace dans ce champ."
|
||||
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
msgid "Please do not use any spaces or special characters in this field."
|
||||
msgstr ""
|
||||
"Merci de ne pas utiliser d'espace ou de caractère spécial dans ce champ."
|
||||
|
||||
#: cms/static/js/views/utils/xblock_utils.js
|
||||
msgid "component"
|
||||
msgstr "composant"
|
||||
@@ -5356,11 +5415,526 @@ msgstr "Actions"
|
||||
msgid "Due Date"
|
||||
msgstr "Date d'échéance"
|
||||
|
||||
#: cms/templates/js/paging-header.underscore
|
||||
#: common/static/common/templates/components/paging-footer.underscore
|
||||
#: common/static/common/templates/discussion/pagination.underscore
|
||||
msgid "Previous"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/previous-video-upload-list.underscore
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
#: lms/templates/verify_student/enrollment_confirmation_step.underscore
|
||||
msgid "Status"
|
||||
msgstr "Statut"
|
||||
|
||||
#: common/static/common/templates/image-modal.underscore
|
||||
msgid "Large"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/image-modal.underscore
|
||||
msgid "Zoom In"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/image-modal.underscore
|
||||
msgid "Zoom Out"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/paging-footer.underscore
|
||||
msgid "Page number"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/paging-footer.underscore
|
||||
msgid "Enter the page number you'd like to quickly navigate to."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/paging-header.underscore
|
||||
msgid "Sorted by"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/search-field.underscore
|
||||
msgid "Clear search"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "DISCUSSION HOME:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
#: lms/templates/commerce/provider.underscore
|
||||
#: lms/templates/commerce/receipt.underscore
|
||||
#: lms/templates/discovery/course_card.underscore
|
||||
msgid "gettext("
|
||||
msgstr "gettext("
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Find discussions"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Focus in on specific topics"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Search for specific posts"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Sort by date, vote, or comments"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Engage with posts"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Upvote posts and good responses"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Report Forum Misuse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Follow posts for updates"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Receive updates"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Toggle Notifications Setting"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid ""
|
||||
"Check this box to receive an email digest once a day notifying you about "
|
||||
"new, unread activity from posts you are following."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-answer.underscore
|
||||
msgid "Mark as Answer"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-answer.underscore
|
||||
msgid "Unmark as Answer"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-close.underscore
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-endorse.underscore
|
||||
msgid "Endorse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-endorse.underscore
|
||||
msgid "Unendorse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-follow.underscore
|
||||
msgid "Follow"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-follow.underscore
|
||||
msgid "Unfollow"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-pin.underscore
|
||||
msgid "Pin"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-pin.underscore
|
||||
msgid "Unpin"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-report.underscore
|
||||
msgid "Report abuse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-report.underscore
|
||||
msgid "Report"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-report.underscore
|
||||
msgid "Unreport"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-vote.underscore
|
||||
msgid "Vote for this post,"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Visible To:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "All Groups"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid ""
|
||||
"Discussion admins, moderators, and TAs can make their posts visible to all "
|
||||
"students or specify a single cohort."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Title:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Add a clear and descriptive title to encourage participation."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Enter your question or comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "follow this post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "post anonymously"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "post anonymously to classmates"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Add Post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/post-user-display.underscore
|
||||
msgid "Community TA"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/profile-thread.underscore
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "This thread is closed."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/profile-thread.underscore
|
||||
msgid "View discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-edit.underscore
|
||||
msgid "Editing comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-edit.underscore
|
||||
msgid "Update comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-show.underscore
|
||||
#, python-format
|
||||
msgid "posted %(time_ago)s by %(author)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-show.underscore
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "Reported"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
msgid "Editing post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
msgid "Edit post title"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
msgid "Update post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "answered question"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "unanswered question"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "Pinned"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "Following"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "By: Staff"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "By: Community TA"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
msgid "fmt"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(comments_count)s %(span_sr_open)scomments (%(unread_comments_count)s "
|
||||
"unread comments)%(span_close)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#, python-format
|
||||
msgid "%(comments_count)s %(span_sr_open)scomments %(span_close)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-edit.underscore
|
||||
msgid "Editing response"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-edit.underscore
|
||||
msgid "Update response"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "marked as answer %(time_ago)s by %(user)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "marked as answer %(time_ago)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "endorsed %(time_ago)s by %(user)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "endorsed %(time_ago)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response.underscore
|
||||
msgid "fmts"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response.underscore
|
||||
msgid "Add a comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
#, python-format
|
||||
msgid "This post is visible only to %(group_name)s."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "This post is visible to everyone."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
#, python-format
|
||||
msgid "%(post_type)s posted %(time_ago)s by %(author)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "Closed"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
#, python-format
|
||||
msgid "Related to: %(courseware_title_linked)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid "Post type:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid "Question"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid "Discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid ""
|
||||
"Questions raise issues that need answers. Discussions share ideas and start "
|
||||
"conversations."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Add a Response"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Post a response:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Expand discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Collapse discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Topic Area:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Discussion topics; current selection is:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Filter topics"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Add your post to a relevant topic to help others find it."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/user-profile.underscore
|
||||
msgid "Active Threads"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates.underscore
|
||||
msgid "username or email"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "No results"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Course Key"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Download URL"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Grade"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Last Updated"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Download the user's certificate"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Not available"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Regenerate"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Regenerate the user's certificate"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Your team could not be created."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Your team could not be updated."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid ""
|
||||
"Enter information to describe your team. You cannot change these details "
|
||||
"after you create the team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Optional Characteristics"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid ""
|
||||
"Help other learners decide whether to join your team by specifying some "
|
||||
"characteristics for your team. Choose carefully, because fewer people might "
|
||||
"be interested in joining your team if it seems too restrictive."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Create team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Update team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Cancel team creating."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Cancel team updating."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-actions.underscore
|
||||
msgid "Are you having trouble finding a team to join?"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile-header-actions.underscore
|
||||
msgid "Join Team"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "New Post"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Team Details"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "You are a member of this team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Team member profiles"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Team capacity"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "country"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "language"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Leave Team"
|
||||
msgstr ""
|
||||
|
||||
#: lms/static/js/fixtures/donation.underscore
|
||||
#: lms/templates/dashboard/donation.underscore
|
||||
msgid "Donate"
|
||||
msgstr "Faire un don"
|
||||
|
||||
#: lms/templates/ccx/schedule.underscore
|
||||
msgid "Expand All"
|
||||
msgstr ""
|
||||
@@ -5401,12 +5975,6 @@ msgstr ""
|
||||
msgid "Subsection"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/commerce/provider.underscore
|
||||
#: lms/templates/commerce/receipt.underscore
|
||||
#: lms/templates/discovery/course_card.underscore
|
||||
msgid "gettext("
|
||||
msgstr "gettext("
|
||||
|
||||
#: lms/templates/commerce/provider.underscore
|
||||
#, python-format
|
||||
msgid "<img src='%s' alt='%s'></image>"
|
||||
@@ -5503,10 +6071,6 @@ msgstr ""
|
||||
msgid "End My Exam"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/dashboard/donation.underscore
|
||||
msgid "Donate"
|
||||
msgstr "Faire un don"
|
||||
|
||||
#: lms/templates/discovery/course_card.underscore
|
||||
msgid "LEARN MORE"
|
||||
msgstr "EN SAVOIR PLUS"
|
||||
@@ -6483,6 +7047,16 @@ msgstr "Glisser déposer ou cliquer ici pour importer des fichiers vidéo."
|
||||
msgid "status"
|
||||
msgstr "statut"
|
||||
|
||||
#: cms/templates/js/add-xblock-component-button.underscore
|
||||
msgid "Add Component:"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/add-xblock-component-menu-problem.underscore
|
||||
#: cms/templates/js/add-xblock-component-menu.underscore
|
||||
#, python-format
|
||||
msgid "%(type)s Component Template Menu"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/add-xblock-component-menu-problem.underscore
|
||||
msgid "Common Problem Types"
|
||||
msgstr "Types d'exercices classiques"
|
||||
@@ -6557,6 +7131,11 @@ msgstr "Identifiant"
|
||||
msgid "Certificate Details"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "Course Title"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "Course Title Override"
|
||||
@@ -6601,19 +7180,13 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "Add Signatory"
|
||||
msgid "Add Additional Signatory"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "(Up to 4 signatories are allowed for a certificate)"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
#: cms/templates/js/content-group-editor.underscore
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
msgid "Create"
|
||||
msgstr "Créer"
|
||||
|
||||
#: cms/templates/js/certificate-web-preview.underscore
|
||||
msgid "Choose mode"
|
||||
msgstr ""
|
||||
@@ -7055,10 +7628,6 @@ msgstr "Vous n'avez encore ajouté aucun manuel à ce cours."
|
||||
msgid "Add your first textbook"
|
||||
msgstr "Ajouter votre premier manuel"
|
||||
|
||||
#: cms/templates/js/paging-header.underscore
|
||||
msgid "Previous"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/previous-video-upload-list.underscore
|
||||
msgid "Previous Uploads"
|
||||
msgstr ""
|
||||
|
||||
Binary file not shown.
@@ -61,7 +61,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: edx-platform\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2015-08-21 14:18+0000\n"
|
||||
"POT-Creation-Date: 2015-09-04 14:07+0000\n"
|
||||
"PO-Revision-Date: 2015-05-28 20:00+0000\n"
|
||||
"Last-Translator: Nadav Stark <nadav@yeda.org.il>\n"
|
||||
"Language-Team: Hebrew (http://www.transifex.com/open-edx/edx-platform/language/he/)\n"
|
||||
@@ -1215,10 +1215,6 @@ msgstr ""
|
||||
msgid "incorrect"
|
||||
msgstr ""
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "partially correct"
|
||||
msgstr ""
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "incomplete"
|
||||
msgstr ""
|
||||
@@ -1241,10 +1237,6 @@ msgstr ""
|
||||
msgid "This is incorrect."
|
||||
msgstr ""
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "This is partially correct."
|
||||
msgstr ""
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "This is unanswered."
|
||||
msgstr ""
|
||||
@@ -4550,7 +4542,14 @@ msgid "{month} {day}, {year}"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid "a course of study offered by {partner_name}, through {platform_name}."
|
||||
msgid ""
|
||||
"a course of study offered by {partner_short_name}, an online learning "
|
||||
"initiative of {partner_long_name} through {platform_name}."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid ""
|
||||
"a course of study offered by {partner_short_name}, through {platform_name}."
|
||||
msgstr ""
|
||||
|
||||
#. Translators: Accomplishments describe the awards/certifications obtained by
|
||||
@@ -4650,13 +4649,13 @@ msgstr ""
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid ""
|
||||
"This is a valid {platform_name} certificate for {user_name}, who "
|
||||
"participated in {partner_name} {course_number}"
|
||||
"participated in {partner_short_name} {course_number}"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This text is bound to the HTML 'title' element of the page
|
||||
#. and appears in the browser title bar
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid "{partner_name} {course_number} Certificate | {platform_name}"
|
||||
msgid "{partner_short_name} {course_number} Certificate | {platform_name}"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This text fragment appears after the student's name
|
||||
@@ -4813,6 +4812,14 @@ msgid ""
|
||||
"{payment_support_link}."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/commerce/api/v1/serializers.py
|
||||
msgid "{course_id} is not a valid course key."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/commerce/api/v1/serializers.py
|
||||
msgid "Course {course_id} does not exist."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/course_wiki/tab.py lms/djangoapps/course_wiki/views.py
|
||||
#: lms/templates/wiki/base.html
|
||||
msgid "Wiki"
|
||||
@@ -5333,6 +5340,23 @@ msgstr ""
|
||||
msgid "File is not attached."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid "Could not find problem with this location."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid ""
|
||||
"The problem responses report is being created. To view the status of the "
|
||||
"report, see Pending Tasks below."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid ""
|
||||
"A problem responses report generation task is already in progress. Check the"
|
||||
" 'Pending Tasks' table for the status of the task. When completed, the "
|
||||
"report will be available for download in the table below."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid "Invoice number '{num}' does not exist."
|
||||
msgstr ""
|
||||
@@ -5719,6 +5743,10 @@ msgstr ""
|
||||
msgid "CourseMode price updated successfully"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/instructor_dashboard.py
|
||||
msgid "No end date set"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/instructor_dashboard.py
|
||||
msgid "Enrollment data is now available in {dashboard_link}."
|
||||
msgstr ""
|
||||
@@ -5816,18 +5844,6 @@ msgstr ""
|
||||
msgid "Grades for assignment \"{name}\""
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Found {num} records to dump."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Couldn't find module with that urlname."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Student state for problem {problem}"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Grades from {course_id}"
|
||||
msgstr ""
|
||||
@@ -5991,6 +6007,12 @@ msgstr ""
|
||||
msgid "emailed"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
msgid "generated"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
@@ -6003,12 +6025,6 @@ msgstr ""
|
||||
msgid "problem distribution graded"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
msgid "generated"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
@@ -7392,6 +7408,7 @@ msgid "Optional language the team uses as ISO 639-1 code."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/plugins.py
|
||||
#: lms/djangoapps/teams/templates/teams/teams.html
|
||||
msgid "Teams"
|
||||
msgstr ""
|
||||
|
||||
@@ -7404,11 +7421,11 @@ msgid "course_id must be provided"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/views.py
|
||||
msgid "The supplied topic id {topic_id} is not valid"
|
||||
msgid "text_search and order_by cannot be provided together"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/views.py
|
||||
msgid "text_search is not yet supported."
|
||||
msgid "The supplied topic id {topic_id} is not valid"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: 'ordering' is a string describing a way
|
||||
@@ -9112,6 +9129,10 @@ msgstr ""
|
||||
msgid "Sign Out"
|
||||
msgstr ""
|
||||
|
||||
#: common/lib/capa/capa/templates/codeinput.html
|
||||
msgid "{programming_language} editor"
|
||||
msgstr ""
|
||||
|
||||
#: common/templates/license.html
|
||||
msgid "All Rights Reserved"
|
||||
msgstr ""
|
||||
@@ -11605,7 +11626,9 @@ msgid "Section:"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/courseware/legacy_instructor_dashboard.html
|
||||
msgid "Problem urlname:"
|
||||
msgid ""
|
||||
"To download a CSV listing student responses to a given problem, visit the "
|
||||
"Data Download section of the Instructor Dashboard."
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/courseware/legacy_instructor_dashboard.html
|
||||
@@ -13377,6 +13400,20 @@ msgstr ""
|
||||
msgid "Generate Proctored Exam Results Report"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid ""
|
||||
"To generate a CSV file that lists all student answers to a given problem, "
|
||||
"enter the location of the problem (from its Staff Debug Info)."
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid "Problem location: "
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid "Download a CSV of problem responses"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid ""
|
||||
"For smaller courses, click to list profile information for enrolled students"
|
||||
@@ -15674,41 +15711,50 @@ msgid "This module is not enabled."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"Upon successful completion of your course, learners receive a certificate to"
|
||||
" acknowledge their accomplishment. If you are a course team member with the "
|
||||
"Admin role in Studio, you can configure your course certificate."
|
||||
msgid "Working with Certificates"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"Click {em_start}Add your first certificate{em_end} to add a certificate "
|
||||
"configuration. Upload the organization logo to be used on the certificate, "
|
||||
"and specify at least one signatory. You can include up to four signatories "
|
||||
"for a certificate. You can also upload a signature image file for each "
|
||||
"signatory. {em_start}Note:{em_end} Signature images are used only for "
|
||||
"verified certificates. Optionally, specify a different course title to use "
|
||||
"on your course certificate. You might want to use a different title if, for "
|
||||
"example, the official course name is too long to display well on a "
|
||||
"certificate."
|
||||
"Specify a course title to use on the certificate if the course's official "
|
||||
"title is too long to be displayed well."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"Select a course mode and click {em_start}Preview Certificate{em_end} to "
|
||||
"preview the certificate that a learner in the selected enrollment track "
|
||||
"would receive. When the certificate is ready for issuing, click "
|
||||
"{em_start}Activate.{em_end} To stop issuing an active certificate, click "
|
||||
"{em_start}Deactivate{em_end}."
|
||||
"For verified certificates, specify between one and four signatories and "
|
||||
"upload the associated images."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
" To edit the certificate configuration, hover over the top right corner of "
|
||||
"the form and click {em_start}Edit{em_end}. To delete a certificate, hover "
|
||||
"over the top right corner of the form and click the delete icon. In general,"
|
||||
" do not delete certificates after a course has started, because some "
|
||||
"certificates might already have been issued to learners."
|
||||
"To edit or delete a certificate before it is activated, hover over the top "
|
||||
"right corner of the form and select {em_start}Edit{em_end} or the delete "
|
||||
"icon."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"To view a sample certificate, choose a course mode and select "
|
||||
"{em_start}Preview Certificate{em_end}."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid "Issuing Certificates to Learners"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"To begin issuing certificates, a course team member with the Admin role "
|
||||
"selects {em_start}Activate{em_end}. Course team members without the Admin "
|
||||
"role cannot edit or delete an activated certificate."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"{em_start}Do not{em_end} delete certificates after a course has started; "
|
||||
"learners who have already earned certificates will no longer be able to "
|
||||
"access them."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
|
||||
Binary file not shown.
@@ -44,8 +44,8 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: edx-platform\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2015-08-21 14:17+0000\n"
|
||||
"PO-Revision-Date: 2015-08-21 02:41+0000\n"
|
||||
"POT-Creation-Date: 2015-09-04 14:06+0000\n"
|
||||
"PO-Revision-Date: 2015-09-04 14:08+0000\n"
|
||||
"Last-Translator: Sarina Canelake <sarina@edx.org>\n"
|
||||
"Language-Team: Hebrew (http://www.transifex.com/open-edx/edx-platform/language/he/)\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
@@ -91,8 +91,8 @@ msgstr ""
|
||||
#: cms/static/js/views/show_textbook.js cms/static/js/views/validation.js
|
||||
#: cms/static/js/views/modals/base_modal.js
|
||||
#: cms/static/js/views/modals/course_outline_modals.js
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
#: cms/templates/js/add-xblock-component-menu-problem.underscore
|
||||
#: cms/templates/js/add-xblock-component-menu.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
@@ -103,6 +103,11 @@ msgstr ""
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
#: cms/templates/js/section-name-edit.underscore
|
||||
#: cms/templates/js/xblock-string-field-editor.underscore
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
#: common/static/common/templates/discussion/response-comment-edit.underscore
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
#: common/static/common/templates/discussion/thread-response-edit.underscore
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
#: lms/templates/instructor/instructor_dashboard_2/cohort-form.underscore
|
||||
msgid "Cancel"
|
||||
msgstr ""
|
||||
@@ -123,6 +128,7 @@ msgstr ""
|
||||
#: cms/templates/js/show-textbook.underscore
|
||||
#: cms/templates/js/signatory-editor.underscore
|
||||
#: cms/templates/js/xblock-outline.underscore
|
||||
#: common/static/common/templates/discussion/forum-action-delete.underscore
|
||||
msgid "Delete"
|
||||
msgstr ""
|
||||
|
||||
@@ -203,6 +209,8 @@ msgstr ""
|
||||
#: cms/static/js/views/modals/edit_xblock.js
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: cms/templates/js/signatory-editor.underscore
|
||||
#: common/static/common/templates/image-modal.underscore
|
||||
#: common/static/common/templates/discussion/forum-action-close.underscore
|
||||
msgid "Close"
|
||||
msgstr ""
|
||||
|
||||
@@ -292,6 +300,8 @@ msgstr ""
|
||||
|
||||
#: common/lib/xmodule/xmodule/js/src/combinedopenended/display.js
|
||||
#: lms/static/coffee/src/staff_grading/staff_grading.js
|
||||
#: common/static/common/templates/discussion/thread-response.underscore
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
#: lms/templates/verify_student/incourse_reverify.underscore
|
||||
msgid "Submit"
|
||||
msgstr ""
|
||||
@@ -726,6 +736,7 @@ msgstr ""
|
||||
#: cms/templates/js/show-textbook.underscore
|
||||
#: cms/templates/js/signatory-details.underscore
|
||||
#: cms/templates/js/xblock-string-field-editor.underscore
|
||||
#: common/static/common/templates/discussion/forum-action-edit.underscore
|
||||
msgid "Edit"
|
||||
msgstr ""
|
||||
|
||||
@@ -813,9 +824,11 @@ msgstr ""
|
||||
msgid "Formats"
|
||||
msgstr ""
|
||||
|
||||
#. #-#-#-#-# djangojs-partial.po (edx-platform) #-#-#-#-#
|
||||
#. Translators: this is a message from the raw HTML editor displayed in the
|
||||
#. browser when a user needs to edit HTML
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: common/static/common/templates/image-modal.underscore
|
||||
msgid "Fullscreen"
|
||||
msgstr ""
|
||||
|
||||
@@ -1131,6 +1144,8 @@ msgstr ""
|
||||
#. browser when a user needs to edit HTML
|
||||
#: common/lib/xmodule/xmodule/js/src/html/edit.js
|
||||
#: cms/templates/js/paging-header.underscore
|
||||
#: common/static/common/templates/components/paging-footer.underscore
|
||||
#: common/static/common/templates/discussion/pagination.underscore
|
||||
msgid "Next"
|
||||
msgstr ""
|
||||
|
||||
@@ -1840,6 +1855,7 @@ msgstr ""
|
||||
#: common/static/coffee/src/discussion/utils.js
|
||||
#: common/static/coffee/src/discussion/views/discussion_thread_list_view.js
|
||||
#: common/static/coffee/src/discussion/views/discussion_topic_menu_view.js
|
||||
#: common/static/common/templates/discussion/pagination.underscore
|
||||
msgid "…"
|
||||
msgstr ""
|
||||
|
||||
@@ -2014,6 +2030,8 @@ msgid "Your post will be discarded."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/coffee/src/discussion/views/response_comment_show_view.js
|
||||
#: common/static/common/templates/discussion/post-user-display.underscore
|
||||
#: common/static/common/templates/discussion/profile-thread.underscore
|
||||
msgid "anonymous"
|
||||
msgstr ""
|
||||
|
||||
@@ -2029,6 +2047,18 @@ msgstr ""
|
||||
msgid "Are you sure you want to delete this response?"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
msgid "Required field."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
msgid "Please do not use any spaces in this field."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/js/components/utils/view_utils.js
|
||||
msgid "Please do not use any spaces or special characters in this field."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/js/components/views/paging_header.js
|
||||
msgid "Showing %(first_index)s out of %(num_items)s total"
|
||||
msgstr ""
|
||||
@@ -2194,6 +2224,7 @@ msgstr ""
|
||||
|
||||
#: common/static/js/vendor/ova/catch/js/catch.js
|
||||
#: lms/static/js/courseware/credit_progress.js
|
||||
#: common/static/common/templates/discussion/forum-actions.underscore
|
||||
#: lms/templates/discovery/facet.underscore
|
||||
#: lms/templates/edxnotes/note-item.underscore
|
||||
msgid "More"
|
||||
@@ -2212,6 +2243,8 @@ msgid "Public"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/js/vendor/ova/catch/js/catch.js
|
||||
#: common/static/common/templates/components/search-field.underscore
|
||||
#: lms/djangoapps/support/static/support/templates/certificates.underscore
|
||||
msgid "Search"
|
||||
msgstr ""
|
||||
|
||||
@@ -2273,13 +2306,16 @@ msgid "An unexpected error occurred. Please try again."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/team.js
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/topic.js
|
||||
#: lms/templates/edxnotes/tab-item.underscore
|
||||
msgid "name"
|
||||
msgid "last activity"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/team.js
|
||||
msgid "open_slots"
|
||||
msgid "open slots"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/collections/topic.js
|
||||
#: lms/templates/edxnotes/tab-item.underscore
|
||||
msgid "name"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This refers to the number of teams (a count of how many teams
|
||||
@@ -2288,6 +2324,17 @@ msgstr ""
|
||||
msgid "team count"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
#: cms/templates/js/content-group-editor.underscore
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
msgid "Update"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
msgid "Team Name (Required) *"
|
||||
msgstr ""
|
||||
@@ -2312,6 +2359,7 @@ msgid "Language"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid ""
|
||||
"The language that team members primarily use to communicate with each other."
|
||||
msgstr ""
|
||||
@@ -2322,6 +2370,7 @@ msgid "Country"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/edit_team.js
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "The country that team members primarily identify with."
|
||||
msgstr ""
|
||||
|
||||
@@ -2354,20 +2403,48 @@ msgstr ""
|
||||
msgid "You are not currently a member of any team."
|
||||
msgstr ""
|
||||
|
||||
#. Translators: "and others" refers to fact that additional members of a team
|
||||
#. exist that are not displayed.
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_card.js
|
||||
msgid "and others"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: 'date' is a placeholder for a fuzzy, relative timestamp (see:
|
||||
#. https://github.com/rmm5t/jquery-timeago)
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_card.js
|
||||
msgid "Last Activity %(date)s"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_card.js
|
||||
msgid "View %(span_start)s %(team_name)s %(span_end)s"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_join.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile_header_actions.js
|
||||
msgid "An error occurred. Try again."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_join.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
msgid "Leave this team?"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
msgid ""
|
||||
"If you leave, you can no longer post in this team's discussions. Your place "
|
||||
"will be available to another learner."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile.js
|
||||
#: lms/static/js/verify_student/views/reverify_view.js
|
||||
#: lms/templates/verify_student/review_photos_step.underscore
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile_header_actions.js
|
||||
msgid "You already belong to another team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_join.js
|
||||
#: lms/djangoapps/teams/static/teams/js/views/team_profile_header_actions.js
|
||||
msgid "This team is full."
|
||||
msgstr ""
|
||||
|
||||
@@ -2386,13 +2463,13 @@ msgid "teams"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"See all teams in your course, organized by topic. Join a team to collaborate"
|
||||
" with other learners who are interested in the same topic as you are."
|
||||
msgid "Teams"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Teams"
|
||||
msgid ""
|
||||
"See all teams in your course, organized by topic. Join a team to collaborate"
|
||||
" with other learners who are interested in the same topic as you are."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
@@ -2400,22 +2477,47 @@ msgid "My Team"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: sr_start and sr_end surround text meant only for screen
|
||||
#. readers. The whole string will be shown to users as "Browse teams" if they
|
||||
#. are using a screenreader, and "Browse" otherwise.
|
||||
#. readers.
|
||||
#. The whole string will be shown to users as "Browse teams" if they are using
|
||||
#. a
|
||||
#. screenreader, and "Browse" otherwise.
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Browse %(sr_start)s teams %(sr_end)s"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"Create a new team if you can't find existing teams to join, or if you would "
|
||||
"like to learn with friends you know."
|
||||
msgid "Team Search"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Showing results for \"%(searchString)s\""
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Create a New Team"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"Create a new team if you can't find an existing team to join, or if you "
|
||||
"would like to learn with friends you know."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile-header-actions.underscore
|
||||
msgid "Edit Team"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid ""
|
||||
"If you make significant changes, make sure you notify members of the team "
|
||||
"before making these changes."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "Search teams"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/teams_tab.js
|
||||
msgid "All Topics"
|
||||
msgstr ""
|
||||
@@ -2438,15 +2540,27 @@ msgid_plural "%(team_count)s Teams"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topic_card.js
|
||||
msgid "Topic"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topic_card.js
|
||||
msgid "View Teams in the %(topic_name)s Topic"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: this string is shown at the bottom of the teams page
|
||||
#. to find a team to join or else to create a new one. There are three
|
||||
#. links that need to be included in the message:
|
||||
#. 1. Browse teams in other topics
|
||||
#. 2. search teams
|
||||
#. 3. create a new team
|
||||
#. Be careful to start each link with the appropriate start indicator
|
||||
#. (e.g. {browse_span_start} for #1) and finish it with {span_end}.
|
||||
#: lms/djangoapps/teams/static/teams/js/views/topic_teams.js
|
||||
msgid ""
|
||||
"Try {browse_span_start}browsing all teams{span_end} or "
|
||||
"{search_span_start}searching team descriptions{span_end}. If you still can't"
|
||||
" find a team to join, {create_span_start}create a new team in this "
|
||||
"{browse_span_start}Browse teams in other topics{span_end} or "
|
||||
"{search_span_start}search teams{span_end} in this topic. If you still can't "
|
||||
"find a team to join, {create_span_start}create a new team in this "
|
||||
"topic{span_end}."
|
||||
msgstr ""
|
||||
|
||||
@@ -3784,11 +3898,6 @@ msgstr ""
|
||||
msgid "Review your info"
|
||||
msgstr ""
|
||||
|
||||
#: lms/static/js/verify_student/views/reverify_view.js
|
||||
#: lms/templates/verify_student/review_photos_step.underscore
|
||||
msgid "Confirm"
|
||||
msgstr ""
|
||||
|
||||
#: lms/static/js/verify_student/views/step_view.js
|
||||
msgid "An error has occurred. Please try reloading the page."
|
||||
msgstr ""
|
||||
@@ -4151,6 +4260,7 @@ msgstr ""
|
||||
|
||||
#: cms/static/js/factories/manage_users.js
|
||||
#: cms/static/js/factories/manage_users_lib.js
|
||||
#: common/static/common/templates/discussion/post-user-display.underscore
|
||||
msgid "Staff"
|
||||
msgstr ""
|
||||
|
||||
@@ -4334,6 +4444,7 @@ msgid "Date Added"
|
||||
msgstr ""
|
||||
|
||||
#: cms/static/js/views/assets.js cms/templates/js/asset-library.underscore
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Type"
|
||||
msgstr ""
|
||||
|
||||
@@ -4890,18 +5001,6 @@ msgid ""
|
||||
"more than <%=limit%> characters."
|
||||
msgstr ""
|
||||
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
msgid "Required field."
|
||||
msgstr ""
|
||||
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
msgid "Please do not use any spaces in this field."
|
||||
msgstr ""
|
||||
|
||||
#: cms/static/js/views/utils/view_utils.js
|
||||
msgid "Please do not use any spaces or special characters in this field."
|
||||
msgstr ""
|
||||
|
||||
#: cms/static/js/views/utils/xblock_utils.js
|
||||
msgid "component"
|
||||
msgstr ""
|
||||
@@ -4991,11 +5090,526 @@ msgstr ""
|
||||
msgid "Due Date"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/paging-header.underscore
|
||||
#: common/static/common/templates/components/paging-footer.underscore
|
||||
#: common/static/common/templates/discussion/pagination.underscore
|
||||
msgid "Previous"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/previous-video-upload-list.underscore
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
#: lms/templates/verify_student/enrollment_confirmation_step.underscore
|
||||
msgid "Status"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/image-modal.underscore
|
||||
msgid "Large"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/image-modal.underscore
|
||||
msgid "Zoom In"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/image-modal.underscore
|
||||
msgid "Zoom Out"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/paging-footer.underscore
|
||||
msgid "Page number"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/paging-footer.underscore
|
||||
msgid "Enter the page number you'd like to quickly navigate to."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/paging-header.underscore
|
||||
msgid "Sorted by"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/components/search-field.underscore
|
||||
msgid "Clear search"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "DISCUSSION HOME:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
#: lms/templates/commerce/provider.underscore
|
||||
#: lms/templates/commerce/receipt.underscore
|
||||
#: lms/templates/discovery/course_card.underscore
|
||||
msgid "gettext("
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Find discussions"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Focus in on specific topics"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Search for specific posts"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Sort by date, vote, or comments"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Engage with posts"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Upvote posts and good responses"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Report Forum Misuse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Follow posts for updates"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Receive updates"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid "Toggle Notifications Setting"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/discussion-home.underscore
|
||||
msgid ""
|
||||
"Check this box to receive an email digest once a day notifying you about "
|
||||
"new, unread activity from posts you are following."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-answer.underscore
|
||||
msgid "Mark as Answer"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-answer.underscore
|
||||
msgid "Unmark as Answer"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-close.underscore
|
||||
msgid "Open"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-endorse.underscore
|
||||
msgid "Endorse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-endorse.underscore
|
||||
msgid "Unendorse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-follow.underscore
|
||||
msgid "Follow"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-follow.underscore
|
||||
msgid "Unfollow"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-pin.underscore
|
||||
msgid "Pin"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-pin.underscore
|
||||
msgid "Unpin"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-report.underscore
|
||||
msgid "Report abuse"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-report.underscore
|
||||
msgid "Report"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-report.underscore
|
||||
msgid "Unreport"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/forum-action-vote.underscore
|
||||
msgid "Vote for this post,"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Visible To:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "All Groups"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid ""
|
||||
"Discussion admins, moderators, and TAs can make their posts visible to all "
|
||||
"students or specify a single cohort."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Title:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Add a clear and descriptive title to encourage participation."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Enter your question or comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "follow this post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "post anonymously"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "post anonymously to classmates"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/new-post.underscore
|
||||
msgid "Add Post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/post-user-display.underscore
|
||||
msgid "Community TA"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/profile-thread.underscore
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "This thread is closed."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/profile-thread.underscore
|
||||
msgid "View discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-edit.underscore
|
||||
msgid "Editing comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-edit.underscore
|
||||
msgid "Update comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-show.underscore
|
||||
#, python-format
|
||||
msgid "posted %(time_ago)s by %(author)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/response-comment-show.underscore
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "Reported"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
msgid "Editing post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
msgid "Edit post title"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-edit.underscore
|
||||
msgid "Update post"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "answered question"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "unanswered question"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "Pinned"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "Following"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "By: Staff"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
msgid "By: Community TA"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
msgid "fmt"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#, python-format
|
||||
msgid ""
|
||||
"%(comments_count)s %(span_sr_open)scomments (%(unread_comments_count)s "
|
||||
"unread comments)%(span_close)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-list-item.underscore
|
||||
#, python-format
|
||||
msgid "%(comments_count)s %(span_sr_open)scomments %(span_close)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-edit.underscore
|
||||
msgid "Editing response"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-edit.underscore
|
||||
msgid "Update response"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "marked as answer %(time_ago)s by %(user)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "marked as answer %(time_ago)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "endorsed %(time_ago)s by %(user)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response-show.underscore
|
||||
#, python-format
|
||||
msgid "endorsed %(time_ago)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response.underscore
|
||||
msgid "fmts"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-response.underscore
|
||||
msgid "Add a comment"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
#, python-format
|
||||
msgid "This post is visible only to %(group_name)s."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "This post is visible to everyone."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
#, python-format
|
||||
msgid "%(post_type)s posted %(time_ago)s by %(author)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
msgid "Closed"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-show.underscore
|
||||
#, python-format
|
||||
msgid "Related to: %(courseware_title_linked)s"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid "Post type:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid "Question"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid "Discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread-type.underscore
|
||||
msgid ""
|
||||
"Questions raise issues that need answers. Discussions share ideas and start "
|
||||
"conversations."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Add a Response"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Post a response:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Expand discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/thread.underscore
|
||||
msgid "Collapse discussion"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Topic Area:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Discussion topics; current selection is:"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Filter topics"
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/topic.underscore
|
||||
msgid "Add your post to a relevant topic to help others find it."
|
||||
msgstr ""
|
||||
|
||||
#: common/static/common/templates/discussion/user-profile.underscore
|
||||
msgid "Active Threads"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates.underscore
|
||||
msgid "username or email"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "No results"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Course Key"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Download URL"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Grade"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Last Updated"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Download the user's certificate"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Not available"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Regenerate"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/support/static/support/templates/certificates_results.underscore
|
||||
msgid "Regenerate the user's certificate"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Your team could not be created."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Your team could not be updated."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid ""
|
||||
"Enter information to describe your team. You cannot change these details "
|
||||
"after you create the team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Optional Characteristics"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid ""
|
||||
"Help other learners decide whether to join your team by specifying some "
|
||||
"characteristics for your team. Choose carefully, because fewer people might "
|
||||
"be interested in joining your team if it seems too restrictive."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Create team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Update team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Cancel team creating."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/edit-team.underscore
|
||||
msgid "Cancel team updating."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-actions.underscore
|
||||
msgid "Are you having trouble finding a team to join?"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile-header-actions.underscore
|
||||
msgid "Join Team"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "New Post"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Team Details"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "You are a member of this team."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Team member profiles"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Team capacity"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "country"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "language"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/static/teams/templates/team-profile.underscore
|
||||
msgid "Leave Team"
|
||||
msgstr ""
|
||||
|
||||
#: lms/static/js/fixtures/donation.underscore
|
||||
#: lms/templates/dashboard/donation.underscore
|
||||
msgid "Donate"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/ccx/schedule.underscore
|
||||
msgid "Expand All"
|
||||
msgstr ""
|
||||
@@ -5036,12 +5650,6 @@ msgstr ""
|
||||
msgid "Subsection"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/commerce/provider.underscore
|
||||
#: lms/templates/commerce/receipt.underscore
|
||||
#: lms/templates/discovery/course_card.underscore
|
||||
msgid "gettext("
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/commerce/provider.underscore
|
||||
#, python-format
|
||||
msgid "<img src='%s' alt='%s'></image>"
|
||||
@@ -5131,10 +5739,6 @@ msgstr ""
|
||||
msgid "End My Exam"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/dashboard/donation.underscore
|
||||
msgid "Donate"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/discovery/course_card.underscore
|
||||
msgid "LEARN MORE"
|
||||
msgstr ""
|
||||
@@ -6051,6 +6655,16 @@ msgstr ""
|
||||
msgid "status"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/add-xblock-component-button.underscore
|
||||
msgid "Add Component:"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/add-xblock-component-menu-problem.underscore
|
||||
#: cms/templates/js/add-xblock-component-menu.underscore
|
||||
#, python-format
|
||||
msgid "%(type)s Component Template Menu"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/add-xblock-component-menu-problem.underscore
|
||||
msgid "Common Problem Types"
|
||||
msgstr ""
|
||||
@@ -6125,6 +6739,11 @@ msgstr ""
|
||||
msgid "Certificate Details"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "Course Title"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/certificate-details.underscore
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "Course Title Override"
|
||||
@@ -6169,19 +6788,13 @@ msgid ""
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "Add Signatory"
|
||||
msgid "Add Additional Signatory"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
msgid "(Up to 4 signatories are allowed for a certificate)"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/certificate-editor.underscore
|
||||
#: cms/templates/js/content-group-editor.underscore
|
||||
#: cms/templates/js/group-configuration-editor.underscore
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/certificate-web-preview.underscore
|
||||
msgid "Choose mode"
|
||||
msgstr ""
|
||||
@@ -6606,10 +7219,6 @@ msgstr ""
|
||||
msgid "Add your first textbook"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/paging-header.underscore
|
||||
msgid "Previous"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/js/previous-video-upload-list.underscore
|
||||
msgid "Previous Uploads"
|
||||
msgstr ""
|
||||
|
||||
Binary file not shown.
@@ -72,7 +72,7 @@ msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: edx-platform\n"
|
||||
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
|
||||
"POT-Creation-Date: 2015-08-21 14:18+0000\n"
|
||||
"POT-Creation-Date: 2015-09-04 14:07+0000\n"
|
||||
"PO-Revision-Date: 2015-06-28 20:21+0000\n"
|
||||
"Last-Translator: ria1234 <contactpayal@yahoo.com.au>\n"
|
||||
"Language-Team: Hindi (http://www.transifex.com/open-edx/edx-platform/language/hi/)\n"
|
||||
@@ -1227,10 +1227,6 @@ msgstr ""
|
||||
msgid "incorrect"
|
||||
msgstr ""
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "partially correct"
|
||||
msgstr ""
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "incomplete"
|
||||
msgstr ""
|
||||
@@ -1253,10 +1249,6 @@ msgstr ""
|
||||
msgid "This is incorrect."
|
||||
msgstr ""
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "This is partially correct."
|
||||
msgstr ""
|
||||
|
||||
#: common/lib/capa/capa/inputtypes.py
|
||||
msgid "This is unanswered."
|
||||
msgstr ""
|
||||
@@ -4587,7 +4579,14 @@ msgid "{month} {day}, {year}"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid "a course of study offered by {partner_name}, through {platform_name}."
|
||||
msgid ""
|
||||
"a course of study offered by {partner_short_name}, an online learning "
|
||||
"initiative of {partner_long_name} through {platform_name}."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid ""
|
||||
"a course of study offered by {partner_short_name}, through {platform_name}."
|
||||
msgstr ""
|
||||
|
||||
#. Translators: Accomplishments describe the awards/certifications obtained by
|
||||
@@ -4687,13 +4686,13 @@ msgstr ""
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid ""
|
||||
"This is a valid {platform_name} certificate for {user_name}, who "
|
||||
"participated in {partner_name} {course_number}"
|
||||
"participated in {partner_short_name} {course_number}"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This text is bound to the HTML 'title' element of the page
|
||||
#. and appears in the browser title bar
|
||||
#: lms/djangoapps/certificates/views/webview.py
|
||||
msgid "{partner_name} {course_number} Certificate | {platform_name}"
|
||||
msgid "{partner_short_name} {course_number} Certificate | {platform_name}"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This text fragment appears after the student's name
|
||||
@@ -4849,6 +4848,14 @@ msgid ""
|
||||
"{payment_support_link}."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/commerce/api/v1/serializers.py
|
||||
msgid "{course_id} is not a valid course key."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/commerce/api/v1/serializers.py
|
||||
msgid "Course {course_id} does not exist."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/course_wiki/tab.py lms/djangoapps/course_wiki/views.py
|
||||
#: lms/templates/wiki/base.html
|
||||
msgid "Wiki"
|
||||
@@ -5384,6 +5391,23 @@ msgstr ""
|
||||
msgid "File is not attached."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid "Could not find problem with this location."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid ""
|
||||
"The problem responses report is being created. To view the status of the "
|
||||
"report, see Pending Tasks below."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid ""
|
||||
"A problem responses report generation task is already in progress. Check the"
|
||||
" 'Pending Tasks' table for the status of the task. When completed, the "
|
||||
"report will be available for download in the table below."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/api.py
|
||||
msgid "Invoice number '{num}' does not exist."
|
||||
msgstr ""
|
||||
@@ -5770,6 +5794,10 @@ msgstr ""
|
||||
msgid "CourseMode price updated successfully"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/instructor_dashboard.py
|
||||
msgid "No end date set"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/instructor_dashboard.py
|
||||
msgid "Enrollment data is now available in {dashboard_link}."
|
||||
msgstr ""
|
||||
@@ -5865,18 +5893,6 @@ msgstr ""
|
||||
msgid "Grades for assignment \"{name}\""
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Found {num} records to dump."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Couldn't find module with that urlname."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Student state for problem {problem}"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/instructor/views/legacy.py
|
||||
msgid "Grades from {course_id}"
|
||||
msgstr ""
|
||||
@@ -6040,6 +6056,12 @@ msgstr "नष्ट कर दिया गया"
|
||||
msgid "emailed"
|
||||
msgstr "ईमेल कर दी गई"
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
msgid "generated"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
@@ -6052,12 +6074,6 @@ msgstr "श्रेणी दी जा चुकी है"
|
||||
msgid "problem distribution graded"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
msgid "generated"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: This is a past-tense verb that is inserted into task progress
|
||||
#. messages as {action}.
|
||||
#: lms/djangoapps/instructor_task/tasks.py
|
||||
@@ -7517,6 +7533,7 @@ msgid "Optional language the team uses as ISO 639-1 code."
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/plugins.py
|
||||
#: lms/djangoapps/teams/templates/teams/teams.html
|
||||
msgid "Teams"
|
||||
msgstr ""
|
||||
|
||||
@@ -7529,11 +7546,11 @@ msgid "course_id must be provided"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/views.py
|
||||
msgid "The supplied topic id {topic_id} is not valid"
|
||||
msgid "text_search and order_by cannot be provided together"
|
||||
msgstr ""
|
||||
|
||||
#: lms/djangoapps/teams/views.py
|
||||
msgid "text_search is not yet supported."
|
||||
msgid "The supplied topic id {topic_id} is not valid"
|
||||
msgstr ""
|
||||
|
||||
#. Translators: 'ordering' is a string describing a way
|
||||
@@ -9269,6 +9286,10 @@ msgstr "सहायता"
|
||||
msgid "Sign Out"
|
||||
msgstr ""
|
||||
|
||||
#: common/lib/capa/capa/templates/codeinput.html
|
||||
msgid "{programming_language} editor"
|
||||
msgstr ""
|
||||
|
||||
#: common/templates/license.html
|
||||
msgid "All Rights Reserved"
|
||||
msgstr ""
|
||||
@@ -11836,8 +11857,10 @@ msgid "Section:"
|
||||
msgstr "धारा:"
|
||||
|
||||
#: lms/templates/courseware/legacy_instructor_dashboard.html
|
||||
msgid "Problem urlname:"
|
||||
msgstr "समस्या का यू आर एल दें:"
|
||||
msgid ""
|
||||
"To download a CSV listing student responses to a given problem, visit the "
|
||||
"Data Download section of the Instructor Dashboard."
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/courseware/legacy_instructor_dashboard.html
|
||||
msgid ""
|
||||
@@ -13650,6 +13673,20 @@ msgstr ""
|
||||
msgid "Generate Proctored Exam Results Report"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid ""
|
||||
"To generate a CSV file that lists all student answers to a given problem, "
|
||||
"enter the location of the problem (from its Staff Debug Info)."
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid "Problem location: "
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid "Download a CSV of problem responses"
|
||||
msgstr ""
|
||||
|
||||
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
|
||||
msgid ""
|
||||
"For smaller courses, click to list profile information for enrolled students"
|
||||
@@ -16013,41 +16050,50 @@ msgid "This module is not enabled."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"Upon successful completion of your course, learners receive a certificate to"
|
||||
" acknowledge their accomplishment. If you are a course team member with the "
|
||||
"Admin role in Studio, you can configure your course certificate."
|
||||
msgid "Working with Certificates"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"Click {em_start}Add your first certificate{em_end} to add a certificate "
|
||||
"configuration. Upload the organization logo to be used on the certificate, "
|
||||
"and specify at least one signatory. You can include up to four signatories "
|
||||
"for a certificate. You can also upload a signature image file for each "
|
||||
"signatory. {em_start}Note:{em_end} Signature images are used only for "
|
||||
"verified certificates. Optionally, specify a different course title to use "
|
||||
"on your course certificate. You might want to use a different title if, for "
|
||||
"example, the official course name is too long to display well on a "
|
||||
"certificate."
|
||||
"Specify a course title to use on the certificate if the course's official "
|
||||
"title is too long to be displayed well."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"Select a course mode and click {em_start}Preview Certificate{em_end} to "
|
||||
"preview the certificate that a learner in the selected enrollment track "
|
||||
"would receive. When the certificate is ready for issuing, click "
|
||||
"{em_start}Activate.{em_end} To stop issuing an active certificate, click "
|
||||
"{em_start}Deactivate{em_end}."
|
||||
"For verified certificates, specify between one and four signatories and "
|
||||
"upload the associated images."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
" To edit the certificate configuration, hover over the top right corner of "
|
||||
"the form and click {em_start}Edit{em_end}. To delete a certificate, hover "
|
||||
"over the top right corner of the form and click the delete icon. In general,"
|
||||
" do not delete certificates after a course has started, because some "
|
||||
"certificates might already have been issued to learners."
|
||||
"To edit or delete a certificate before it is activated, hover over the top "
|
||||
"right corner of the form and select {em_start}Edit{em_end} or the delete "
|
||||
"icon."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"To view a sample certificate, choose a course mode and select "
|
||||
"{em_start}Preview Certificate{em_end}."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid "Issuing Certificates to Learners"
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"To begin issuing certificates, a course team member with the Admin role "
|
||||
"selects {em_start}Activate{em_end}. Course team members without the Admin "
|
||||
"role cannot edit or delete an activated certificate."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
msgid ""
|
||||
"{em_start}Do not{em_end} delete certificates after a course has started; "
|
||||
"learners who have already earned certificates will no longer be able to "
|
||||
"access them."
|
||||
msgstr ""
|
||||
|
||||
#: cms/templates/certificates.html
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user