Merge pull request #9835 from edx/rc/2015-09-22

Release candidate for 2015 09 22
This commit is contained in:
Brian Beggs
2015-09-23 12:39:23 -04:00
199 changed files with 2189 additions and 1766 deletions

View File

@@ -239,3 +239,4 @@ Mirjam Škarica <mirjamskarica@gmail.com>
Saleem Latif <saleem@edx.org>
Julien Paillé <julien.paille@openfun.fr>
Michael Frey <mfrey@edx.org>
Hasnain Naveed <hasnain@edx.org>

View File

@@ -1,53 +0,0 @@
@shard_1
Feature: CMS.Help
As a course author, I am able to access online help
Scenario: Users can access online help on course listing page
Given There are no courses
And I am logged into Studio
Then I should see online help for "get_started"
Scenario: Users can access online help within a course
Given I have opened a new course in Studio
And I click the course link in Studio Home
Then I should see online help for "outline"
And I go to the course updates page
Then I should see online help for "updates"
And I go to the pages page
Then I should see online help for "pages"
And I go to the files and uploads page
Then I should see online help for "files"
And I go to the textbooks page
Then I should see online help for "textbooks"
And I select Schedule and Details
Then I should see online help for "setting_up"
And I am viewing the grading settings
Then I should see online help for "grading"
And I am viewing the course team settings
Then I should see online help for "course-team"
And I select the Advanced Settings
Then I should see online help for "index"
And I select Checklists from the Tools menu
Then I should see online help for "checklist"
And I go to the import page
Then I should see online help for "import"
And I go to the export page
Then I should see online help for "export"
Scenario: Users can access online help on the unit page
Given I am in Studio editing a new unit
Then I should see online help for "units"

View File

@@ -1,24 +0,0 @@
# pylint: disable=missing-docstring
# pylint: disable=redefined-outer-name
# pylint: disable=unused-argument
from nose.tools import assert_false # pylint: disable=no-name-in-module
from lettuce import step, world
@step(u'I should see online help for "([^"]*)"$')
def see_online_help_for(step, page_name):
# make sure the online Help link exists on this page and contains the expected page name
elements_found = world.browser.find_by_xpath(
'//li[contains(@class, "nav-account-help")]//a[contains(@href, "{page_name}")]'.format(
page_name=page_name
)
)
assert_false(elements_found.is_empty())
# make sure the PDF link on the sock of this page exists
# for now, the PDF link stays constant for all the pages so we just check for "pdf"
elements_found = world.browser.find_by_xpath(
'//section[contains(@class, "sock")]//li[contains(@class, "js-help-pdf")]//a[contains(@href, "pdf")]'
)
assert_false(elements_found.is_empty())

View File

@@ -16,6 +16,9 @@ from models.settings.course_details import (CourseDetails, CourseSettingsEncoder
from models.settings.course_grading import CourseGradingModel
from contentstore.utils import reverse_course_url, reverse_usage_url
from xmodule.modulestore.tests.factories import CourseFactory
from student.roles import CourseInstructorRole
from student.tests.factories import UserFactory
from models.settings.course_metadata import CourseMetadata
from xmodule.fields import Date
@@ -1106,3 +1109,116 @@ class CourseGraderUpdatesTest(CourseTestCase):
self.assertEqual(obj, grader)
current_graders = CourseGradingModel.fetch(self.course.id).graders
self.assertEqual(len(self.starting_graders) + 1, len(current_graders))
class CourseEnrollmentEndFieldTest(CourseTestCase):
"""
Base class to test the enrollment end fields in the course settings details view in Studio
when using marketing site flag and global vs non-global staff to access the page.
"""
NOT_EDITABLE_HELPER_MESSAGE = "Contact your edX Partner Manager to update these settings."
NOT_EDITABLE_DATE_WRAPPER = "<div class=\"field date is-not-editable\" id=\"field-enrollment-end-date\">"
NOT_EDITABLE_TIME_WRAPPER = "<div class=\"field time is-not-editable\" id=\"field-enrollment-end-time\">"
NOT_EDITABLE_DATE_FIELD = "<input type=\"text\" class=\"end-date date end\" \
id=\"course-enrollment-end-date\" placeholder=\"MM/DD/YYYY\" autocomplete=\"off\" readonly aria-readonly=\"true\" />"
NOT_EDITABLE_TIME_FIELD = "<input type=\"text\" class=\"time end\" id=\"course-enrollment-end-time\" \
value=\"\" placeholder=\"HH:MM\" autocomplete=\"off\" readonly aria-readonly=\"true\" />"
EDITABLE_DATE_WRAPPER = "<div class=\"field date \" id=\"field-enrollment-end-date\">"
EDITABLE_TIME_WRAPPER = "<div class=\"field time \" id=\"field-enrollment-end-time\">"
EDITABLE_DATE_FIELD = "<input type=\"text\" class=\"end-date date end\" \
id=\"course-enrollment-end-date\" placeholder=\"MM/DD/YYYY\" autocomplete=\"off\" />"
EDITABLE_TIME_FIELD = "<input type=\"text\" class=\"time end\" \
id=\"course-enrollment-end-time\" value=\"\" placeholder=\"HH:MM\" autocomplete=\"off\" />"
EDITABLE_ELEMENTS = [
EDITABLE_DATE_WRAPPER,
EDITABLE_TIME_WRAPPER,
EDITABLE_DATE_FIELD,
EDITABLE_TIME_FIELD,
]
NOT_EDITABLE_ELEMENTS = [
NOT_EDITABLE_HELPER_MESSAGE,
NOT_EDITABLE_DATE_WRAPPER,
NOT_EDITABLE_TIME_WRAPPER,
NOT_EDITABLE_DATE_FIELD,
NOT_EDITABLE_TIME_FIELD,
]
def setUp(self):
""" Initialize course used to test enrollment fields. """
super(CourseEnrollmentEndFieldTest, self).setUp()
self.course = CourseFactory.create(org='edX', number='dummy', display_name='Marketing Site Course')
self.course_details_url = reverse_course_url('settings_handler', unicode(self.course.id))
def _get_course_details_response(self, global_staff):
""" Return the course details page as either global or non-global staff"""
user = UserFactory(is_staff=global_staff)
CourseInstructorRole(self.course.id).add_users(user)
self.client.login(username=user.username, password='test')
return self.client.get_html(self.course_details_url)
def _verify_editable(self, response):
""" Verify that the response has expected editable fields.
Assert that all editable field content exists and no
uneditable field content exists for enrollment end fields.
"""
self.assertEqual(response.status_code, 200)
for element in self.NOT_EDITABLE_ELEMENTS:
self.assertNotContains(response, element)
for element in self.EDITABLE_ELEMENTS:
self.assertContains(response, element)
def _verify_not_editable(self, response):
""" Verify that the response has expected non-editable fields.
Assert that all uneditable field content exists and no
editable field content exists for enrollment end fields.
"""
self.assertEqual(response.status_code, 200)
for element in self.NOT_EDITABLE_ELEMENTS:
self.assertContains(response, element)
for element in self.EDITABLE_ELEMENTS:
self.assertNotContains(response, element)
@mock.patch.dict("django.conf.settings.FEATURES", {'ENABLE_MKTG_SITE': False})
def test_course_details_with_disabled_setting_global_staff(self):
""" Test that user enrollment end date is editable in response.
Feature flag 'ENABLE_MKTG_SITE' is not enabled.
User is global staff.
"""
self._verify_editable(self._get_course_details_response(True))
@mock.patch.dict("django.conf.settings.FEATURES", {'ENABLE_MKTG_SITE': False})
def test_course_details_with_disabled_setting_non_global_staff(self):
""" Test that user enrollment end date is editable in response.
Feature flag 'ENABLE_MKTG_SITE' is not enabled.
User is non-global staff.
"""
self._verify_editable(self._get_course_details_response(False))
@mock.patch.dict("django.conf.settings.FEATURES", {'ENABLE_MKTG_SITE': True})
def test_course_details_with_enabled_setting_global_staff(self):
""" Test that user enrollment end date is editable in response.
Feature flag 'ENABLE_MKTG_SITE' is enabled.
User is global staff.
"""
self._verify_editable(self._get_course_details_response(True))
@mock.patch.dict("django.conf.settings.FEATURES", {'ENABLE_MKTG_SITE': True})
def test_course_details_with_enabled_setting_non_global_staff(self):
""" Test that user enrollment end date is not editable in response.
Feature flag 'ENABLE_MKTG_SITE' is enabled.
User is non-global staff.
"""
self._verify_not_editable(self._get_course_details_response(False))

View File

@@ -1,42 +1,21 @@
import unittest
from opaque_keys.edx.locator import LocalId
from xmodule import templates
from xmodule.modulestore import ModuleStoreEnum
from xmodule.modulestore.tests import persistent_factories
from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, TEST_DATA_SPLIT_MODULESTORE
from xmodule.course_module import CourseDescriptor
from xmodule.modulestore.django import modulestore, clear_existing_modulestores
from xmodule.seq_module import SequenceDescriptor
from xmodule.capa_module import CapaDescriptor
from xmodule.contentstore.django import _CONTENTSTORE
from xmodule.modulestore.exceptions import ItemNotFoundError, DuplicateCourseError
from xmodule.html_module import HtmlDescriptor
from xmodule.modulestore.exceptions import DuplicateCourseError
class TemplateTests(unittest.TestCase):
class TemplateTests(ModuleStoreTestCase):
"""
Test finding and using the templates (boilerplates) for xblocks.
"""
def setUp(self):
super(TemplateTests, self).setUp()
clear_existing_modulestores() # redundant w/ cleanup but someone was getting errors
self.addCleanup(self._drop_mongo_collections)
self.addCleanup(clear_existing_modulestores)
self.split_store = modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.split)
@staticmethod
def _drop_mongo_collections():
"""
If using a Mongo-backed modulestore & contentstore, drop the collections.
"""
module_store = modulestore()
if hasattr(module_store, '_drop_database'):
module_store._drop_database() # pylint: disable=protected-access
_CONTENTSTORE.clear()
if hasattr(module_store, 'close_connections'):
module_store.close_connections()
MODULESTORE = TEST_DATA_SPLIT_MODULESTORE
def test_get_templates(self):
found = templates.all_templates()
@@ -69,42 +48,49 @@ class TemplateTests(unittest.TestCase):
self.assertIsNotNone(HtmlDescriptor.get_template('announcement.yaml'))
def test_factories(self):
test_course = persistent_factories.PersistentCourseFactory.create(
course='course', run='2014', org='testx',
display_name='fun test course', user_id='testbot'
test_course = CourseFactory.create(
org='testx',
course='course',
run='2014',
display_name='fun test course',
user_id='testbot'
)
self.assertIsInstance(test_course, CourseDescriptor)
self.assertEqual(test_course.display_name, 'fun test course')
index_info = self.split_store.get_course_index_info(test_course.id)
self.assertEqual(index_info['org'], 'testx')
self.assertEqual(index_info['course'], 'course')
self.assertEqual(index_info['run'], '2014')
course_from_store = self.store.get_course(test_course.id)
self.assertEqual(course_from_store.id.org, 'testx')
self.assertEqual(course_from_store.id.course, 'course')
self.assertEqual(course_from_store.id.run, '2014')
test_chapter = persistent_factories.ItemFactory.create(
display_name='chapter 1',
parent_location=test_course.location
test_chapter = ItemFactory.create(
parent_location=test_course.location,
category='chapter',
display_name='chapter 1'
)
self.assertIsInstance(test_chapter, SequenceDescriptor)
# refetch parent which should now point to child
test_course = self.split_store.get_course(test_course.id.version_agnostic())
test_course = self.store.get_course(test_course.id.version_agnostic())
self.assertIn(test_chapter.location, test_course.children)
with self.assertRaises(DuplicateCourseError):
persistent_factories.PersistentCourseFactory.create(
course='course', run='2014', org='testx',
display_name='fun test course', user_id='testbot'
CourseFactory.create(
org='testx',
course='course',
run='2014',
display_name='fun test course',
user_id='testbot'
)
def test_temporary_xblocks(self):
"""
Test create_xblock to create non persisted xblocks
"""
test_course = persistent_factories.PersistentCourseFactory.create(
test_course = CourseFactory.create(
course='course', run='2014', org='testx',
display_name='fun test course', user_id='testbot'
)
test_chapter = self.split_store.create_xblock(
test_chapter = self.store.create_xblock(
test_course.system, test_course.id, 'chapter', fields={'display_name': 'chapter n'},
parent_xblock=test_course
)
@@ -114,7 +100,7 @@ class TemplateTests(unittest.TestCase):
# test w/ a definition (e.g., a problem)
test_def_content = '<problem>boo</problem>'
test_problem = self.split_store.create_xblock(
test_problem = self.store.create_xblock(
test_course.system, test_course.id, 'problem', fields={'data': test_def_content},
parent_xblock=test_chapter
)
@@ -124,131 +110,28 @@ class TemplateTests(unittest.TestCase):
test_problem.display_name = 'test problem'
self.assertEqual(test_problem.display_name, 'test problem')
def test_persist_dag(self):
"""
try saving temporary xblocks
"""
test_course = persistent_factories.PersistentCourseFactory.create(
course='course', run='2014', org='testx',
display_name='fun test course', user_id='testbot'
)
test_chapter = self.split_store.create_xblock(
test_course.system, test_course.id, 'chapter', fields={'display_name': 'chapter n'},
parent_xblock=test_course
)
self.assertEqual(test_chapter.display_name, 'chapter n')
test_def_content = '<problem>boo</problem>'
# create child
new_block = self.split_store.create_xblock(
test_course.system, test_course.id,
'problem',
fields={
'data': test_def_content,
'display_name': 'problem'
},
parent_xblock=test_chapter
)
self.assertIsNotNone(new_block.definition_locator)
self.assertTrue(isinstance(new_block.definition_locator.definition_id, LocalId))
# better to pass in persisted parent over the subdag so
# subdag gets the parent pointer (otherwise 2 ops, persist dag, update parent children,
# persist parent
persisted_course = self.split_store.persist_xblock_dag(test_course, 'testbot')
self.assertEqual(len(persisted_course.children), 1)
persisted_chapter = persisted_course.get_children()[0]
self.assertEqual(persisted_chapter.category, 'chapter')
self.assertEqual(persisted_chapter.display_name, 'chapter n')
self.assertEqual(len(persisted_chapter.children), 1)
persisted_problem = persisted_chapter.get_children()[0]
self.assertEqual(persisted_problem.category, 'problem')
self.assertEqual(persisted_problem.data, test_def_content)
# update it
persisted_problem.display_name = 'altered problem'
persisted_problem = self.split_store.persist_xblock_dag(persisted_problem, 'testbot')
self.assertEqual(persisted_problem.display_name, 'altered problem')
def test_delete_course(self):
test_course = persistent_factories.PersistentCourseFactory.create(
course='history', run='doomed', org='edu.harvard',
test_course = CourseFactory.create(
org='edu.harvard',
course='history',
run='doomed',
display_name='doomed test course',
user_id='testbot')
persistent_factories.ItemFactory.create(
display_name='chapter 1',
parent_location=test_course.location
ItemFactory.create(
parent_location=test_course.location,
category='chapter',
display_name='chapter 1'
)
id_locator = test_course.id.for_branch(ModuleStoreEnum.BranchName.draft)
guid_locator = test_course.location.course_agnostic()
# verify it can be retrieved by id
self.assertIsInstance(self.split_store.get_course(id_locator), CourseDescriptor)
# and by guid -- TODO reenable when split_draft supports getting specific versions
# self.assertIsInstance(self.split_store.get_item(guid_locator), CourseDescriptor)
self.split_store.delete_course(id_locator, 'testbot')
# test can no longer retrieve by id
self.assertRaises(ItemNotFoundError, self.split_store.get_course, id_locator)
# but can by guid -- same TODO as above
# self.assertIsInstance(self.split_store.get_item(guid_locator), CourseDescriptor)
def test_block_generations(self):
"""
Test get_block_generations
"""
test_course = persistent_factories.PersistentCourseFactory.create(
course='history', run='hist101', org='edu.harvard',
display_name='history test course',
user_id='testbot'
)
chapter = persistent_factories.ItemFactory.create(
display_name='chapter 1',
parent_location=test_course.location,
user_id='testbot'
)
sub = persistent_factories.ItemFactory.create(
display_name='subsection 1',
parent_location=chapter.location,
user_id='testbot',
category='vertical'
)
first_problem = persistent_factories.ItemFactory.create(
display_name='problem 1', parent_location=sub.location, user_id='testbot', category='problem',
data="<problem></problem>"
)
first_problem.max_attempts = 3
first_problem.save() # decache the above into the kvs
updated_problem = self.split_store.update_item(first_problem, 'testbot')
self.assertIsNotNone(updated_problem.previous_version)
self.assertEqual(updated_problem.previous_version, first_problem.update_version)
self.assertNotEqual(updated_problem.update_version, first_problem.update_version)
self.split_store.delete_item(updated_problem.location, 'testbot')
second_problem = persistent_factories.ItemFactory.create(
display_name='problem 2',
parent_location=sub.location.version_agnostic(),
user_id='testbot', category='problem',
data="<problem></problem>"
)
# The draft course root has 2 revisions: the published revision, and then the subsequent
# changes to the draft revision
version_history = self.split_store.get_block_generations(test_course.location)
self.assertIsNotNone(version_history)
self.assertEqual(version_history.locator.version_guid, test_course.location.version_guid)
self.assertEqual(len(version_history.children), 1)
self.assertEqual(version_history.children[0].children, [])
self.assertEqual(version_history.children[0].locator.version_guid, chapter.location.version_guid)
# sub changed on add, add problem, delete problem, add problem in strict linear seq
version_history = self.split_store.get_block_generations(sub.location)
self.assertEqual(len(version_history.children), 1)
self.assertEqual(len(version_history.children[0].children), 1)
self.assertEqual(len(version_history.children[0].children[0].children), 1)
self.assertEqual(len(version_history.children[0].children[0].children[0].children), 0)
# first and second problem may show as same usage_id; so, need to ensure their histories are right
version_history = self.split_store.get_block_generations(updated_problem.location)
self.assertEqual(version_history.locator.version_guid, first_problem.location.version_guid)
self.assertEqual(len(version_history.children), 1) # updated max_attempts
self.assertEqual(len(version_history.children[0].children), 0)
version_history = self.split_store.get_block_generations(second_problem.location)
self.assertNotEqual(version_history.locator.version_guid, first_problem.location.version_guid)
self.assertIsInstance(self.store.get_course(id_locator), CourseDescriptor)
# TODO reenable when split_draft supports getting specific versions
# guid_locator = test_course.location.course_agnostic()
# Verify it can be retrieved by guid
# self.assertIsInstance(self.store.get_item(guid_locator), CourseDescriptor)
self.store.delete_course(id_locator, 'testbot')
# Test can no longer retrieve by id.
self.assertIsNone(self.store.get_course(id_locator))
# But can retrieve by guid -- same TODO as above
# self.assertIsInstance(self.store.get_item(guid_locator), CourseDescriptor)

View File

@@ -903,12 +903,15 @@ def settings_handler(request, course_key_string):
# see if the ORG of this course can be attributed to a 'Microsite'. In that case, the
# course about page should be editable in Studio
about_page_editable = not microsite.get_value_for_org(
marketing_site_enabled = microsite.get_value_for_org(
course_module.location.org,
'ENABLE_MKTG_SITE',
settings.FEATURES.get('ENABLE_MKTG_SITE', False)
)
about_page_editable = not marketing_site_enabled
enrollment_end_editable = GlobalStaff().has_user(request.user) or not marketing_site_enabled
short_description_editable = settings.FEATURES.get('EDITABLE_SHORT_DESCRIPTION', True)
settings_context = {
'context_course': course_module,
@@ -924,6 +927,7 @@ def settings_handler(request, course_key_string):
'credit_eligibility_enabled': credit_eligibility_enabled,
'is_credit_course': False,
'show_min_grade_warning': False,
'enrollment_end_editable': enrollment_end_editable,
}
if prerequisite_course_enabled:
courses, in_process_course_actions = get_courses_accessible_to_user(request)

View File

@@ -204,8 +204,6 @@ LOGGING = get_logger_config(LOG_DIR,
PLATFORM_NAME = ENV_TOKENS.get('PLATFORM_NAME', 'edX')
STUDIO_NAME = ENV_TOKENS.get('STUDIO_NAME', 'edX Studio')
STUDIO_SHORT_NAME = ENV_TOKENS.get('STUDIO_SHORT_NAME', 'Studio')
TENDER_DOMAIN = ENV_TOKENS.get('TENDER_DOMAIN', TENDER_DOMAIN)
TENDER_SUBDOMAIN = ENV_TOKENS.get('TENDER_SUBDOMAIN', TENDER_SUBDOMAIN)
# Event Tracking
if "TRACKING_IGNORE_URL_PATTERNS" in ENV_TOKENS:

View File

@@ -98,6 +98,9 @@ FEATURES['LICENSING'] = True
FEATURES['ENABLE_MOBILE_REST_API'] = True # Enable video bumper in Studio
FEATURES['ENABLE_VIDEO_BUMPER'] = True # Enable video bumper in Studio settings
# Enable partner support link in Studio footer
FEATURES['PARTNER_SUPPORT_EMAIL'] = 'partner-support@example.com'
########################### Entrance Exams #################################
FEATURES['ENTRANCE_EXAMS'] = True

View File

@@ -619,18 +619,6 @@ REQUIRE_ENVIRONMENT = "node"
DEBUG_TOOLBAR_PATCH_SETTINGS = False
################################# TENDER ######################################
# If you want to enable Tender integration (http://tenderapp.com/),
# put in the subdomain where Tender hosts tender_widget.js. For example,
# if you want to use the URL https://example.tenderapp.com/tender_widget.js,
# you should use "example".
TENDER_SUBDOMAIN = None
# If you want to have a vanity domain that points to Tender, put that here.
# For example, "help.myapp.com". Otherwise, should should be your full
# tenderapp domain name: for example, "example.tenderapp.com".
TENDER_DOMAIN = None
################################# CELERY ######################################
# Message configuration
@@ -1004,6 +992,9 @@ ADVANCED_COMPONENT_TYPES = [
# In-course reverification checkpoint
'edx-reverification-block',
# Peer instruction tool
'ubcpi',
]
# Adding components in this list will disable the creation of new problem for

View File

@@ -94,9 +94,6 @@ STATICFILES_STORAGE = 'pipeline.storage.NonPackagingPipelineStorage'
STATIC_URL = "/static/"
PIPELINE_ENABLED = False
TENDER_DOMAIN = "help.edge.edx.org"
TENDER_SUBDOMAIN = "edxedge"
# Update module store settings per defaults for tests
update_module_store_settings(
MODULESTORE,

View File

@@ -83,7 +83,6 @@
'gettext': 'empty:',
'xmodule': 'empty:',
'mathjax': 'empty:',
'tender': 'empty:',
'youtube': 'empty:'
},

View File

@@ -70,14 +70,6 @@ require.config({
// end of Annotation tool files
// externally hosted files
"tender": [
// if TENDER_SUBDOMAIN is defined, use that; otherwise, use a dummy value
// (the application JS will never `require(['tender'])` if it's not defined)
"//" + (typeof TENDER_SUBDOMAIN === "string" ? TENDER_SUBDOMAIN : "example") + ".tenderapp.com/tender_widget",
// if tender fails to load, fallback on a local file
// so that require doesn't fall over
"js/src/tender_fallback"
],
"mathjax": "//cdn.mathjax.org/mathjax/2.4-latest/MathJax.js?config=TeX-MML-AM_HTMLorMML-full&delayStartupUntil=configured",
"youtube": [
// youtube URL does not end in ".js". We add "?noext" to the path so
@@ -172,9 +164,6 @@ require.config({
deps: ["backbone"],
exports: "Backbone.Paginator"
},
"tender": {
exports: 'Tender'
},
"youtube": {
exports: "YT"
},

View File

@@ -53,7 +53,6 @@ requirejs.config({
"mathjax": "//cdn.mathjax.org/mathjax/2.4-latest/MathJax.js?config=TeX-MML-AM_HTMLorMML-full&delayStartupUntil=configured",
"youtube": "//www.youtube.com/player_api?noext",
"tender": "//api.tenderapp.com/tender_widget",
"coffee/src/ajax_prefix": "xmodule_js/common_static/coffee/src/ajax_prefix",
"js/spec/test_utils": "js/spec/test_utils",

View File

@@ -44,7 +44,6 @@ requirejs.config({
"mathjax": "//cdn.mathjax.org/mathjax/2.4-latest/MathJax.js?config=TeX-MML-AM_HTMLorMML-full&delayStartupUntil=configured",
"youtube": "//www.youtube.com/player_api?noext",
"tender": "//api.tenderapp.com/tender_widget.js"
"coffee/src/ajax_prefix": "xmodule_js/common_static/coffee/src/ajax_prefix"
}

View File

@@ -61,9 +61,6 @@ domReady(function() {
// general link management - smooth scrolling page links
$('a[rel*="view"][href^="#"]').bind('click', smoothScrollLink);
// tender feedback window scrolling
$('a.show-tender').bind('click', smoothScrollTop);
IframeUtils.iframeBinding();
// disable ajax caching in IE so that backbone fetches work

View File

@@ -1,8 +1,8 @@
// studio - base styling
// ====================
// Table of Contents
// * +Basic Setup
// Table of Contents
// * +Basic Setup
// * +Typography - Basic
// * +Typography - Primary Content
// * +Typography - Secondary Content
@@ -19,7 +19,7 @@
// * +JS Dependent
// +Basic Setup
// ====================
// ====================
html {
font-size: 62.5%;
height: 102%; // force scrollbar to prevent jump when scroll appears, cannot use overflow because it breaks drag
@@ -66,7 +66,7 @@ h1 {
}
// +Typography - Basic
// ====================
// ====================
.page-header {
@extend %t-title3;
@extend %t-strong;
@@ -111,7 +111,7 @@ h1 {
}
// +Typography - Primary Content
// ====================
// ====================
.content-primary {
.section-header {
@@ -148,7 +148,7 @@ h1 {
}
// +Typography - Secondary Content
// ====================
// ====================
.content-secondary {
.section-header {
@@ -177,7 +177,7 @@ h1 {
}
// +Typography - Loose Headings (BT: needs to be removed once html is clean)
// ====================
// ====================
.title-1, .title-2, .title-3, .title-4, .title-5, .title-6 {
@extend %t-strong;
}
@@ -226,13 +226,13 @@ p, ul, ol, dl {
}
// +Layout - Basic
// ====================
// ====================
.wrapper-view {
}
// +Layout - Basic Page Header
// ====================
// ====================
.wrapper-mast {
margin: ($baseline*1.5) 0 0 0;
padding: 0 $baseline;
@@ -375,7 +375,7 @@ p, ul, ol, dl {
}
// +Layout - Basic Page Content
// ====================
// ====================
.wrapper-content {
margin: 0;
padding: 0 $baseline;
@@ -419,7 +419,7 @@ p, ul, ol, dl {
}
// +Layout - Primary Content
// ====================
// ====================
.content-primary {
.title-1 {
@@ -457,7 +457,7 @@ p, ul, ol, dl {
}
// +Layout - Supplemental Content
// ====================
// ====================
.content-supplementary {
> section {
@@ -466,7 +466,7 @@ p, ul, ol, dl {
}
// +Layout - Grandfathered
// ====================
// ====================
.main-wrapper {
position: relative;
margin: 0 ($baseline*2);
@@ -503,7 +503,7 @@ p, ul, ol, dl {
}
// +UI - Actions
// ====================
// ====================
.new-unit-item,
.new-subsection-item,
.new-policy-item {
@@ -535,7 +535,7 @@ p, ul, ol, dl {
}
// +UI - Misc
// ====================
// ====================
hr.divide {
@extend %cont-text-sr;
}
@@ -623,7 +623,7 @@ hr.divide {
// +Utility - Basic
// ====================
// ====================
// UI - semantically hide text
.sr {

View File

@@ -37,7 +37,6 @@
@import 'elements/header';
@import 'elements/footer';
@import 'elements/sock';
@import 'elements/tender-widget';
@import 'elements/system-feedback'; // alerts, notifications, states
@import 'elements/system-help'; // help UI
@import 'elements/modal'; // interstitial UI, dialogs, modal windows

View File

@@ -1,7 +1,7 @@
// studio - utilities - variables
// ====================
// Table of Contents
// Table of Contents
// * +Grid
// * +Fonts
// * +Colors - Utility
@@ -16,7 +16,7 @@
$baseline: 20px;
// +Grid
// ====================
// ====================
$gw-column: ($baseline*3);
$gw-gutter: $baseline;
$fg-column: $gw-column;
@@ -26,16 +26,16 @@ $fg-max-width: 1280px;
$fg-min-width: 900px;
// +Fonts
// ====================
// ====================
$f-sans-serif: 'Open Sans','Helvetica Neue', Helvetica, Arial, sans-serif;
$f-monospace: 'Bitstream Vera Sans Mono', Consolas, Courier, monospace;
// +Colors - Utility
// ====================
// ====================
$transparent: rgba(0,0,0,0); // used when color value is needed for UI width/transitions but element is transparent
// +Colors - Primary
// ====================
// ====================
$black: rgb(0,0,0);
$black-t0: rgba($black, 0.125);
$black-t1: rgba($black, 0.25);
@@ -168,7 +168,7 @@ $orange-u2: desaturate($orange,30%);
$orange-u3: desaturate($orange,45%);
// +Colors - Shadows
// ====================
// ====================
$shadow: rgba($black, 0.2);
$shadow-l1: rgba($black, 0.1);
$shadow-l2: rgba($black, 0.05);
@@ -176,7 +176,7 @@ $shadow-d1: rgba($black, 0.4);
$shadow-d2: rgba($black, 0.6);
// +Colors - Application
// ====================
// ====================
$color-draft: $gray-l3;
$color-live: $blue;
$color-ready: $green;
@@ -190,7 +190,7 @@ $color-copy-base: $gray-l1;
$color-copy-emphasized: $gray-d2;
// +Timing
// ====================
// ====================
// used for animation/transition mixin syncing
$tmg-s3: 3.0s;
$tmg-s2: 2.0s;
@@ -201,7 +201,7 @@ $tmg-f2: 0.25s;
$tmg-f3: 0.125s;
// +Archetype UI
// ====================
// ====================
$ui-action-primary-color: $blue-u2;
$ui-action-primary-color-focus: $blue-s1;
@@ -209,12 +209,12 @@ $ui-link-color: $blue-u2;
$ui-link-color-focus: $blue-s1;
// +Specific UI
// ====================
// ====================
$ui-notification-height: ($baseline*10);
$ui-update-color: $blue-l4;
// +Deprecated
// ====================
// +Deprecated
// ====================
// do not use, future clean up will use updated styles
$baseFontColor: $gray-d2;
$lighter-base-font-color: rgb(100,100,100);

View File

@@ -1,7 +1,7 @@
// studio animations & keyframes
// ====================
// Table of Contents
// Table of Contents
// * +Fade In - Extend
// * +Fade Out - Extend
// * +Rotate Up - Extend
@@ -16,7 +16,7 @@
// * +Dropped - Extend
// +Fade In - Extend
// ====================
// ====================
// fade in keyframes
@include keyframes(fadeIn) {
0% {
@@ -38,9 +38,9 @@
}
// +Fade Out - Extend
// ====================
// ====================
// fade out keyframes
@include keyframes(fadeOut) {
@include keyframes(fadeOut) {
0% {
opacity: 1.0;
}
@@ -60,7 +60,7 @@
}
// +Rotate Up - Extend
// ====================
// ====================
// rotate up keyframes
@include keyframes(rotateUp) {
0% {
@@ -262,7 +262,7 @@
}
}
// flash double animation
// flash double animation
%anim-flashDouble {
@include animation(flashDouble $tmg-f1 ease-in-out 1);
}

View File

@@ -1,7 +1,7 @@
// studio - elements - UI controls
// ====================
// Table of Contents
// Table of Contents
// * +General Action - Extend
// * +General Type and Size - Extend
// * +Primary Button - Extends
@@ -16,7 +16,7 @@
// +General Action - Extend
// ====================
// ====================
%action {
@extend %ui-fake-link;
@@ -28,7 +28,7 @@
}
// +General Type and Size - Extend
// ====================
// ====================
%sizing {
@extend %t-action4;
padding: ($baseline/4) ($baseline/2) ($baseline/3) ($baseline/2);
@@ -36,7 +36,7 @@
// +Primary Button - Extends
// ====================
// ====================
// gray primary button
%btn-primary-gray {
@extend %ui-btn-primary;
@@ -106,7 +106,7 @@
}
// +Secondary Button - Extends
// ====================
// ====================
// gray secondary button
%btn-secondary-gray {
@extend %ui-btn-secondary;
@@ -193,7 +193,7 @@
}
// +Button Element
// ====================
// ====================
.button {
.icon {
@@ -385,7 +385,7 @@
cursor: move;
}
}
// UI: is draggable
.is-draggable {
@include transition(border-color $tmg-f2 ease-in-out 0, box-shadow $tmg-f2 ease-in-out 0, margin $tmg-f2 ease-in-out 0);

View File

@@ -86,6 +86,7 @@
.action-item {
@include float(left);
@include margin-right($baseline/2);
margin-bottom: ($baseline/2);
&:last-child {
@include margin-right(0);

View File

@@ -1,273 +0,0 @@
// tender help/support widget
// ====================
// UI: hiding the default tender help "tag" element
#tender_toggler {
display: none;
}
#tender_frame, #tender_window {
background-image: none !important;
background: none;
}
#tender_window {
border-radius: 3px;
box-shadow: 0 2px 3px $shadow;
height: ($baseline*35) !important;
background: $white !important;
border: 2px solid $blue;
}
#tender_window {
padding: 0 !important;
}
#tender_frame {
background: $white;
}
#tender_closer {
color: $white-t2 !important;
text-transform: uppercase;
top: 16px !important;
&:hover {
color: $white !important;
}
}
// ====================
// tender style overrides - not rendered through here, but an archive is needed
#tender_frame iframe html {
font-size: 62.5%;
}
.widget-layout {
font-family: 'Open Sans', sans-serif;
}
.widget-layout .search,
.widget-layout .tabs,
.widget-layout .footer,
.widget-layout .header h1 a {
display: none;
}
.widget-layout .header {
background: rgb(0, 159, 230);
padding: ($baseline/2) $baseline;
}
.widget-layout h1, .widget-layout h2, .widget-layout h3, .widget-layout h4, .widget-layout h5, .widget-layout h6, .widget-layout label {
@extend %t-strong;
}
.widget-layout .header h1 {
@extend %t-title4;
}
.widget-layout .content {
overflow: auto;
height: auto !important;
padding: 20px;
}
.widget-layout .flash {
margin: -10px 0 15px 0;
padding: 10px 20px !important;
background-image: none !important;
}
.widget-layout .flash-error {
background: rgb(178, 6, 16) !important;
color: rgb(255,255,255) !important;
}
.widget-layout label {
@extend %t-copy-sub1;
@extend %t-strong;
margin-bottom: ($baseline/4);
color: #4c4c4c;
}
.widget-layout input[type="text"], .widget-layout textarea {
@extend %t-copy-base;
padding: 10px;
color: rgb(0,0,0) !important;
border: 1px solid #b0b6c2;
border-radius: 2px;
background-color: #edf1f5;
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #edf1f5),color-stop(100%, #fdfdfe));
background-image: -webkit-linear-gradient(top, #edf1f5,#fdfdfe);
background-image: -moz-linear-gradient(top, #edf1f5,#fdfdfe);
background-image: -ms-linear-gradient(top, #edf1f5,#fdfdfe);
background-image: -o-linear-gradient(top, #edf1f5,#fdfdfe);
background-image: linear-gradient(top, #edf1f5,#fdfdfe);
background-color: #edf1f5;
-webkit-box-shadow: 0 1px 2px rgba(0,0,0,0.1) inset;
-moz-box-shadow: 0 1px 2px rgba(0,0,0,0.1) inset;
box-shadow: 0 1px 2px rgba(0,0,0,0.1) inset;
}
.widget-layout input[type="text"]:focus, .widget-layout textarea:focus {
background-color: #fffcf1;
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, #fffcf1),color-stop(100%, #fffefd));
background-image: -webkit-linear-gradient(top, #fffcf1,#fffefd);
background-image: -moz-linear-gradient(top, #fffcf1,#fffefd);
background-image: -ms-linear-gradient(top, #fffcf1,#fffefd);
background-image: -o-linear-gradient(top, #fffcf1,#fffefd);
background-image: linear-gradient(top, #fffcf1,#fffefd);
outline: 0;
}
.widget-layout textarea {
width: 97%;
}
.widget-layout p.note {
text-align: right !important;
display: inline-block !important;
position: absolute !important;
right: -130px !important;
top: -5px !important;
font-size: 13px !important;
opacity: 0.80;
}
.widget-layout .form-actions {
margin: 15px 0;
border: none;
padding: 0;
}
.widget-layout dl.form {
float: none;
width: 100%;
border-bottom: 1px solid $gray-l5;
margin-bottom: ($baseline/2);
padding-bottom: ($baseline/2);
}
.widget-layout dl.form:last-child {
border: none;
padding-bottom: 0;
margin-bottom: $baseline;
}
.widget-layout dl.form dt, .widget-layout dl.form dd {
display: inline-block;
vertical-align: middle;
}
.widget-layout dl.form dt {
margin-right: ($baseline*0.75);
width: 70px;
}
.widget-layout dl.form dd {
width: 65%;
position: relative;
}
// specific elements
.widget-layout #discussion_body {
}
.widget-layout #discussion_body:before {
@extend %t-copy-sub1;
@extend %t-strong;
content: "What Question or Feedback Would You Like to Share?";
display: block;
margin-bottom: ($baseline/4);
color: #4c4c4c;
}
.widget-layout dl#brain_buster_captcha {
float: none;
width: 100%;
border-top: 1px solid $gray-l5;
margin-top: ($baseline/2);
padding-top: ($baseline/2);
}
.widget-layout dl#brain_buster_captcha dd {
display: block !important;
}
.widget-layout dl#brain_buster_captcha #captcha_answer {
border-color: #333;
}
.widget-layout dl#brain_buster_captcha dd label {
@extend %t-strong;
display: block;
margin: 0 15px 5px 0 !important;
}
.widget-layout dl#brain_buster_captcha dd #captcha_answer {
display: block;
width: 97%;
}
.widget-layout .form-actions .btn-post_topic {
@extend %t-copy-base;
@extend %t-strong;
display: block;
width: 100%;
height: auto !important;
-webkit-box-shadow: 0 1px 0 rgba(255,255,255,0.3) inset,0 0 0 $transparent;
-moz-box-shadow: 0 1px 0 rgba(255,255,255,0.3) inset,0 0 0 $transparent;
box-shadow: 0 1px 0 rgba(255,255,255,0.3) inset,0 0 0 $transparent;
-webkit-transition-property: background-color,0.15s;
-moz-transition-property: background-color,0.15s;
-ms-transition-property: background-color,0.15s;
-o-transition-property: background-color,0.15s;
transition-property: background-color,0.15s;
-webkit-transition-duration: box-shadow,0.15s;
-moz-transition-duration: box-shadow,0.15s;
-ms-transition-duration: box-shadow,0.15s;
-o-transition-duration: box-shadow,0.15s;
transition-duration: box-shadow,0.15s;
-webkit-transition-timing-function: ease-out;
-moz-transition-timing-function: ease-out;
-ms-transition-timing-function: ease-out;
-o-transition-timing-function: ease-out;
transition-timing-function: ease-out;
-webkit-transition-delay: 0;
-moz-transition-delay: 0;
-ms-transition-delay: 0;
-o-transition-delay: 0;
transition-delay: 0;
border: 1px solid #34854c;
border-radius: 3px;
background-color: rgba(255,255,255,0.3);
background-image: -webkit-gradient(linear, left top, left bottom, color-stop(0%, rgba(255,255,255,0.3)),color-stop(100%, rgba(255,255,255,0)));
background-image: -webkit-linear-gradient(top, rgba(255,255,255,0.3),rgba(255,255,255,0));
background-image: -moz-linear-gradient(top, rgba(255,255,255,0.3),rgba(255,255,255,0));
background-image: -ms-linear-gradient(top, rgba(255,255,255,0.3),rgba(255,255,255,0));
background-image: -o-linear-gradient(top, rgba(255,255,255,0.3),rgba(255,255,255,0));
background-image: linear-gradient(top, rgba(255,255,255,0.3),rgba(255,255,255,0));
background-color: #25b85a;
-webkit-box-shadow: 0 1px 0 rgba(255,255,255,0.3) inset;
-moz-box-shadow: 0 1px 0 rgba(255,255,255,0.3) inset;
box-shadow: 0 1px 0 rgba(255,255,255,0.3) inset;
color: $white;
text-align: center;
margin-top: $baseline;
padding: ($baseline/2) $baseline;
}
.widget-layout .form-actions #private-discussion-opt {
float: none;
text-align: left;
margin: 0 0 15px 0;
}
.widget-layout .form-actions .btn-post_topic:hover, .widget-layout .form-actions .btn-post_topic:active {
background-color: #16ca57;
color: $white;
}

View File

@@ -4,7 +4,7 @@
// Table of Contents
// * +Layout - Xblocks
// * +Licensing - Xblocks
// * +Pagination - Xblocks
// * +Pagination - Xblocks
// * +Messaging - Xblocks
// * +Case: Page Level
// * +Case: Nesting Level
@@ -14,7 +14,7 @@
// * +Case - Special Xblock Type Overrides
// +Layout - Xblocks
// +Layout - Xblocks
// ====================
// styling for xblocks at various levels of nesting: page level,
.wrapper-xblock {
@@ -116,7 +116,7 @@
}
}
// +Licensing - Xblocks
// +Licensing - Xblocks
// ====================
.xblock-license,
.xmodule_display.xmodule_HtmlModule .xblock-license,
@@ -157,7 +157,7 @@
}
// +Pagination - Xblocks
// +Pagination - Xblocks
.container-paging-header {
.meta-wrap {
margin: $baseline ($baseline/2);
@@ -910,7 +910,7 @@ div.wrapper-comp-editor.is-inactive ~ div.launch-latex-compiler {
@extend %t-copy-sub2;
}
}
.wrapper-license-options {
margin-bottom: ($baseline/2);

View File

@@ -1,11 +1,11 @@
// ------------------------------------------
// left to right module
// authors:
// authors:
// twitter.com/anasnakawa
// twitter.com/victorzamfir
// licensed under the MIT license
// licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.php
// ------------------------------------------
@import 'variables-ltr';
@import 'mixins';
@import 'mixins';

View File

@@ -1,11 +1,11 @@
// ------------------------------------------
// right to left module
// authors:
// authors:
// twitter.com/anasnakawa
// twitter.com/victorzamfir
// licensed under the MIT license
// licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.php
// ------------------------------------------
@import 'variables-rtl';
@import 'mixins';
@import 'mixins';

View File

@@ -1,15 +1,15 @@
// ------------------------------------------
// left to right variables to be used by bi-app mixins
// authors:
// authors:
// twitter.com/anasnakawa
// twitter.com/victorzamfir
// licensed under the MIT license
// licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.php
// ------------------------------------------
// namespacing variables with bi-app to
// avoid conflicting with other global variables
$bi-app-left : left;
$bi-app-right : right;
$bi-app-direction : ltr;
$bi-app-invert-direction: rtl;
$bi-app-left : left;
$bi-app-right : right;
$bi-app-direction : ltr;
$bi-app-invert-direction: rtl;

View File

@@ -1,15 +1,15 @@
// ------------------------------------------
// right to left variables to be used by bi-app mixins
// authors:
// authors:
// twitter.com/anasnakawa
// twitter.com/victorzamfir
// licensed under the MIT license
// licensed under the MIT license
// http://www.opensource.org/licenses/mit-license.php
// ------------------------------------------
// namespacing variables with bi-app to
// avoid conflicting with other global variables
$bi-app-left : right;
$bi-app-left : right;
$bi-app-right : left;
$bi-app-direction : rtl;
$bi-app-invert-direction: ltr;
$bi-app-direction : rtl;
$bi-app-invert-direction: ltr;

View File

@@ -1,7 +1,7 @@
// studio - views - certificates
// ====================
// Table of Contents
// Table of Contents
// * +Layout - Certificates
// * +Main - Collection
// * +Main - Certificate
@@ -510,7 +510,7 @@
// * +Signatories -Certificate
// ====================
// TO-DO: refactor to use collection styling where possible.
// TO-DO: refactor to use collection styling where possible.
.view-certificates .certificates {
.signatory-details, .signatory-edit {
@@ -694,4 +694,4 @@
}
}
}
}
}

View File

@@ -62,6 +62,27 @@
margin-top: ($baseline);
}
// specific fields - settings details
.settings-details {
// course details that should appear more like content than elements to change
.is-not-editable {
label {
}
input, textarea {
@extend %t-copy-lead1;
@extend %t-strong;
box-shadow: none;
border: none;
background: none;
margin: 0;
}
}
}
// in form - elements
.group-settings {
@@ -225,7 +246,7 @@
}
}
}
.input-minimum-grade {
@include float(left);
@include size(92%,100%);
@@ -305,21 +326,10 @@
}
}
// course details that should appear more like content than elements to change
.field.is-not-editable {
label {
}
.is-not-editable {
input, textarea {
@extend %t-copy-lead1;
@extend %t-strong;
box-shadow: none;
border: none;
background: none;
padding: 0;
margin: 0;
}
}
@@ -438,6 +448,13 @@
padding-bottom: 0;
}
.is-not-editable {
input, textarea {
padding: 10px;
}
}
.field {
@include float(left);
width: flex-grid(3, 9);

View File

@@ -24,16 +24,6 @@
)}</p>
</div>
</div>
<ul class="list-actions">
% if settings.TENDER_DOMAIN:
<li class="action-item">
<a href="http://${settings.TENDER_DOMAIN}/discussion/new" class="action action-primary show-tender">
${_('Contact {platform_name} Support').format(platform_name=settings.PLATFORM_NAME)}
</a>
</li>
% endif
</ul>
</div>
</section>
</div>

View File

@@ -42,7 +42,6 @@ import json
<script type="text/javascript">
window.baseUrl = ${json.dumps(settings.STATIC_URL)};
window.TENDER_SUBDOMAIN = ${json.dumps(settings.TENDER_SUBDOMAIN)};
var require = {baseUrl: window.baseUrl};
</script>
<script type="text/javascript" src="${static.url("js/vendor/require.js")}"></script>
@@ -65,7 +64,6 @@ import json
<%include file="widgets/sock.html" args="online_help_token=online_help_token" />
% endif
<%include file="widgets/footer.html" />
<%include file="widgets/tender.html" />
<div id="page-notification"></div>
</div>

View File

@@ -7,7 +7,7 @@ from django.utils.translation import ugettext as _
from django.template.defaultfilters import escapejs
%>
<!-- TODO decode course # from context_course into title -->
## TODO decode course # from context_course into title.
<%block name="title">${_("Course Updates")}</%block>
<%block name="bodyclass">is-signedin course course-info updates view-updates</%block>

View File

@@ -14,15 +14,8 @@ from django.conf import settings
</%block>
<%!
if settings.TENDER_DOMAIN:
help_link_start = '<a href="http://{domain}/discussion/new" class="show-tender" title="{title}">'.format(
domain=settings.TENDER_DOMAIN,
title=_("Use our feedback tool, Tender, to share your feedback")
),
help_link_end = '</a>'
else:
help_link_start = '<a href="mailto:{email}">'.format(email=settings.TECH_SUPPORT_EMAIL)
help_link_end = '</a>'
help_link_start = '<a href="mailto:{email}">'.format(email=settings.TECH_SUPPORT_EMAIL)
help_link_end = '</a>'
%>
<%block name="content">

View File

@@ -61,7 +61,8 @@
<ol class="list-input">
<li class="field text required" id="field-course-name">
<label for="new-course-name">${_("Course Name")}</label>
## Translators: This is an example name for a new course, seen when filling out the form to create a new course.
## Translators: This is an example name for a new course, seen when
## filling out the form to create a new course.
<input class="new-course-name" id="new-course-name" type="text" name="new-course-name" required placeholder="${_('e.g. Introduction to Computer Science')}" aria-describedby="tip-new-course-name tip-error-new-course-name" />
<span class="tip" id="tip-new-course-name">${_("The public display name for your course. This cannot be changed, but you can set a different display name in Advanced Settings later.")}</span>
<span class="tip tip-error is-hiding" id="tip-error-new-course-name"></span>
@@ -77,7 +78,9 @@
<li class="field text required" id="field-course-number">
<label for="new-course-number">${_("Course Number")}</label>
## Translators: This is an example for the number used to identify a course, seen when filling out the form to create a new course. The number here is short for "Computer Science 101". It can contain letters but cannot contain spaces.
## Translators: This is an example for the number used to identify a course,
## seen when filling out the form to create a new course. The number here is
## short for "Computer Science 101". It can contain letters but cannot contain spaces.
<input class="new-course-number" id="new-course-number" type="text" name="new-course-number" required placeholder="${_('e.g. CS101')}" aria-describedby="tip-new-course-number tip-error-new-course-number" />
<span class="tip" id="tip-new-course-number">${_("The unique number that identifies your course within your organization.")} <strong>${_("Note: This is part of your course URL, so no spaces or special characters are allowed and it cannot be changed.")}</strong></span>
<span class="tip tip-error is-hiding" id="tip-error-new-course-number"></span>
@@ -85,7 +88,8 @@
<li class="field text required" id="field-course-run">
<label for="new-course-run">${_("Course Run")}</label>
## Translators: This is an example for the "run" used to identify different instances of a course, seen when filling out the form to create a new course.
## Translators: This is an example for the "run" used to identify different
## instances of a course, seen when filling out the form to create a new course.
<input class="new-course-run" id="new-course-run" type="text" name="new-course-run" required placeholder="${_('e.g. 2014_T1')}" aria-describedby="tip-new-course-run tip-error-new-course-run" />
<span class="tip" id="tip-new-course-run">${_("The term in which your course will run.")} <strong>${_("Note: This is part of your course URL, so no spaces or special characters are allowed and it cannot be changed.")}</strong></span>
<span class="tip tip-error is-hiding" id="tip-error-new-course-run"></span>
@@ -123,7 +127,9 @@
<ol class="list-input">
<li class="field text required" id="field-library-name">
<label for="new-library-name">${_("Library Name")}</label>
## Translators: This is an example name for a new content library, seen when filling out the form to create a new library. (A library is a collection of content or problems.)
## Translators: This is an example name for a new content library, seen when
## filling out the form to create a new library.
## (A library is a collection of content or problems.)
<input class="new-library-name" id="new-library-name" type="text" name="new-library-name" required placeholder="${_('e.g. Computer Science Problems')}" aria-describedby="tip-new-library-name tip-error-new-library-name" />
<span class="tip" id="tip-new-library-name">${_("The public display name for your library.")}</span>
<span class="tip tip-error is-hiding" id="tip-error-new-library-name"></span>
@@ -137,7 +143,10 @@
<li class="field text required" id="field-library-number">
<label for="new-library-number">${_("Library Code")}</label>
## Translators: This is an example for the "code" used to identify a library, seen when filling out the form to create a new library. This example is short for "Computer Science Problems". The example number may contain letters but must not contain spaces.
## Translators: This is an example for the "code" used to identify a library,
## seen when filling out the form to create a new library. This example is short
## for "Computer Science Problems". The example number may contain letters
## but must not contain spaces.
<input class="new-library-number" id="new-library-number" type="text" name="new-library-number" required placeholder="${_('e.g. CSPROB')}" aria-describedby="tip-new-library-number tip-error-new-library-number" />
<span class="tip" id="tip-new-library-number">${_("The unique code that identifies this library.")} <strong>${_("Note: This is part of your library URL, so no spaces or special characters are allowed.")}</strong> ${_("This cannot be changed.")}</span>
<span class="tip tip-error is-hiding" id="tip-error-new-library-number"></span>
@@ -188,7 +197,11 @@
<dt class="label sr">${_("This course run is currently being created.")}</dt>
<dd class="value">
<i class="icon fa fa-refresh fa-spin"></i>
## Translators: This is a status message, used to inform the user of what the system is doing. This status means that the user has requested to re-run an existing course, and the system is currently in the process of duplicating and configuring the existing course so that it can be re-run.
## Translators: This is a status message, used to inform the user of
## what the system is doing. This status means that the user has
## requested to re-run an existing course, and the system is currently
## in the process of duplicating and configuring the existing course
## so that it can be re-run.
<span class="copy">${_("Configuring as re-run")}</span>
</dd>
</dl>
@@ -227,10 +240,14 @@
</div>
<dl class="course-status">
<dt class="label sr">This re-run processing status:</dt>
## Translators: This is a status message for the course re-runs feature.
## When a course admin indicates that a course should be re-run, the system
## needs to process the request and prepare the new course. The status of
## the process will follow this text.
<dt class="label sr">${_("This re-run processing status:")}</dt>
<dd class="value">
<i class="icon fa fa-warning"></i>
<span class="copy">Configuration Error</span>
<span class="copy">${_("Configuration Error")}</span>
</dd>
</dl>
</div>
@@ -479,13 +496,6 @@
<a href="${get_online_help_info(online_help_token())['doc_url']}" target="_blank">${_("Getting Started with {studio_name}").format(studio_name=settings.STUDIO_NAME)}</a>
</li>
% if settings.TENDER_DOMAIN:
<li class="action-item">
<a href="http://${settings.TENDER_DOMAIN}/discussion/new" class="action action-primary" title="${_("Use our feedback tool, Tender, to request help")}">
${_("Request help with {studio_name}").format(studio_name=settings.STUDIO_NAME)}
</a>
</li>
% endif
</ol>
</div>
@@ -513,14 +523,8 @@
<%!
from django.conf import settings
if settings.TENDER_DOMAIN:
help_link_start = '<a href="http://{domain}/discussion/new" class="show-tender">'.format(
domain=settings.TENDER_DOMAIN,
)
help_link_end = '</a>'
else:
help_link_start = '<a href="mailto:{email}">'.format(email=settings.TECH_SUPPORT_EMAIL)
help_link_end = '</a>'
help_link_start = '<a href="mailto:{email}">'.format(email=settings.TECH_SUPPORT_EMAIL)
help_link_end = '</a>'
%>
<p>${_("Your request to author courses in {studio_name} has been denied. Please {link_start}contact {platform_name} Staff with further questions{link_end}.").format(
studio_name=settings.STUDIO_NAME,
@@ -556,16 +560,6 @@ else:
<div class="bit">
<h3 class="title title-3">${_('Need help?')}</h3>
<p>${_('Please check your Junk or Spam folders in case our email isn\'t in your INBOX. Still can\'t find the verification email? Request help via the link below.')}</p>
<ol class='list-actions'>
% if settings.TENDER_DOMAIN:
<li class="action-item">
<a href="http://${settings.TENDER_DOMAIN}/discussion/new" class="show-tender" title="${_("Use our feedback tool, Tender, to request help")}">
${_("Request help with your {studio_name} account").format(studio_name=settings.STUDIO_NAME)}
</a>
</li>
% endif
</ol>
</div>
</aside>
</section>

View File

@@ -30,9 +30,9 @@ from django.utils.translation import ugettext as _
</li>
<li class="field text required" id="field-password">
<a href="${forgot_password_link}" class="action action-forgotpassword" tabindex="-1">${_("Forgot password?")}</a>
<label for="password">${_("Password")}</label>
<input id="password" type="password" name="password" />
<a href="${forgot_password_link}" class="action action-forgotpassword">${_("Forgot password?")}</a>
</li>
</ol>
</fieldset>
@@ -45,20 +45,6 @@ from django.utils.translation import ugettext as _
<input name="honor_code" type="checkbox" value="true" checked="true" hidden="true">
</form>
</article>
% if settings.TENDER_DOMAIN:
<aside class="content-supplementary" role="complementary">
<h2 class="sr">${_("{studio_name} Support").format(studio_name=settings.STUDIO_SHORT_NAME)}</h2>
<div class="bit">
<h3 class="title-3">${_("Need Help?")}</h3>
<p>${_('Having trouble with your account? Use {link_start}our support center{link_end} to look over self help steps, find solutions others have found to the same problem, or let us know of your issue.').format(
link_start='<a href="http://{domain}" rel="external">'.format(domain=settings.TENDER_DOMAIN),
link_end='</a>',
)}</p>
</div>
</aside>
% endif
</section>
</div>
</%block>

View File

@@ -220,17 +220,25 @@ CMS.URL.UPLOAD_ASSET = '${upload_asset_url}';
<span class="tip tip-stacked timezone">${_("(UTC)")}</span>
</div>
</li>
<%
enrollment_end_readonly = "readonly aria-readonly=\"true\"" if not enrollment_end_editable else ""
enrollment_end_editable_class = "is-not-editable" if not enrollment_end_editable else ""
%>
<li class="field-group field-group-enrollment-end" id="enrollment-end">
<div class="field date" id="field-enrollment-end-date">
<div class="field date ${enrollment_end_editable_class}" id="field-enrollment-end-date">
<label for="course-enrollment-end-date">${_("Enrollment End Date")}</label>
<input type="text" class="end-date date end" id="course-enrollment-end-date" placeholder="MM/DD/YYYY" autocomplete="off" />
<span class="tip tip-stacked">${_("Last day students can enroll")}</span>
<input type="text" class="end-date date end" id="course-enrollment-end-date" placeholder="MM/DD/YYYY" autocomplete="off" ${enrollment_end_readonly} />
<span class="tip tip-stacked">
${_("Last day students can enroll.")}
% if not enrollment_end_editable:
${_("Contact your edX Partner Manager to update these settings.")}
% endif
</span>
</div>
<div class="field time" id="field-enrollment-end-time">
<div class="field time ${enrollment_end_editable_class}" id="field-enrollment-end-time">
<label for="course-enrollment-end-time">${_("Enrollment End Time")}</label>
<input type="text" class="time end" id="course-enrollment-end-time" value="" placeholder="HH:MM" autocomplete="off" />
<input type="text" class="time end" id="course-enrollment-end-time" value="" placeholder="HH:MM" autocomplete="off" ${enrollment_end_readonly} />
<span class="tip tip-stacked timezone">${_("(UTC)")}</span>
</div>
</li>

View File

@@ -19,11 +19,6 @@ from django.core.urlresolvers import reverse
<li class="nav-item nav-peripheral-pp">
<a data-rel="edx.org" href="${marketing_link('PRIVACY')}">${_("Privacy Policy")}</a>
</li>
% if settings.TENDER_DOMAIN and user.is_authenticated():
<li class="nav-item nav-peripheral-feedback">
<a data-rel="edx.org" href="http://${settings.TENDER_DOMAIN}/discussion/new" class="show-tender" title="${_('Use our feedback tool, Tender, to share your feedback')}">${_("Contact Us")}</a>
</li>
% endif
</ol>
</nav>
</div>

View File

@@ -20,46 +20,56 @@ from django.core.urlresolvers import reverse
</header>
<div class="support">
<h3 class="title">${_("{studio_name} Documentation").format(studio_name=settings.STUDIO_NAME)}</h3>
<%!
from django.conf import settings
<div class="copy">
<p>${_("You can click Help in the upper right corner of any page to get more information about the page you're on. You can also use the links below to download the Building and Running an {platform_name} Course PDF file, to go to the {platform_name} Author Support site, or to enroll in edX101.").format(platform_name=settings.PLATFORM_NAME)}</p>
</div>
is_edx_domain = settings.FEATURES.get('IS_EDX_DOMAIN', False)
partner_email = settings.FEATURES.get('PARTNER_SUPPORT_EMAIL', '')
<ul class="list-actions">
<li class="action-item js-help-pdf">
<a href="${get_online_help_info(online_help_token)['pdf_url']}" target="_blank" rel="external" class="action action-primary">${_("Building and Running an {platform_name} Course PDF").format(platform_name=settings.PLATFORM_NAME)}</a>
</li>
% if settings.TENDER_DOMAIN:
<li class="action-item">
<a href="http://${settings.TENDER_DOMAIN}" rel="external" class="action action-primary">${_("{studio_name} Author Support").format(studio_name=settings.STUDIO_NAME)}</a>
<span class="tip">${_("{studio_name} Author Support").format(studio_name=settings.STUDIO_NAME)}</span>
</li>
% endif
<li class="action-item">
<a href="https://www.edx.org/course/overview-creating-edx-course-edx-edx101#.VO4eaLPF-n1" rel="external" class="action action-primary">${_("Enroll in edX101")}</a>
<span class="tip">${_("How to use {studio_name} to build your course").format(studio_name=settings.STUDIO_NAME)}</span>
</li>
</ul>
</div>
% if settings.TENDER_DOMAIN:
<div class="feedback">
<h3 class="title">${_("Request help with {studio_name}").format(studio_name=settings.STUDIO_NAME)}</h3>
<div class="copy">
<p>${_("Have problems, questions, or suggestions about {studio_name}?").format(studio_name=settings.STUDIO_NAME)}</p>
</div>
links = [{
'href': 'http://docs.edx.org',
'sr_mouseover_text': _('Access documentation on http://docs.edx.org'),
'text': _('edX Documentation'),
'condition': True
}, {
'href': 'https://partners.edx.org',
'sr_mouseover_text': _('Access Course Staff Support on the Partner Portal to submit or review support tickets'),
'text': _('edX Partner Portal'),
'condition': is_edx_domain
}, {
'href': 'https://open.edx.org',
'sr_mouseover_text': _('Access the Open edX Portal'),
'text': _('Open edX Portal'),
'condition': not is_edx_domain
}, {
'href': 'https://www.edx.org/course/overview-creating-edx-course-edx-edx101#.VO4eaLPF-n1',
'sr_mouseover_text': _('Enroll in edX101: Overview of Creating an edX Course'),
'text': _('Enroll in edX101'),
'condition': True
}, {
'href': 'https://www.edx.org/course/creating-course-edx-studio-edx-studiox',
'sr_mouseover_text': _('Enroll in StudioX: Creating a Course with edX Studio'),
'text': _('Enroll in StudioX'),
'condition': True
}, {
'href': 'mailto:{email}'.format(email=partner_email),
'sr_mouseover_text': _('Send an email to {email}').format(email=partner_email),
'text': _('Contact Us'),
'condition': 'PARTNER_SUPPORT_EMAIL' in settings.FEATURES
}]
%>
<ul class="list-actions">
<li class="action-item">
<a href="http://${settings.TENDER_DOMAIN}/discussion/new" class="action action-primary" title="${_("Use our feedback tool, Tender, to share your feedback")}"><i class="icon fa fa-comments"></i>${_("Contact Us")}</a>
</li>
% for link in links:
% if link['condition']:
<li class="action-item">
<a href="${link['href']}" title="${link['sr_mouseover_text']}" rel="external" class="action action-primary">${link['text']}</a>
<span class="tip">${link['sr_mouseover_text']}</span>
</li>
%endif
% endfor
</ul>
</div>
% endif
</section>
</div>
</div>

View File

@@ -1,20 +0,0 @@
% if settings.TENDER_SUBDOMAIN and user.is_authenticated():
<script type="text/javascript">
window.Tender = {
hideToggle: true,
title: '',
body: '',
hide_kb: 'true',
widgetToggles: document.getElementsByClassName('show-tender')
}
// In order to avoid requirejs timeout errors should tender not be
// available, we're not using domReady as a loader plugin here.
// For more details, please see the note at
// http://requirejs.org/docs/api.html#pageload
require(['domReady'], function (domReady) {
domReady(function () {
require(['tender']);
});
});
</script>
% endif

View File

@@ -6,7 +6,8 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
# Factories are self documenting
# pylint: disable=missing-docstring
class CourseModeFactory(DjangoModelFactory):
FACTORY_FOR = CourseMode
class Meta(object):
model = CourseMode
course_id = SlashSeparatedCourseKey('MITx', '999', 'Robot_Super_Course')
mode_slug = 'audit'

View File

@@ -1,25 +1,22 @@
'''
django admin pages for courseware model
'''
""" Django admin pages for student app """
from django import forms
from config_models.admin import ConfigurationModelAdmin
from django.contrib.auth.models import User
from student.models import UserProfile, UserTestGroup, CourseEnrollmentAllowed, DashboardConfiguration
from student.models import (
CourseEnrollment, Registration, PendingNameChange, CourseAccessRole, LinkedInAddToProfileConfiguration
)
from ratelimitbackend import admin
from student.roles import REGISTERED_ACCESS_ROLES
from xmodule.modulestore.django import modulestore
from opaque_keys.edx.keys import CourseKey
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey
from config_models.admin import ConfigurationModelAdmin
from student.models import (
UserProfile, UserTestGroup, CourseEnrollmentAllowed, DashboardConfiguration, CourseEnrollment, Registration,
PendingNameChange, CourseAccessRole, LinkedInAddToProfileConfiguration
)
from student.roles import REGISTERED_ACCESS_ROLES
class CourseAccessRoleForm(forms.ModelForm):
"""Form for adding new Course Access Roles view the Django Admin Panel."""
class Meta(object): # pylint: disable=missing-docstring
model = CourseAccessRole
@@ -135,12 +132,21 @@ class LinkedInAddToProfileConfigurationAdmin(admin.ModelAdmin):
exclude = ('dashboard_tracking_code',)
class CourseEnrollmentAdmin(admin.ModelAdmin):
""" Admin interface for the CourseEnrollment model. """
list_display = ('id', 'course_id', 'mode', 'user', 'is_active',)
list_filter = ('mode', 'is_active',)
search_fields = ('course_id', 'mode', 'user__username',)
readonly_fields = ('course_id', 'mode', 'user',)
class Meta(object): # pylint: disable=missing-docstring
model = CourseEnrollment
admin.site.register(UserProfile)
admin.site.register(UserTestGroup)
admin.site.register(CourseEnrollment)
admin.site.register(CourseEnrollmentAllowed)
admin.site.register(Registration)
@@ -152,3 +158,5 @@ admin.site.register(CourseAccessRole, CourseAccessRoleAdmin)
admin.site.register(DashboardConfiguration, ConfigurationModelAdmin)
admin.site.register(LinkedInAddToProfileConfiguration, LinkedInAddToProfileConfigurationAdmin)
admin.site.register(CourseEnrollment, CourseEnrollmentAdmin)

View File

@@ -0,0 +1,46 @@
"""Management command to grant or revoke superuser access for one or more users"""
from optparse import make_option
from django.contrib.auth.models import User
from django.core.management.base import BaseCommand, CommandError
class Command(BaseCommand):
"""Management command to grant or revoke superuser access for one or more users"""
option_list = BaseCommand.option_list + (
make_option('--unset',
action='store_true',
dest='unset',
default=False,
help='Set is_superuser to False instead of True'),
)
args = '<user|email> [user|email ...]>'
help = """
This command will set is_superuser to true for one or more users.
Lookup by username or email address, assumes usernames
do not look like email addresses.
"""
def handle(self, *args, **options):
if len(args) < 1:
raise CommandError('Usage is set_superuser {0}'.format(self.args))
for user in args:
try:
if '@' in user:
userobj = User.objects.get(email=user)
else:
userobj = User.objects.get(username=user)
if options['unset']:
userobj.is_superuser = False
else:
userobj.is_superuser = True
userobj.save()
except Exception as err: # pylint: disable=broad-except
print "Error modifying user with identifier {}: {}: {}".format(user, type(err).__name__, err.message)
print 'Success!'

View File

@@ -17,14 +17,16 @@ from opaque_keys.edx.locations import SlashSeparatedCourseKey
class GroupFactory(DjangoModelFactory):
FACTORY_FOR = Group
FACTORY_DJANGO_GET_OR_CREATE = ('name', )
class Meta(object):
model = Group
django_get_or_create = ('name', )
name = factory.Sequence(u'group{0}'.format)
class UserStandingFactory(DjangoModelFactory):
FACTORY_FOR = UserStanding
class Meta(object):
model = UserStanding
user = None
account_status = None
@@ -32,8 +34,9 @@ class UserStandingFactory(DjangoModelFactory):
class UserProfileFactory(DjangoModelFactory):
FACTORY_FOR = UserProfile
FACTORY_DJANGO_GET_OR_CREATE = ('user', )
class Meta(object):
model = UserProfile
django_get_or_create = ('user', )
user = None
name = factory.LazyAttribute(u'{0.user.first_name} {0.user.last_name}'.format)
@@ -45,7 +48,8 @@ class UserProfileFactory(DjangoModelFactory):
class CourseModeFactory(DjangoModelFactory):
FACTORY_FOR = CourseMode
class Meta(object):
model = CourseMode
course_id = None
mode_display_name = u'Honor Code',
@@ -57,15 +61,17 @@ class CourseModeFactory(DjangoModelFactory):
class RegistrationFactory(DjangoModelFactory):
FACTORY_FOR = Registration
class Meta(object):
model = Registration
user = None
activation_key = uuid4().hex.decode('ascii')
class UserFactory(DjangoModelFactory):
FACTORY_FOR = User
FACTORY_DJANGO_GET_OR_CREATE = ('email', 'username')
class Meta(object):
model = User
django_get_or_create = ('email', 'username')
username = factory.Sequence(u'robot{0}'.format)
email = factory.Sequence(u'robot+test+{0}@edx.org'.format)
@@ -101,7 +107,8 @@ class UserFactory(DjangoModelFactory):
class AnonymousUserFactory(factory.Factory):
FACTORY_FOR = AnonymousUser
class Meta(object):
model = AnonymousUser
class AdminFactory(UserFactory):
@@ -109,14 +116,16 @@ class AdminFactory(UserFactory):
class CourseEnrollmentFactory(DjangoModelFactory):
FACTORY_FOR = CourseEnrollment
class Meta(object):
model = CourseEnrollment
user = factory.SubFactory(UserFactory)
course_id = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')
class CourseAccessRoleFactory(DjangoModelFactory):
FACTORY_FOR = CourseAccessRole
class Meta(object):
model = CourseAccessRole
user = factory.SubFactory(UserFactory)
course_id = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')
@@ -124,7 +133,8 @@ class CourseAccessRoleFactory(DjangoModelFactory):
class CourseEnrollmentAllowedFactory(DjangoModelFactory):
FACTORY_FOR = CourseEnrollmentAllowed
class Meta(object):
model = CourseEnrollmentAllowed
email = 'test@edx.org'
course_id = SlashSeparatedCourseKey('edX', 'toy', '2012_Fall')
@@ -137,7 +147,8 @@ class PendingEmailChangeFactory(DjangoModelFactory):
new_email: sequence of new+email+{}@edx.org
activation_key: sequence of integers, padded to 30 characters
"""
FACTORY_FOR = PendingEmailChange
class Meta(object):
model = PendingEmailChange
user = factory.SubFactory(UserFactory)
new_email = factory.Sequence(u'new+email+{0}@edx.org'.format)

View File

@@ -8,6 +8,7 @@ from django.test import TestCase
from django.test.client import Client
from django.test.utils import override_settings
from django.conf import settings
from django.contrib.auth.models import User
from django.core.cache import cache
from django.core.urlresolvers import reverse, NoReverseMatch
from django.http import HttpResponseBadRequest, HttpResponse
@@ -252,7 +253,7 @@ class LoginTest(TestCase):
self._assert_response(response, success=True)
# Reload the user from the database
self.user = UserFactory.FACTORY_FOR.objects.get(pk=self.user.pk)
self.user = User.objects.get(pk=self.user.pk)
self.assertEqual(self.user.profile.get_meta()['session_id'], client1.session.session_key)

View File

@@ -488,21 +488,18 @@ class DashboardTest(ModuleStoreTestCase):
self.assertContains(response, expected_url)
@unittest.skipUnless(settings.ROOT_URLCONF == 'lms.urls', 'Test only valid in lms')
@ddt.data((ModuleStoreEnum.Type.mongo, 1), (ModuleStoreEnum.Type.split, 3))
@ddt.unpack
def test_dashboard_metadata_caching(self, modulestore_type, expected_mongo_calls):
@ddt.data(ModuleStoreEnum.Type.mongo, ModuleStoreEnum.Type.split)
def test_dashboard_metadata_caching(self, modulestore_type):
"""
Check that the student dashboard makes use of course metadata caching.
After enrolling a student in a course, that course's metadata should be
cached as a CourseOverview. The student dashboard should never have to make
calls to the modulestore.
After creating a course, that course's metadata should be cached as a
CourseOverview. The student dashboard should never have to make calls to
the modulestore.
Arguments:
modulestore_type (ModuleStoreEnum.Type): Type of modulestore to create
test course in.
expected_mongo_calls (int >=0): Number of MongoDB queries expected for
a single call to the module store.
Note to future developers:
If you break this test so that the "check_mongo_calls(0)" fails,
@@ -512,11 +509,11 @@ class DashboardTest(ModuleStoreTestCase):
CourseDescriptor isn't necessary.
"""
# Create a course and log in the user.
test_course = CourseFactory.create(default_store=modulestore_type)
# Creating a new course will trigger a publish event and the course will be cached
test_course = CourseFactory.create(default_store=modulestore_type, emit_signals=True)
self.client.login(username="jack", password="test")
# Enrolling the user in the course will result in a modulestore query.
with check_mongo_calls(expected_mongo_calls):
with check_mongo_calls(0):
CourseEnrollment.enroll(self.user, test_course.id)
# Subsequent requests will only result in SQL queries to load the

View File

@@ -379,7 +379,7 @@ div.problem {
}
> span {
display: block;
display: inline-block;
margin-bottom: lh(0.5);
}

View File

@@ -206,9 +206,8 @@ class LTIFields(object):
ask_to_send_username = Boolean(
display_name=_("Request user's username"),
# Translators: This is used to request the user's username for a third party service.
# Usernames can only be requested if "Open in New Page" is set to True.
help=_(
"Select True to request the user's username. You must also set Open in New Page to True to get the user's information."
"Select True to request the user's username."
),
default=False,
scope=Scope.settings
@@ -216,9 +215,8 @@ class LTIFields(object):
ask_to_send_email = Boolean(
display_name=_("Request user's email"),
# Translators: This is used to request the user's email for a third party service.
# Emails can only be requested if "Open in New Page" is set to True.
help=_(
"Select True to request the user's email address. You must also set Open in New Page to True to get the user's information."
"Select True to request the user's email address."
),
default=False,
scope=Scope.settings
@@ -603,11 +601,10 @@ class LTIModule(LTIFields, LTI20ModuleMixin, XModule):
except AttributeError:
self.user_username = ""
if self.open_in_a_new_page:
if self.ask_to_send_username and self.user_username:
body["lis_person_sourcedid"] = self.user_username
if self.ask_to_send_email and self.user_email:
body["lis_person_contact_email_primary"] = self.user_email
if self.ask_to_send_username and self.user_username:
body["lis_person_sourcedid"] = self.user_username
if self.ask_to_send_email and self.user_email:
body["lis_person_contact_email_primary"] = self.user_email
# Appending custom parameter for signing.
body.update(custom_parameters)

View File

@@ -71,10 +71,11 @@ class XModuleFactory(Factory):
Factory for XModules
"""
# We have to give a Factory a FACTORY_FOR.
# We have to give a model for Factory.
# However, the class that we create is actually determined by the category
# specified in the factory
FACTORY_FOR = Dummy
class Meta(object): # pylint: disable=missing-docstring
model = Dummy
@lazy_attribute
def modulestore(self):
@@ -114,7 +115,7 @@ class CourseFactory(XModuleFactory):
name = kwargs.get('name', kwargs.get('run', Location.clean(kwargs.get('display_name'))))
run = kwargs.pop('run', name)
user_id = kwargs.pop('user_id', ModuleStoreEnum.UserID.test)
emit_signals = kwargs.get('emit_signals', False)
emit_signals = kwargs.pop('emit_signals', False)
# Pass the metadata just as field=value pairs
kwargs.update(kwargs.pop('metadata', {}))

View File

@@ -1,91 +0,0 @@
"""Provides factories for Split."""
from xmodule.modulestore import ModuleStoreEnum
from xmodule.course_module import CourseDescriptor
from xmodule.x_module import XModuleDescriptor
import factory
from factory.helpers import lazy_attribute
from opaque_keys.edx.keys import UsageKey
# Factories are self documenting
# pylint: disable=missing-docstring
class SplitFactory(factory.Factory):
"""
Abstracted superclass which defines modulestore so that there's no dependency on django
if the caller passes modulestore in kwargs
"""
@lazy_attribute
def modulestore(self):
# Delayed import so that we only depend on django if the caller
# hasn't provided their own modulestore
from xmodule.modulestore.django import modulestore
return modulestore()._get_modulestore_by_type(ModuleStoreEnum.Type.split)
class PersistentCourseFactory(SplitFactory):
"""
Create a new course (not a new version of a course, but a whole new index entry).
keywords: any xblock field plus (note, the below are filtered out; so, if they
become legitimate xblock fields, they won't be settable via this factory)
* org: defaults to textX
* master_branch: (optional) defaults to ModuleStoreEnum.BranchName.draft
* user_id: (optional) defaults to 'test_user'
* display_name (xblock field): will default to 'Robot Super Course' unless provided
"""
FACTORY_FOR = CourseDescriptor
# pylint: disable=unused-argument
@classmethod
def _create(cls, target_class, course='999', run='run', org='testX', user_id=ModuleStoreEnum.UserID.test,
master_branch=ModuleStoreEnum.BranchName.draft, **kwargs):
modulestore = kwargs.pop('modulestore')
root_block_id = kwargs.pop('root_block_id', 'course')
# Write the data to the mongo datastore
new_course = modulestore.create_course(
org, course, run, user_id, fields=kwargs,
master_branch=master_branch, root_block_id=root_block_id
)
return new_course
@classmethod
def _build(cls, target_class, *args, **kwargs):
raise NotImplementedError()
class ItemFactory(SplitFactory):
FACTORY_FOR = XModuleDescriptor
display_name = factory.LazyAttributeSequence(lambda o, n: "{} {}".format(o.category, n))
# pylint: disable=unused-argument
@classmethod
def _create(cls, target_class, parent_location, category='chapter',
user_id=ModuleStoreEnum.UserID.test, definition_locator=None, force=False,
continue_version=False, **kwargs):
"""
passes *kwargs* as the new item's field values:
:param parent_location: (required) the location of the course & possibly parent
:param category: (defaults to 'chapter')
:param definition_locator (optional): the DescriptorLocator for the definition this uses or branches
"""
modulestore = kwargs.pop('modulestore')
if isinstance(parent_location, UsageKey):
return modulestore.create_child(
user_id, parent_location, category, defintion_locator=definition_locator,
force=force, continue_version=continue_version, **kwargs
)
else:
return modulestore.create_item(
user_id, parent_location, category, defintion_locator=definition_locator,
force=force, continue_version=continue_version, **kwargs
)
@classmethod
def _build(cls, target_class, *args, **kwargs):
raise NotImplementedError()

View File

@@ -772,6 +772,122 @@ class SplitModuleCourseTests(SplitModuleTest):
self.assertEqual(len(result.children[0].children), 1)
self.assertEqual(result.children[0].children[0].locator.version_guid, versions[0])
@patch('xmodule.tabs.CourseTab.from_json', side_effect=mock_tab_from_json)
def test_persist_dag(self, _from_json):
"""
try saving temporary xblocks
"""
test_course = modulestore().create_course(
course='course', run='2014', org='testx',
display_name='fun test course', user_id='testbot',
master_branch=ModuleStoreEnum.BranchName.draft
)
test_chapter = modulestore().create_xblock(
test_course.system, test_course.id, 'chapter', fields={'display_name': 'chapter n'},
parent_xblock=test_course
)
self.assertEqual(test_chapter.display_name, 'chapter n')
test_def_content = '<problem>boo</problem>'
# create child
new_block = modulestore().create_xblock(
test_course.system, test_course.id,
'problem',
fields={
'data': test_def_content,
'display_name': 'problem'
},
parent_xblock=test_chapter
)
self.assertIsNotNone(new_block.definition_locator)
self.assertTrue(isinstance(new_block.definition_locator.definition_id, LocalId))
# better to pass in persisted parent over the subdag so
# subdag gets the parent pointer (otherwise 2 ops, persist dag, update parent children,
# persist parent
persisted_course = modulestore().persist_xblock_dag(test_course, 'testbot')
self.assertEqual(len(persisted_course.children), 1)
persisted_chapter = persisted_course.get_children()[0]
self.assertEqual(persisted_chapter.category, 'chapter')
self.assertEqual(persisted_chapter.display_name, 'chapter n')
self.assertEqual(len(persisted_chapter.children), 1)
persisted_problem = persisted_chapter.get_children()[0]
self.assertEqual(persisted_problem.category, 'problem')
self.assertEqual(persisted_problem.data, test_def_content)
# update it
persisted_problem.display_name = 'altered problem'
persisted_problem = modulestore().update_item(persisted_problem, 'testbot')
self.assertEqual(persisted_problem.display_name, 'altered problem')
@patch('xmodule.tabs.CourseTab.from_json', side_effect=mock_tab_from_json)
def test_block_generations(self, _from_json):
"""
Test get_block_generations
"""
test_course = modulestore().create_course(
org='edu.harvard',
course='history',
run='hist101',
display_name='history test course',
user_id='testbot',
master_branch=ModuleStoreEnum.BranchName.draft
)
chapter = modulestore().create_child(
None, test_course.location,
block_type='chapter',
block_id='chapter1',
fields={'display_name': 'chapter 1'}
)
sub = modulestore().create_child(
None, chapter.location,
block_type='vertical',
block_id='subsection1',
fields={'display_name': 'subsection 1'}
)
first_problem = modulestore().create_child(
None, sub.location,
block_type='problem',
block_id='problem1',
fields={'display_name': 'problem 1', 'data': '<problem></problem>'}
)
first_problem.max_attempts = 3
first_problem.save() # decache the above into the kvs
updated_problem = modulestore().update_item(first_problem, 'testbot')
self.assertIsNotNone(updated_problem.previous_version)
self.assertEqual(updated_problem.previous_version, first_problem.update_version)
self.assertNotEqual(updated_problem.update_version, first_problem.update_version)
modulestore().delete_item(updated_problem.location, 'testbot')
second_problem = modulestore().create_child(
None, sub.location.version_agnostic(),
block_type='problem',
block_id='problem2',
fields={'display_name': 'problem 2', 'data': '<problem></problem>'}
)
# The draft course root has 2 revisions: the published revision, and then the subsequent
# changes to the draft revision
version_history = modulestore().get_block_generations(test_course.location)
self.assertIsNotNone(version_history)
self.assertEqual(version_history.locator.version_guid, test_course.location.version_guid)
self.assertEqual(len(version_history.children), 1)
self.assertEqual(version_history.children[0].children, [])
self.assertEqual(version_history.children[0].locator.version_guid, chapter.location.version_guid)
# sub changed on add, add problem, delete problem, add problem in strict linear seq
version_history = modulestore().get_block_generations(sub.location)
self.assertEqual(len(version_history.children), 1)
self.assertEqual(len(version_history.children[0].children), 1)
self.assertEqual(len(version_history.children[0].children[0].children), 1)
self.assertEqual(len(version_history.children[0].children[0].children[0].children), 0)
# first and second problem may show as same usage_id; so, need to ensure their histories are right
version_history = modulestore().get_block_generations(updated_problem.location)
self.assertEqual(version_history.locator.version_guid, first_problem.location.version_guid)
self.assertEqual(len(version_history.children), 1) # updated max_attempts
self.assertEqual(len(version_history.children[0].children), 0)
version_history = modulestore().get_block_generations(second_problem.location)
self.assertNotEqual(version_history.locator.version_guid, first_problem.location.version_guid)
class TestCourseStructureCache(SplitModuleTest):
"""Tests for the CourseStructureCache"""

View File

@@ -104,7 +104,8 @@ class ModuleSystemFactory(Factory):
performed by :func:`xmodule.tests.get_test_system`, so
arguments for that function are valid factory attributes.
"""
FACTORY_FOR = ModuleSystem
class Meta(object): # pylint: disable=missing-docstring
model = ModuleSystem
@classmethod
def _build(cls, target_class, *args, **kwargs): # pylint: disable=unused-argument
@@ -119,7 +120,8 @@ class DescriptorSystemFactory(Factory):
performed by :func:`xmodule.tests.get_test_descriptor_system`, so
arguments for that function are valid factory attributes.
"""
FACTORY_FOR = DescriptorSystem
class Meta(object): # pylint: disable=missing-docstring
model = DescriptorSystem
@classmethod
def _build(cls, target_class, *args, **kwargs): # pylint: disable=unused-argument
@@ -190,7 +192,8 @@ class LeafDescriptorFactory(Factory):
"""
# pylint: disable=missing-docstring
FACTORY_FOR = XModuleDescriptor
class Meta(object):
model = XModuleDescriptor
runtime = SubFactory(DescriptorSystemFactory)
url_name = LazyAttributeSequence('{.block_type}_{}'.format)

View File

@@ -64,7 +64,8 @@ class XmlImportFactory(Factory):
Factory for generating XmlImportData's, which can hold all the data needed
to run an XModule XML import
"""
FACTORY_FOR = XmlImportData
class Meta(object): # pylint: disable=missing-docstring
model = XmlImportData
filesystem = MemoryFS()
xblock_mixins = (InheritanceMixin, XModuleMixin)

View File

@@ -14,12 +14,15 @@
'submit .search-form': 'performSearch',
'blur .search-form': 'onFocusOut',
'keyup .search-field': 'refreshState',
'click .action-clear': 'clearSearch'
'click .action-clear': 'clearSearch',
'mouseover .action-clear': 'setMouseOverState',
'mouseout .action-clear': 'setMouseOutState',
},
initialize: function(options) {
this.type = options.type;
this.label = options.label;
this.mouseOverClear = false;
},
refreshState: function() {
@@ -43,10 +46,18 @@
return this;
},
setMouseOverState: function(event) {
this.mouseOverClear = true;
},
setMouseOutState: function(event) {
this.mouseOverClear = false;
},
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')) {
if (!this.mouseOverClear) {
this.performSearch(event);
}
},

View File

@@ -1 +0,0 @@
console.error("Can't load Tender -- anything that relies on it will fail");

View File

@@ -1,7 +1,7 @@
// common - utilities - mixins and extends
// ====================
// Table of Contents
// Table of Contents
// * +Font Sizing - Mixin
// * +Line Height - Mixin
// * +Sizing - Mixin
@@ -26,34 +26,34 @@
// * +Icon - Font-Awesome - Extend
// +Font Sizing - Mixin
// ====================
// ====================
@mixin font-size($sizeValue: 16){
font-size: $sizeValue + px;
font-size: ($sizeValue/10) + rem;
}
// +Line Height - Mixin
// ====================
// ====================
@mixin line-height($fontSize: auto){
line-height: ($fontSize*1.48) + px;
line-height: (($fontSize/10)*1.48) + rem;
}
// +Sizing - Mixin
// ====================
// ====================
@mixin size($width: $baseline, $height: $baseline) {
height: $height;
width: $width;
}
// +Square - Mixin
// ====================
// ====================
@mixin square($size: $baseline) {
@include size($size);
}
// +Placeholder Styling - Mixin
// ====================
// ====================
@mixin placeholder($color) {
:-moz-placeholder {
color: $color;
@@ -67,7 +67,7 @@
}
// +Flex Support - Mixin
// ====================
// ====================
@mixin ui-flexbox() {
display: -webkit-box;
display: -moz-box;
@@ -77,7 +77,7 @@
}
// +Flex PolyFill - Extends
// ====================
// ====================
// justify-content right for display:flex alignment in older browsers
%ui-justify-right-flex {
@@ -107,7 +107,7 @@
// +UI - Wrapper - Extends
// ====================
// ====================
// used for page/view-level wrappers (for centering/grids)
%ui-wrapper {
@include clearfix();
@@ -128,7 +128,7 @@
}
// +UI - Window - Extends
// ====================
// ====================
%ui-window {
@include clearfix();
border-radius: ($baseline/10);
@@ -144,13 +144,13 @@
}
// +UI - Visual Link - Extends
// ====================
// ====================
%ui-fake-link {
cursor: pointer;
}
// +UI - Functional Disable - Extends
// ====================
// ====================
%ui-disabled {
pointer-events: none;
outline: none;
@@ -158,7 +158,7 @@
}
// +UI - Depth Levels - Extends
// ====================
// ====================
%ui-depth0 { z-index: 0; }
%ui-depth1 { z-index: 10; }
%ui-depth2 { z-index: 100; }
@@ -168,7 +168,7 @@
// +UI - Clear Children - Extends
// ====================
// ====================
// extends - UI - utility - first child clearing
%wipe-first-child {
@@ -190,7 +190,7 @@
}
// +UI - Buttons - Extends
// ====================
// ====================
%ui-btn {
@include box-sizing(border-box);
@include transition(color $tmg-f2 ease-in-out 0s, border-color $tmg-f2 ease-in-out 0s, background $tmg-f2 ease-in-out 0s, box-shadow $tmg-f2 ease-in-out 0s);
@@ -329,7 +329,7 @@
}
// +UI - Well Archetype - Extends
// ====================
// ====================
%ui-well {
box-shadow: inset 0 1px 2px 1px $shadow;
padding: ($baseline*0.75) $baseline;
@@ -378,7 +378,7 @@
}
// +Content - No List - Extends
// ====================
// ====================
// removes list styling/spacing when using uls, ols for navigation and less content-centric cases
%cont-no-list {
list-style: none;
@@ -393,7 +393,7 @@
}
// +Content - Hidden Image Text - Extend
// ====================
// ====================
// image-replacement hidden text
%cont-text-hide {
text-indent: 100%;
@@ -402,7 +402,7 @@
}
// +Content - Screenreader Text - Extend
// ====================
// ====================
%cont-text-sr {
border: 0;
clip: rect(0 0 0 0);
@@ -415,13 +415,13 @@
}
// +Content - Text Wrap - Extend
// ====================
// ====================
%cont-text-wrap {
word-wrap: break-word;
}
// +Content - Text Truncate - Extend
// ====================
// ====================
%cont-truncated {
@include box-sizing(border-box);
overflow: hidden;
@@ -430,7 +430,7 @@
}
// * +Icon - Font-Awesome - Extend
// ====================
// ====================
%use-font-awesome {
display: inline-block;
font-family: FontAwesome;

View File

@@ -68,6 +68,9 @@ from django.core.urlresolvers import reverse
</header>
<form class="form-register-choose" method="post" name="enrollment_mode_form" id="enrollment_mode_form">
<%
b_tag_kwargs = {'b_start': '<b>', 'b_end': '</b>'}
%>
% if "verified" in modes:
<div class="register-choice register-choice-certificate">
<div class="wrapper-copy">
@@ -82,9 +85,9 @@ from django.core.urlresolvers import reverse
<div class="copy-inline">
<h4>${_("Benefits of a Verified Certificate")}</h4>
<ul>
<li>${_("{b_start}Eligible for credit:{b_end} Receive academic credit after successfully completing the course").format(b_start='<b>', b_end='</b>')}</li>
<li>${_("{b_start}Official:{b_end} Receive an instructor-signed certificate with the institution's logo").format(b_start='<b>', b_end='</b>')}</li>
<li>${_("{b_start}Easily shareable:{b_end} Add the certificate to your CV or resume, or post it directly on LinkedIn").format(b_start='<b>', b_end='</b>')}</li>
<li>${_("{b_start}Eligible for credit:{b_end} Receive academic credit after successfully completing the course").format(**b_tag_kwargs)}</li>
<li>${_("{b_start}Official:{b_end} Receive an instructor-signed certificate with the institution's logo").format(**b_tag_kwargs)}</li>
<li>${_("{b_start}Easily shareable:{b_end} Add the certificate to your CV or resume, or post it directly on LinkedIn").format(**b_tag_kwargs)}</li>
</ul>
</div>
<div class="copy-inline list-actions">
@@ -108,9 +111,12 @@ from django.core.urlresolvers import reverse
<div class="copy-inline">
<h4>${_("Benefits of a Verified Certificate")}</h4>
<ul>
<li>${_("{b_start}Official: {b_end}Receive an instructor-signed certificate with the institution's logo").format(b_start='<b>', b_end='</b>')}</li>
<li>${_("{b_start}Easily shareable: {b_end}Add the certificate to your CV or resume, or post it directly on LinkedIn").format(b_start='<b>', b_end='</b>')}</li>
<li>${_("{b_start}Motivating: {b_end}Give yourself an additional incentive to complete the course").format(b_start='<b>', b_end='</b>')}</li>
<li>${_("{b_start}Official: {b_end}Receive an instructor-signed certificate with the institution's logo").format(**b_tag_kwargs)}</li>
<li>${_("{b_start}Easily shareable: {b_end}Add the certificate to your CV or resume, or post it directly on LinkedIn").format(**b_tag_kwargs)}</li>
<li>${_("{b_start}Motivating: {b_end}Give yourself an additional incentive to complete the course").format(**b_tag_kwargs)}</li>
% if settings.FEATURES.get('IS_EDX_DOMAIN', False):
<li>${_("{b_start}Support our Mission: {b_end} EdX, a non-profit, relies on verified certificates to help fund free education for everyone globally").format(**b_tag_kwargs)}</li>
% endif
</ul>
</div>
<div class="copy-inline list-actions">

View File

@@ -12,7 +12,8 @@ from . import COMMENTS_STUB_URL
class ContentFactory(factory.Factory):
FACTORY_FOR = dict
class Meta(object): # pylint: disable=missing-docstring
model = dict
id = None
user_id = "1234"
username = "dummy-username"
@@ -63,7 +64,8 @@ class Response(Comment):
class SearchResult(factory.Factory):
FACTORY_FOR = dict
class Meta(object): # pylint: disable=missing-docstring
model = dict
discussion_data = []
annotated_content_info = {}
num_pages = 1

View File

@@ -10,7 +10,8 @@ from . import EDXNOTES_STUB_URL
class Range(factory.Factory):
FACTORY_FOR = dict
class Meta(object): # pylint: disable=missing-docstring
model = dict
start = "/div[1]/p[1]"
end = "/div[1]/p[1]"
startOffset = 0
@@ -18,7 +19,8 @@ class Range(factory.Factory):
class Note(factory.Factory):
FACTORY_FOR = dict
class Meta(object): # pylint: disable=missing-docstring
model = dict
user = "dummy-user"
usage_id = "dummy-usage-id"
course_id = "dummy-course-id"

View File

@@ -72,7 +72,7 @@ class InstructorDashboardPage(CoursePage):
"""
self.q(css='a[data-section=proctoring]').first.click()
proctoring_section = ProctoringPage(self.browser)
proctoring_section.wait_for_ajax()
proctoring_section.wait_for_page()
return proctoring_section
@staticmethod

View File

@@ -4,11 +4,13 @@ Course Schedule and Details Settings page.
"""
from __future__ import unicode_literals
from bok_choy.promise import EmptyPromise
from bok_choy.javascript import requirejs
from .course_page import CoursePage
from .utils import press_the_notification_button
@requirejs('js/factories/settings')
class SettingsPage(CoursePage):
"""
Course Schedule and Details Settings page.
@@ -22,6 +24,13 @@ class SettingsPage(CoursePage):
def is_browser_on_page(self):
return self.q(css='body.view-settings').present
def wait_for_require_js(self):
"""
Wait for require-js to load javascript files.
"""
if hasattr(self, 'wait_for_js'):
self.wait_for_js() # pylint: disable=no-member
def refresh_and_wait_for_load(self):
"""
Refresh the page and wait for all resources to load.
@@ -182,4 +191,5 @@ class SettingsPage(CoursePage):
lambda: self.q(css='body.view-settings').present,
'Page is refreshed'
).fulfill()
self.wait_for_require_js()
self.wait_for_ajax()

View File

@@ -12,6 +12,7 @@ import os
from bok_choy.promise import EmptyPromise
from .course_page import CoursePage
from common.test.acceptance.tests.helpers import disable_animations
class CertificatesPage(CoursePage):
@@ -138,8 +139,10 @@ class CertificatesPage(CoursePage):
"""
Clicks the main action presented by the prompt (such as 'Delete')
"""
disable_animations(self)
self.wait_for_confirmation_prompt()
self.q(css='button.action-primary').first.click()
self.q(css='.prompt button.action-primary').first.click()
self.wait_for_element_invisibility('.prompt', 'wait for pop up to disappear')
self.wait_for_ajax()
@@ -263,7 +266,7 @@ class Certificate(object):
Returns whether or not the certificate delete icon is present.
"""
EmptyPromise(
lambda: self.find_css('.actions .delete').present,
lambda: self.find_css('.actions .delete.action-icon').present,
'Certificate delete button is displayed'
).fulfill()
@@ -323,8 +326,7 @@ class Certificate(object):
Remove the first (possibly the only) certificate from the set
"""
self.wait_for_certificate_delete_button()
self.find_css('.actions .delete').first.click()
self.page.wait_for_ajax()
self.find_css('.actions .delete.action-icon').first.click()
class Signatory(object):

View File

@@ -4,6 +4,7 @@ Utility methods useful for Studio page tests.
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.keys import Keys
from bok_choy.javascript import js_defined
from bok_choy.promise import EmptyPromise
from ..common.utils import click_css, wait_for_notification
@@ -199,3 +200,17 @@ def verify_ordering(test_class, page, expected_orderings):
blocks_checked.add(expected)
break
test_class.assertEqual(len(blocks_checked), len(xblocks))
def click_studio_help(page):
"""Click the Studio help link in the page footer."""
page.q(css='.cta-show-sock').click()
EmptyPromise(
lambda: page.q(css='.support .list-actions a').results[0].text != '',
'Support section opened'
).fulfill()
def studio_help_links(page):
"""Return the list of Studio help links in the page footer."""
return page.q(css='.support .list-actions a').results

View File

@@ -480,7 +480,7 @@ class PayAndVerifyTest(EventsTestMixin, UniqueCourseTest):
self.assertEqual(enrollment_mode, 'verified')
@attr('shard_5')
@attr('shard_1')
class CourseWikiTest(UniqueCourseTest):
"""
Tests that verify the course wiki.
@@ -534,7 +534,7 @@ class CourseWikiTest(UniqueCourseTest):
self.assertEqual(content, actual_content)
@attr('shard_5')
@attr('shard_1')
class HighLevelTabTest(UniqueCourseTest):
"""
Tests that verify each of the high-level tabs available within a course.
@@ -720,7 +720,7 @@ class PDFTextBooksTabTest(UniqueCourseTest):
self.tab_nav.go_to_tab("PDF Book {}".format(i))
@attr('shard_5')
@attr('shard_1')
class VideoTest(UniqueCourseTest):
"""
Navigate to a video in the courseware and play it.
@@ -791,7 +791,7 @@ class VideoTest(UniqueCourseTest):
self.assertGreaterEqual(self.video.duration, self.video.elapsed_time)
@attr('shard_5')
@attr('shard_1')
class VisibleToStaffOnlyTest(UniqueCourseTest):
"""
Tests that content with visible_to_staff_only set to True cannot be viewed by students.
@@ -876,7 +876,7 @@ class VisibleToStaffOnlyTest(UniqueCourseTest):
self.assertEqual(["Html Child in visible unit"], self.course_nav.sequence_items)
@attr('shard_5')
@attr('shard_1')
class TooltipTest(UniqueCourseTest):
"""
Tests that tooltips are displayed
@@ -921,7 +921,7 @@ class TooltipTest(UniqueCourseTest):
self.assertTrue(self.courseware_page.tooltips_displayed())
@attr('shard_5')
@attr('shard_1')
class PreRequisiteCourseTest(UniqueCourseTest):
"""
Tests that pre-requisite course messages are displayed
@@ -1006,7 +1006,7 @@ class PreRequisiteCourseTest(UniqueCourseTest):
self.settings_page.save_changes()
@attr('shard_5')
@attr('shard_1')
class ProblemExecutionTest(UniqueCourseTest):
"""
Tests of problems.
@@ -1085,7 +1085,7 @@ class ProblemExecutionTest(UniqueCourseTest):
self.assertFalse(problem_page.is_correct())
@attr('shard_5')
@attr('shard_1')
class EntranceExamTest(UniqueCourseTest):
"""
Tests that course has an entrance exam.
@@ -1156,7 +1156,7 @@ class EntranceExamTest(UniqueCourseTest):
))
@attr('shard_5')
@attr('shard_1')
class NotLiveRedirectTest(UniqueCourseTest):
"""
Test that a banner is shown when the user is redirected to

View File

@@ -44,7 +44,7 @@ class BaseInstructorDashboardTest(EventsTestMixin, UniqueCourseTest):
return instructor_dashboard_page
@attr('shard_5')
@attr('shard_1')
class AutoEnrollmentWithCSVTest(BaseInstructorDashboardTest):
"""
End-to-end tests for Auto-Registration and enrollment functionality via CSV file.
@@ -209,7 +209,7 @@ class ProctoredExamsTest(BaseInstructorDashboardTest):
self._auto_auth("STAFF_TESTER", "staff101@example.com", True)
self.course_outline.visit()
#open the exam settings to make it a proctored exam.
# open the exam settings to make it a proctored exam.
self.course_outline.open_exam_settings_dialog()
self.course_outline.make_exam_timed()
time.sleep(2) # Wait for 2 seconds to save the settings.
@@ -222,14 +222,12 @@ class ProctoredExamsTest(BaseInstructorDashboardTest):
# Start the proctored exam.
self.courseware_page.start_timed_exam()
@flaky # TODO fix this, see SOL-1183
def test_can_add_remove_allowance(self):
"""
Make sure that allowances can be added and removed.
"""
# Given that an exam has been configured to be a proctored exam.
self._create_a_proctored_exam_and_attempt()
# Given that an exam has been configured to be a timed exam.
self._create_a_timed_exam_and_attempt()
# When I log in as an instructor,
self.log_in_as_instructor()
@@ -267,7 +265,7 @@ class ProctoredExamsTest(BaseInstructorDashboardTest):
self.assertFalse(exam_attempts_section.is_student_attempt_visible)
@attr('shard_5')
@attr('shard_1')
class EntranceExamGradeTest(BaseInstructorDashboardTest):
"""
Tests for Entrance exam specific student grading tasks.
@@ -559,7 +557,7 @@ class DataDownloadsTest(BaseInstructorDashboardTest):
self.verify_report_download(report_name)
@attr('shard_5')
@attr('shard_1')
class CertificatesTest(BaseInstructorDashboardTest):
"""
Tests for Certificates functionality on instructor dashboard.

View File

@@ -0,0 +1,46 @@
"""
Test the Studio help links.
"""
from .base_studio_test import StudioCourseTest
from ...pages.studio.index import DashboardPage
from ...pages.studio.utils import click_studio_help, studio_help_links
class StudioHelpTest(StudioCourseTest):
"""Tests for Studio help."""
def test_studio_help_links(self):
"""Test that the help links are present and have the correct content."""
page = DashboardPage(self.browser)
page.visit()
click_studio_help(page)
links = studio_help_links(page)
expected_links = [{
'href': u'http://docs.edx.org/',
'text': u'edX Documentation',
'sr_text': u'Access documentation on http://docs.edx.org'
}, {
'href': u'https://open.edx.org/',
'text': u'Open edX Portal',
'sr_text': u'Access the Open edX Portal'
}, {
'href': u'https://www.edx.org/course/overview-creating-edx-course-edx-edx101#.VO4eaLPF-n1',
'text': u'Enroll in edX101',
'sr_text': u'Enroll in edX101: Overview of Creating an edX Course'
}, {
'href': u'https://www.edx.org/course/creating-course-edx-studio-edx-studiox',
'text': u'Enroll in StudioX',
'sr_text': u'Enroll in StudioX: Creating a Course with edX Studio'
}, {
'href': u'mailto:partner-support@example.com',
'text': u'Contact Us',
'sr_text': 'Send an email to partner-support@example.com'
}]
for expected, actual in zip(expected_links, links):
self.assertEqual(expected['href'], actual.get_attribute('href'))
self.assertEqual(expected['text'], actual.text)
self.assertEqual(
expected['sr_text'],
actual.find_element_by_xpath('following-sibling::span').text
)

View File

@@ -186,7 +186,7 @@ class LibraryEditPageTest(StudioLibraryTest):
self.assertIn("Checkboxes", problem_block.name)
@attr('shard_5')
@attr('shard_2')
@ddt
class LibraryNavigationTest(StudioLibraryTest):
"""

View File

@@ -107,7 +107,6 @@ class CertificatesTest(StudioCourseTest):
self.assertIn("Updated Course Title Override 2", certificate.course_title)
@flaky # TODO fix this, see SOL-1199
def test_can_delete_certificate(self):
"""
Scenario: Ensure that the user can delete certificate.

View File

@@ -40,7 +40,6 @@ class SettingsMilestonesTest(StudioCourseTest):
self.assertTrue(self.settings_detail.pre_requisite_course_options)
@skip # TODO: fix this. SOL-449
def test_prerequisite_course_save_successfully(self):
"""
Scenario: Selecting course from Pre-Requisite course drop down save the selected course as pre-requisite

Binary file not shown.

View File

@@ -131,7 +131,7 @@ msgid ""
msgstr ""
"Project-Id-Version: edx-platform\n"
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
"POT-Creation-Date: 2015-09-11 12:16+0000\n"
"POT-Creation-Date: 2015-09-18 13:23+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"
@@ -3751,25 +3751,16 @@ msgid "Request user's username"
msgstr "يُرجى طلب اسم المستخدم الخاص بالمستخدم"
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's username. You must also set Open in New "
"Page to True to get the user's information."
msgid "Select True to request the user's username."
msgstr ""
"يُرجى اختيار \"صحيح\" لطلب اسم المستخدم الخاص بالمستخدم، ويجب أيضًا ضبط "
"خاصية \"فتح في صفحة جديدة\" على خيار \"صحيح\" للحصول على معلومات المستخدم."
#: common/lib/xmodule/xmodule/lti_module.py
msgid "Request user's email"
msgstr "يُرجى طلب البريد الإلكتروني للمستخدم"
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's email address. You must also set Open in "
"New Page to True to get the user's information."
msgid "Select True to request the user's email address."
msgstr ""
"يُرجى اختيار \"صحيح\" لطلب عنوان البريد الإلكتروني الخاص بالمستخدم. ويجب "
"أيضًا ضبط خاصية \"فتح في صفحة جديدة\" على خيار \"صحيح\" أيضًا للحصول على "
"معلومات المستخدم."
#: common/lib/xmodule/xmodule/lti_module.py
msgid "LTI Application Information"
@@ -8405,10 +8396,6 @@ msgstr ""
msgid "The supplied topic id {topic_id} is not valid"
msgstr "الرقم التعريفي الذي جرى توفيره حول الموضوع {topic_id} غير صالح."
#: lms/djangoapps/teams/views.py
msgid "Error connecting to elasticsearch"
msgstr ""
#. Translators: 'ordering' is a string describing a way
#. of ordering a list. For example, {ordering} may be
#. 'name', indicating that the user wants to sort the
@@ -12513,8 +12500,6 @@ msgstr "إرسال تغريدة حول أنّك سجَّلت في هذا الم
msgid "Email someone to say you've registered for this course"
msgstr "مراسلة شخص ما عبر البريد الإلكتروني لإخباره أنّك سجّلت في هذا المساق "
#. Translators: This text will be automatically posted to the student's
#. Twitter account. {url} should appear at the end of the text.
#: lms/templates/courseware/course_about.html
msgid "I just registered for {number} {title} through {account}: {url}"
msgstr "سجّلتُ لتوّي في {number} {title} من خلال {url} :{account}"
@@ -13018,6 +13003,8 @@ msgstr "سوف يفتح ملف PDF في نافذة متصفح جديدة أو ت
msgid "Download Your Certificate"
msgstr "تنزيل شهادتك"
#. Translators: This message appears to users when the system is processessing
#. course certificates, which can take a few hours.
#: lms/templates/courseware/progress.html
msgid "We're working on it..."
msgstr "جاري العمل على ذلك..."
@@ -17689,9 +17676,8 @@ msgstr ""
msgid "Required Information to Create a re-run of a course"
msgstr "المعلومات المطلوبة لإنشاء تشغيل ثانٍ لمساق ما"
#. Translators: This is an example name for a new course, seen when filling
#. out
#. the form to create a new course.
#. Translators: This is an example name for a new course, seen when
#. filling out the form to create a new course.
#: cms/templates/course-create-rerun.html cms/templates/index.html
msgid "e.g. Introduction to Computer Science"
msgstr "مثلًا، مقدّمة لعلوم الكمبيوتر"
@@ -19064,8 +19050,8 @@ msgid "Library Name"
msgstr "اسم المكتبة"
#. Translators: This is an example name for a new content library, seen when
#. filling out the form to create a new library. (A library is a collection of
#. content or problems.)
#. filling out the form to create a new library.
#. (A library is a collection of content or problems.)
#: cms/templates/index.html
msgid "e.g. Computer Science Problems"
msgstr "مثلًا، مسائل علوم الكمبيوتر"
@@ -19088,8 +19074,9 @@ msgstr "رمز المكتبة"
#. Translators: This is an example for the "code" used to identify a library,
#. seen when filling out the form to create a new library. This example is
#. short for "Computer Science Problems". The example number may contain
#. letters but must not contain spaces.
#. short
#. for "Computer Science Problems". The example number may contain letters
#. but must not contain spaces.
#: cms/templates/index.html
msgid "e.g. CSPROB"
msgstr "مثلًا، CSPROB"
@@ -19118,10 +19105,11 @@ msgstr "تشغيل المساق:"
msgid "This course run is currently being created."
msgstr "يجري حاليًّا إنشاء تشغيل هذا المساق."
#. Translators: This is a status message, used to inform the user of what the
#. system is doing. This status means that the user has requested to re-run an
#. existing course, and the system is currently in the process of duplicating
#. and configuring the existing course so that it can be re-run.
#. Translators: This is a status message, used to inform the user of
#. what the system is doing. This status means that the user has
#. requested to re-run an existing course, and the system is currently
#. in the process of duplicating and configuring the existing course
#. so that it can be re-run.
#: cms/templates/index.html
msgid "Configuring as re-run"
msgstr "الضبط كتشغيل ثانٍ"
@@ -19136,6 +19124,18 @@ msgstr ""
"هذه الصفحة أو {link_start}إعادة فتحها{link_end} لتحديث لائحة المساقات. "
"وسيتطلّب المساق الجديد ضبط بعض الإعدادات يدويًّا."
#. Translators: This is a status message for the course re-runs feature.
#. When a course admin indicates that a course should be re-run, the system
#. needs to process the request and prepare the new course. The status of
#. the process will follow this text.
#: cms/templates/index.html
msgid "This re-run processing status:"
msgstr ""
#: cms/templates/index.html
msgid "Configuration Error"
msgstr ""
#: cms/templates/index.html
msgid ""
"A system error occurred while your course was being processed. Please go to "
@@ -20153,7 +20153,7 @@ msgstr "يجب أن تزيد عن درجة النجاح في المساق أو
#: cms/templates/settings_graders.html
msgid "Grading Rules &amp; Policies"
msgstr "سياسات قواعد &amp; التقييم"
msgstr "سياسات وقواعد التقييم"
#: cms/templates/settings_graders.html
msgid "Deadlines, requirements, and logistics around grading student work"

View File

@@ -81,7 +81,7 @@ msgid ""
msgstr ""
"Project-Id-Version: edx-platform\n"
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
"POT-Creation-Date: 2015-09-11 12:15+0000\n"
"POT-Creation-Date: 2015-09-18 13:22+0000\n"
"PO-Revision-Date: 2015-09-11 12:17+0000\n"
"Last-Translator: Sarina Canelake <sarina@edx.org>\n"
"Language-Team: Arabic (http://www.transifex.com/open-edx/edx-platform/language/ar/)\n"

Binary file not shown.

View File

@@ -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-09-11 12:47+0000\n"
"PO-Revision-Date: 2015-09-11 12:47:23.251524\n"
"POT-Creation-Date: 2015-09-18 13:39+0000\n"
"PO-Revision-Date: 2015-09-18 13:39:23.492978\n"
"Last-Translator: \n"
"Language-Team: openedx-translation <openedx-translation@googlegroups.com>\n"
"MIME-Version: 1.0\n"
@@ -4154,24 +4154,20 @@ msgid "Request user's username"
msgstr "Réqüést üsér's üsérnämé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σ#"
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's username. You must also set Open in New "
"Page to True to get the user's information."
msgid "Select True to request the user's username."
msgstr ""
"Séléçt Trüé tö réqüést thé üsér's üsérnämé. Ýöü müst älsö sét Öpén ïn Néw "
"Pägé tö Trüé tö gét thé üsér's ïnförmätïön. Ⱡ'σяєм ιρѕυм ∂#"
"Séléçt Trüé tö réqüést thé üsér's üsérnämé. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"¢σηѕє¢тєтυя #"
#: common/lib/xmodule/xmodule/lti_module.py
msgid "Request user's email"
msgstr "Réqüést üsér's émäïl Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's email address. You must also set Open in "
"New Page to True to get the user's information."
msgid "Select True to request the user's email address."
msgstr ""
"Séléçt Trüé tö réqüést thé üsér's émäïl äddréss. Ýöü müst älsö sét Öpén ïn "
"Néw Pägé tö Trüé tö gét thé üsér's ïnförmätïön. Ⱡ'σяєм ιρѕ#"
"Séléçt Trüé tö réqüést thé üsér's émäïl äddréss. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт "
"αмєт, ¢σηѕє¢тєтυя α#"
#: common/lib/xmodule/xmodule/lti_module.py
msgid "LTI Application Information"
@@ -9566,11 +9562,6 @@ msgstr ""
"Thé süpplïéd töpïç ïd {topic_id} ïs nöt välïd Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"¢σηѕє¢тєтυя#"
#: lms/djangoapps/teams/views.py
msgid "Error connecting to elasticsearch"
msgstr ""
"Érrör çönnéçtïng tö élästïçséärçh Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢тє#"
#. Translators: 'ordering' is a string describing a way
#. of ordering a list. For example, {ordering} may be
#. 'name', indicating that the user wants to sort the
@@ -14176,8 +14167,6 @@ msgstr ""
"Émäïl söméöné tö säý ýöü'vé régïstéréd för thïs çöürsé Ⱡ'σяєм ιρѕυм ∂σłσя "
"ѕιт αмєт, ¢σηѕє¢тєтυя α#"
#. Translators: This text will be automatically posted to the student's
#. Twitter account. {url} should appear at the end of the text.
#: lms/templates/courseware/course_about.html
msgid "I just registered for {number} {title} through {account}: {url}"
msgstr ""
@@ -14762,6 +14751,8 @@ msgstr ""
msgid "Download Your Certificate"
msgstr "Döwnlöäd Ýöür Çértïfïçäté Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕ#"
#. Translators: This message appears to users when the system is processessing
#. course certificates, which can take a few hours.
#: lms/templates/courseware/progress.html
msgid "We're working on it..."
msgstr "Wé'ré wörkïng ön ït... Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢#"
@@ -20219,9 +20210,8 @@ msgstr ""
"Réqüïréd Ìnförmätïön tö Çréäté ä ré-rün öf ä çöürsé Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт "
"αмєт, ¢σηѕє¢тєтυя α#"
#. Translators: This is an example name for a new course, seen when filling
#. out
#. the form to create a new course.
#. Translators: This is an example name for a new course, seen when
#. filling out the form to create a new course.
#: cms/templates/course-create-rerun.html cms/templates/index.html
msgid "e.g. Introduction to Computer Science"
msgstr ""
@@ -21883,8 +21873,8 @@ msgid "Library Name"
msgstr "Lïßrärý Nämé Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
#. Translators: This is an example name for a new content library, seen when
#. filling out the form to create a new library. (A library is a collection of
#. content or problems.)
#. filling out the form to create a new library.
#. (A library is a collection of content or problems.)
#: cms/templates/index.html
msgid "e.g. Computer Science Problems"
msgstr "é.g. Çömpütér Sçïénçé Prößléms Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
@@ -21911,8 +21901,9 @@ msgstr "Lïßrärý Çödé Ⱡ'σяєм ιρѕυм ∂σłσя ѕ#"
#. Translators: This is an example for the "code" used to identify a library,
#. seen when filling out the form to create a new library. This example is
#. short for "Computer Science Problems". The example number may contain
#. letters but must not contain spaces.
#. short
#. for "Computer Science Problems". The example number may contain letters
#. but must not contain spaces.
#: cms/templates/index.html
msgid "e.g. CSPROB"
msgstr "é.g. ÇSPRÖB Ⱡ'σяєм ιρѕυм ∂σłσя #"
@@ -21945,10 +21936,11 @@ msgstr ""
"Thïs çöürsé rün ïs çürréntlý ßéïng çréätéd. Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, "
"¢σηѕє¢тєтυя #"
#. Translators: This is a status message, used to inform the user of what the
#. system is doing. This status means that the user has requested to re-run an
#. existing course, and the system is currently in the process of duplicating
#. and configuring the existing course so that it can be re-run.
#. Translators: This is a status message, used to inform the user of
#. what the system is doing. This status means that the user has
#. requested to re-run an existing course, and the system is currently
#. in the process of duplicating and configuring the existing course
#. so that it can be re-run.
#: cms/templates/index.html
msgid "Configuring as re-run"
msgstr "Çönfïgürïng äs ré-rün Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, #"
@@ -21968,6 +21960,18 @@ msgstr ""
"αυтє ιяυяє ∂σłσя ιη яєρяєнєη∂єяιт ιη νσłυρтαтє νєłιт єѕѕє ¢ιłłυм ∂σłσяє єυ "
υgιαт ηυłłα ραяιαтυя. єχ¢єρтєυя ѕιηт σ¢¢αє¢αт ¢υρι∂αтαт ηση ρяσι∂єηт,#"
#. Translators: This is a status message for the course re-runs feature.
#. When a course admin indicates that a course should be re-run, the system
#. needs to process the request and prepare the new course. The status of
#. the process will follow this text.
#: cms/templates/index.html
msgid "This re-run processing status:"
msgstr "Thïs ré-rün pröçéssïng stätüs: Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт, ¢σηѕє¢т#"
#: cms/templates/index.html
msgid "Configuration Error"
msgstr "Çönfïgürätïön Érrör Ⱡ'σяєм ιρѕυм ∂σłσя ѕιт αмєт,#"
#: cms/templates/index.html
msgid ""
"A system error occurred while your course was being processed. Please go to "

View File

@@ -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-09-11 12:46+0000\n"
"PO-Revision-Date: 2015-09-11 12:47:23.562016\n"
"POT-Creation-Date: 2015-09-18 13:38+0000\n"
"PO-Revision-Date: 2015-09-18 13:39:23.855088\n"
"Last-Translator: \n"
"Language-Team: openedx-translation <openedx-translation@googlegroups.com>\n"
"MIME-Version: 1.0\n"

View File

@@ -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-09-11 12:16+0000\n"
"POT-Creation-Date: 2015-09-18 13:23+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"
@@ -3829,26 +3829,16 @@ msgid "Request user's username"
msgstr "Solicite el nombre del usuario"
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's username. You must also set Open in New "
"Page to True to get the user's information."
msgid "Select True to request the user's username."
msgstr ""
"Seleccione True para solicitar el nombre de usuario al usuario. También "
"puede configurar La apertura en una nueva página en True para obtener la "
"información del usuario."
#: common/lib/xmodule/xmodule/lti_module.py
msgid "Request user's email"
msgstr "Solicite la dirección de correo del usuario"
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's email address. You must also set Open in "
"New Page to True to get the user's information."
msgid "Select True to request the user's email address."
msgstr ""
"Seleccione True para solicitar el correo electrónico del usuario. También "
"puede configurar la apertura en una nueva página en True para obtener la "
"información del usuario."
#: common/lib/xmodule/xmodule/lti_module.py
msgid "LTI Application Information"
@@ -8628,10 +8618,6 @@ msgstr ""
msgid "The supplied topic id {topic_id} is not valid"
msgstr "El ID de tema proporcionado {topic_id} no es válido"
#: lms/djangoapps/teams/views.py
msgid "Error connecting to elasticsearch"
msgstr ""
#. Translators: 'ordering' is a string describing a way
#. of ordering a list. For example, {ordering} may be
#. 'name', indicating that the user wants to sort the
@@ -12818,8 +12804,6 @@ msgstr "Publica que te has registrado en este curso"
msgid "Email someone to say you've registered for this course"
msgstr "Envía un correo a tus amigos que te has registrado en este curso"
#. Translators: This text will be automatically posted to the student's
#. Twitter account. {url} should appear at the end of the text.
#: lms/templates/courseware/course_about.html
msgid "I just registered for {number} {title} through {account}: {url}"
msgstr ""
@@ -13337,6 +13321,8 @@ msgstr "El PDF se abrirá en una nueva ventana o pestaña del navegador."
msgid "Download Your Certificate"
msgstr "Descargar Tu certificaddo"
#. Translators: This message appears to users when the system is processessing
#. course certificates, which can take a few hours.
#: lms/templates/courseware/progress.html
msgid "We're working on it..."
msgstr "Estamos trabajando en eso..."
@@ -18149,9 +18135,8 @@ msgstr ""
msgid "Required Information to Create a re-run of a course"
msgstr "Información requerida para crear una reapertura del curso"
#. Translators: This is an example name for a new course, seen when filling
#. out
#. the form to create a new course.
#. Translators: This is an example name for a new course, seen when
#. filling out the form to create a new course.
#: cms/templates/course-create-rerun.html cms/templates/index.html
msgid "e.g. Introduction to Computer Science"
msgstr "ej.: Introducción a las Ciencias de la Computación"
@@ -19568,8 +19553,8 @@ msgid "Library Name"
msgstr "Nombre"
#. Translators: This is an example name for a new content library, seen when
#. filling out the form to create a new library. (A library is a collection of
#. content or problems.)
#. filling out the form to create a new library.
#. (A library is a collection of content or problems.)
#: cms/templates/index.html
msgid "e.g. Computer Science Problems"
msgstr "ej.: Problemas de Ciencias de la Computación"
@@ -19592,8 +19577,9 @@ msgstr "Código"
#. Translators: This is an example for the "code" used to identify a library,
#. seen when filling out the form to create a new library. This example is
#. short for "Computer Science Problems". The example number may contain
#. letters but must not contain spaces.
#. short
#. for "Computer Science Problems". The example number may contain letters
#. but must not contain spaces.
#: cms/templates/index.html
msgid "e.g. CSPROB"
msgstr "ej: PROBCC"
@@ -19622,10 +19608,11 @@ msgstr "Impartición del Curso:"
msgid "This course run is currently being created."
msgstr "Esta instancia del curso está actualmente siendo creada."
#. Translators: This is a status message, used to inform the user of what the
#. system is doing. This status means that the user has requested to re-run an
#. existing course, and the system is currently in the process of duplicating
#. and configuring the existing course so that it can be re-run.
#. Translators: This is a status message, used to inform the user of
#. what the system is doing. This status means that the user has
#. requested to re-run an existing course, and the system is currently
#. in the process of duplicating and configuring the existing course
#. so that it can be re-run.
#: cms/templates/index.html
msgid "Configuring as re-run"
msgstr "Está siendo configurado para su reutilización."
@@ -19640,6 +19627,18 @@ msgstr ""
" esta página o {link_start}recarguela{link_end} para actualizar la lista de "
"cursos. El nuevo curso necesitará alguna configuración manual."
#. Translators: This is a status message for the course re-runs feature.
#. When a course admin indicates that a course should be re-run, the system
#. needs to process the request and prepare the new course. The status of
#. the process will follow this text.
#: cms/templates/index.html
msgid "This re-run processing status:"
msgstr ""
#: cms/templates/index.html
msgid "Configuration Error"
msgstr ""
#: cms/templates/index.html
msgid ""
"A system error occurred while your course was being processed. Please go to "

View File

@@ -99,7 +99,7 @@ msgid ""
msgstr ""
"Project-Id-Version: edx-platform\n"
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
"POT-Creation-Date: 2015-09-11 12:15+0000\n"
"POT-Creation-Date: 2015-09-18 13:22+0000\n"
"PO-Revision-Date: 2015-09-11 12:17+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"

Binary file not shown.

View File

@@ -51,7 +51,7 @@
# Steven BERNARD <steven.bernard@u-paris2.fr>, 2013
# Thomas Sihapanya <sihapanya.thomas@gmail.com>, 2015
# Toreador <torrent_lover@hotmail.com>, 2014
# Xavier Antoviaque <xavier@antoviaque.org>, 2014
# Xavier Antoviaque <xavier@antoviaque.org>, 2014-2015
# PETIT Yannick <yannick.petit@gmail.com>, 2013
# yepelboin <yves.epelboin@impmc.upmc.fr>, 2014-2015
# #-#-#-#-# django-studio.po (edx-platform) #-#-#-#-#
@@ -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-09-11 12:16+0000\n"
"POT-Creation-Date: 2015-09-18 13:23+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"
@@ -3704,9 +3704,7 @@ msgid "Request user's username"
msgstr "Demander le nom de l'utilisateur"
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's username. You must also set Open in New "
"Page to True to get the user's information."
msgid "Select True to request the user's username."
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
@@ -3714,9 +3712,7 @@ msgid "Request user's email"
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's email address. You must also set Open in "
"New Page to True to get the user's information."
msgid "Select True to request the user's email address."
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
@@ -8142,10 +8138,6 @@ msgstr ""
msgid "The supplied topic id {topic_id} is not valid"
msgstr ""
#: lms/djangoapps/teams/views.py
msgid "Error connecting to elasticsearch"
msgstr ""
#. Translators: 'ordering' is a string describing a way
#. of ordering a list. For example, {ordering} may be
#. 'name', indicating that the user wants to sort the
@@ -12220,8 +12212,6 @@ msgstr "Tweetez que vous êtes inscrits pour ce cours"
msgid "Email someone to say you've registered for this course"
msgstr "Envoyez par e-mail que vous êtes inscrits à ce cours"
#. Translators: This text will be automatically posted to the student's
#. Twitter account. {url} should appear at the end of the text.
#: lms/templates/courseware/course_about.html
msgid "I just registered for {number} {title} through {account}: {url}"
msgstr "Je viens de m'inscrire pour {number} {title} via {account}: {url}"
@@ -12726,6 +12716,8 @@ msgstr ""
msgid "Download Your Certificate"
msgstr "Télécharger votre certificat"
#. Translators: This message appears to users when the system is processessing
#. course certificates, which can take a few hours.
#: lms/templates/courseware/progress.html
msgid "We're working on it..."
msgstr "Nous y travaillons"
@@ -17322,9 +17314,8 @@ msgstr ""
msgid "Required Information to Create a re-run of a course"
msgstr "Informations requises pour créer une nouvelle session d'un cours"
#. Translators: This is an example name for a new course, seen when filling
#. out
#. the form to create a new course.
#. Translators: This is an example name for a new course, seen when
#. filling out the form to create a new course.
#: cms/templates/course-create-rerun.html cms/templates/index.html
msgid "e.g. Introduction to Computer Science"
msgstr "par exemple, Introduction à l'Informatique"
@@ -18651,8 +18642,8 @@ msgid "Library Name"
msgstr "Nom de la Bibliothèque"
#. Translators: This is an example name for a new content library, seen when
#. filling out the form to create a new library. (A library is a collection of
#. content or problems.)
#. filling out the form to create a new library.
#. (A library is a collection of content or problems.)
#: cms/templates/index.html
msgid "e.g. Computer Science Problems"
msgstr "exemple: Exercices d'introduction à l'Informatique"
@@ -18675,8 +18666,9 @@ msgstr "Code de la bibliothèque"
#. Translators: This is an example for the "code" used to identify a library,
#. seen when filling out the form to create a new library. This example is
#. short for "Computer Science Problems". The example number may contain
#. letters but must not contain spaces.
#. short
#. for "Computer Science Problems". The example number may contain letters
#. but must not contain spaces.
#: cms/templates/index.html
msgid "e.g. CSPROB"
msgstr "MATHPROB par exemple"
@@ -18705,10 +18697,11 @@ msgstr "Cours dispensé:"
msgid "This course run is currently being created."
msgstr "Création de cette session de cours..."
#. Translators: This is a status message, used to inform the user of what the
#. system is doing. This status means that the user has requested to re-run an
#. existing course, and the system is currently in the process of duplicating
#. and configuring the existing course so that it can be re-run.
#. Translators: This is a status message, used to inform the user of
#. what the system is doing. This status means that the user has
#. requested to re-run an existing course, and the system is currently
#. in the process of duplicating and configuring the existing course
#. so that it can be re-run.
#: cms/templates/index.html
msgid "Configuring as re-run"
msgstr "Configuré comme relancé"
@@ -18724,6 +18717,18 @@ msgstr ""
"jour la liste de cours. Le nouveau cours aura besoin d'être configuré "
"manuellement."
#. Translators: This is a status message for the course re-runs feature.
#. When a course admin indicates that a course should be re-run, the system
#. needs to process the request and prepare the new course. The status of
#. the process will follow this text.
#: cms/templates/index.html
msgid "This re-run processing status:"
msgstr ""
#: cms/templates/index.html
msgid "Configuration Error"
msgstr ""
#: cms/templates/index.html
msgid ""
"A system error occurred while your course was being processed. Please go to "

View File

@@ -110,9 +110,9 @@ msgid ""
msgstr ""
"Project-Id-Version: edx-platform\n"
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
"POT-Creation-Date: 2015-09-11 12:15+0000\n"
"PO-Revision-Date: 2015-09-11 12:17+0000\n"
"Last-Translator: Sarina Canelake <sarina@edx.org>\n"
"POT-Creation-Date: 2015-09-18 13:22+0000\n"
"PO-Revision-Date: 2015-09-12 04:07+0000\n"
"Last-Translator: rafcha <raphael.chay@gmail.com>\n"
"Language-Team: French (http://www.transifex.com/open-edx/edx-platform/language/fr/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"

Binary file not shown.

View File

@@ -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-09-11 12:16+0000\n"
"POT-Creation-Date: 2015-09-18 13:23+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"
@@ -3294,9 +3294,7 @@ msgid "Request user's username"
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's username. You must also set Open in New "
"Page to True to get the user's information."
msgid "Select True to request the user's username."
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
@@ -3304,9 +3302,7 @@ msgid "Request user's email"
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's email address. You must also set Open in "
"New Page to True to get the user's information."
msgid "Select True to request the user's email address."
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
@@ -7428,10 +7424,6 @@ msgstr ""
msgid "The supplied topic id {topic_id} is not valid"
msgstr ""
#: lms/djangoapps/teams/views.py
msgid "Error connecting to elasticsearch"
msgstr ""
#. Translators: 'ordering' is a string describing a way
#. of ordering a list. For example, {ordering} may be
#. 'name', indicating that the user wants to sort the
@@ -11284,8 +11276,6 @@ msgstr ""
msgid "Email someone to say you've registered for this course"
msgstr ""
#. Translators: This text will be automatically posted to the student's
#. Twitter account. {url} should appear at the end of the text.
#: lms/templates/courseware/course_about.html
msgid "I just registered for {number} {title} through {account}: {url}"
msgstr ""
@@ -11752,6 +11742,8 @@ msgstr ""
msgid "Download Your Certificate"
msgstr ""
#. Translators: This message appears to users when the system is processessing
#. course certificates, which can take a few hours.
#: lms/templates/courseware/progress.html
msgid "We're working on it..."
msgstr ""
@@ -15955,9 +15947,8 @@ msgstr ""
msgid "Required Information to Create a re-run of a course"
msgstr ""
#. Translators: This is an example name for a new course, seen when filling
#. out
#. the form to create a new course.
#. Translators: This is an example name for a new course, seen when
#. filling out the form to create a new course.
#: cms/templates/course-create-rerun.html cms/templates/index.html
msgid "e.g. Introduction to Computer Science"
msgstr ""
@@ -17127,8 +17118,8 @@ msgid "Library Name"
msgstr ""
#. Translators: This is an example name for a new content library, seen when
#. filling out the form to create a new library. (A library is a collection of
#. content or problems.)
#. filling out the form to create a new library.
#. (A library is a collection of content or problems.)
#: cms/templates/index.html
msgid "e.g. Computer Science Problems"
msgstr ""
@@ -17151,8 +17142,9 @@ msgstr ""
#. Translators: This is an example for the "code" used to identify a library,
#. seen when filling out the form to create a new library. This example is
#. short for "Computer Science Problems". The example number may contain
#. letters but must not contain spaces.
#. short
#. for "Computer Science Problems". The example number may contain letters
#. but must not contain spaces.
#: cms/templates/index.html
msgid "e.g. CSPROB"
msgstr ""
@@ -17179,10 +17171,11 @@ msgstr ""
msgid "This course run is currently being created."
msgstr ""
#. Translators: This is a status message, used to inform the user of what the
#. system is doing. This status means that the user has requested to re-run an
#. existing course, and the system is currently in the process of duplicating
#. and configuring the existing course so that it can be re-run.
#. Translators: This is a status message, used to inform the user of
#. what the system is doing. This status means that the user has
#. requested to re-run an existing course, and the system is currently
#. in the process of duplicating and configuring the existing course
#. so that it can be re-run.
#: cms/templates/index.html
msgid "Configuring as re-run"
msgstr ""
@@ -17194,6 +17187,18 @@ msgid ""
" new course will need some manual configuration."
msgstr ""
#. Translators: This is a status message for the course re-runs feature.
#. When a course admin indicates that a course should be re-run, the system
#. needs to process the request and prepare the new course. The status of
#. the process will follow this text.
#: cms/templates/index.html
msgid "This re-run processing status:"
msgstr ""
#: cms/templates/index.html
msgid "Configuration Error"
msgstr ""
#: cms/templates/index.html
msgid ""
"A system error occurred while your course was being processed. Please go to "

View File

@@ -44,7 +44,7 @@ msgid ""
msgstr ""
"Project-Id-Version: edx-platform\n"
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
"POT-Creation-Date: 2015-09-11 12:15+0000\n"
"POT-Creation-Date: 2015-09-18 13:22+0000\n"
"PO-Revision-Date: 2015-09-11 12:17+0000\n"
"Last-Translator: Sarina Canelake <sarina@edx.org>\n"
"Language-Team: Hebrew (http://www.transifex.com/open-edx/edx-platform/language/he/)\n"

Binary file not shown.

View File

@@ -74,7 +74,7 @@ msgid ""
msgstr ""
"Project-Id-Version: edx-platform\n"
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
"POT-Creation-Date: 2015-09-11 12:16+0000\n"
"POT-Creation-Date: 2015-09-18 13:23+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"
@@ -3317,9 +3317,7 @@ msgid "Request user's username"
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's username. You must also set Open in New "
"Page to True to get the user's information."
msgid "Select True to request the user's username."
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
@@ -3327,9 +3325,7 @@ msgid "Request user's email"
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's email address. You must also set Open in "
"New Page to True to get the user's information."
msgid "Select True to request the user's email address."
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
@@ -7551,10 +7547,6 @@ msgstr ""
msgid "The supplied topic id {topic_id} is not valid"
msgstr ""
#: lms/djangoapps/teams/views.py
msgid "Error connecting to elasticsearch"
msgstr ""
#. Translators: 'ordering' is a string describing a way
#. of ordering a list. For example, {ordering} may be
#. 'name', indicating that the user wants to sort the
@@ -11517,8 +11509,6 @@ msgstr ""
msgid "Email someone to say you've registered for this course"
msgstr ""
#. Translators: This text will be automatically posted to the student's
#. Twitter account. {url} should appear at the end of the text.
#: lms/templates/courseware/course_about.html
msgid "I just registered for {number} {title} through {account}: {url}"
msgstr ""
@@ -11981,6 +11971,8 @@ msgstr ""
msgid "Download Your Certificate"
msgstr ""
#. Translators: This message appears to users when the system is processessing
#. course certificates, which can take a few hours.
#: lms/templates/courseware/progress.html
msgid "We're working on it..."
msgstr ""
@@ -16292,9 +16284,8 @@ msgstr ""
msgid "Required Information to Create a re-run of a course"
msgstr ""
#. Translators: This is an example name for a new course, seen when filling
#. out
#. the form to create a new course.
#. Translators: This is an example name for a new course, seen when
#. filling out the form to create a new course.
#: cms/templates/course-create-rerun.html cms/templates/index.html
msgid "e.g. Introduction to Computer Science"
msgstr ""
@@ -17464,8 +17455,8 @@ msgid "Library Name"
msgstr ""
#. Translators: This is an example name for a new content library, seen when
#. filling out the form to create a new library. (A library is a collection of
#. content or problems.)
#. filling out the form to create a new library.
#. (A library is a collection of content or problems.)
#: cms/templates/index.html
msgid "e.g. Computer Science Problems"
msgstr ""
@@ -17488,8 +17479,9 @@ msgstr ""
#. Translators: This is an example for the "code" used to identify a library,
#. seen when filling out the form to create a new library. This example is
#. short for "Computer Science Problems". The example number may contain
#. letters but must not contain spaces.
#. short
#. for "Computer Science Problems". The example number may contain letters
#. but must not contain spaces.
#: cms/templates/index.html
msgid "e.g. CSPROB"
msgstr ""
@@ -17516,10 +17508,11 @@ msgstr ""
msgid "This course run is currently being created."
msgstr ""
#. Translators: This is a status message, used to inform the user of what the
#. system is doing. This status means that the user has requested to re-run an
#. existing course, and the system is currently in the process of duplicating
#. and configuring the existing course so that it can be re-run.
#. Translators: This is a status message, used to inform the user of
#. what the system is doing. This status means that the user has
#. requested to re-run an existing course, and the system is currently
#. in the process of duplicating and configuring the existing course
#. so that it can be re-run.
#: cms/templates/index.html
msgid "Configuring as re-run"
msgstr ""
@@ -17531,6 +17524,18 @@ msgid ""
" new course will need some manual configuration."
msgstr ""
#. Translators: This is a status message for the course re-runs feature.
#. When a course admin indicates that a course should be re-run, the system
#. needs to process the request and prepare the new course. The status of
#. the process will follow this text.
#: cms/templates/index.html
msgid "This re-run processing status:"
msgstr ""
#: cms/templates/index.html
msgid "Configuration Error"
msgstr ""
#: cms/templates/index.html
msgid ""
"A system error occurred while your course was being processed. Please go to "

View File

@@ -47,7 +47,7 @@ msgid ""
msgstr ""
"Project-Id-Version: edx-platform\n"
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
"POT-Creation-Date: 2015-09-11 12:15+0000\n"
"POT-Creation-Date: 2015-09-18 13:22+0000\n"
"PO-Revision-Date: 2015-09-11 12:17+0000\n"
"Last-Translator: Sarina Canelake <sarina@edx.org>\n"
"Language-Team: Hindi (http://www.transifex.com/open-edx/edx-platform/language/hi/)\n"

View File

@@ -87,8 +87,8 @@ msgid ""
msgstr ""
"Project-Id-Version: edx-platform\n"
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
"POT-Creation-Date: 2015-09-11 12:16+0000\n"
"PO-Revision-Date: 2015-09-11 07:58+0000\n"
"POT-Creation-Date: 2015-09-18 13:23+0000\n"
"PO-Revision-Date: 2015-09-18 03:12+0000\n"
"Last-Translator: Hongseob Lee <shevious@gmail.com>\n"
"Language-Team: Korean (Korea) (http://www.transifex.com/open-edx/edx-platform/language/ko_KR/)\n"
"MIME-Version: 1.0\n"
@@ -3412,20 +3412,16 @@ msgid "Request user's username"
msgstr "아이디를 요청합니다."
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's username. You must also set Open in New "
"Page to True to get the user's information."
msgstr "아이디를 요청하려면 True를 입력하십시오. 아이디를 얻기 위해서는 '신규 페이지에서 열기'가 먼저 설정되어 있어야 합니다."
msgid "Select True to request the user's username."
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
msgid "Request user's email"
msgstr "이용자 이메일을 요청합니다."
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's email address. You must also set Open in "
"New Page to True to get the user's information."
msgstr "이용자 이메일 주소를 요청하려면 True를 입력합니다. 이를 위해 신규 페이지에서 열기가 먼저 설정되어 있어야 합니다."
msgid "Select True to request the user's email address."
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
msgid "LTI Application Information"
@@ -7808,10 +7804,6 @@ msgstr ""
msgid "The supplied topic id {topic_id} is not valid"
msgstr "제공된 주제 ID {topic_id}가 유효하지 않습니다."
#: lms/djangoapps/teams/views.py
msgid "Error connecting to elasticsearch"
msgstr ""
#. Translators: 'ordering' is a string describing a way
#. of ordering a list. For example, {ordering} may be
#. 'name', indicating that the user wants to sort the
@@ -8292,7 +8284,7 @@ msgstr "마지막 수정:"
#: lms/templates/wiki/article.html
msgid "See all children"
msgstr "모든 하위내용 보기"
msgstr "모든 하위 문서 보기"
#: lms/templates/wiki/article.html
msgid "This article was last modified:"
@@ -8869,7 +8861,7 @@ msgstr ""
#. below a field meant to hold the user's full name.
#: openedx/core/djangoapps/user_api/views.py lms/templates/register.html
msgid "Needed for any certificates you may earn"
msgstr "앞으로 받게 될 이수증에 필요합니다."
msgstr "앞으로 받게 될 이수증에 필요합니다. 영문이름 병기를 원하시면 영문이름을 추가하세요."
#. Translators: This label appears above a field on the registration form
#. meant to hold the user's public username.
@@ -8881,13 +8873,13 @@ msgstr "아이디"
msgid ""
"The name that will identify you in your courses - {bold_start}(cannot be "
"changed later){bold_end}"
msgstr "강좌에서 표시되길 원하는 이름 - {bold_start}(변경 불가){bold_end}"
msgstr "영문/숫자로 이루어진 아이디 - {bold_start}(변경 불가){bold_end}"
#. Translators: This example username is used as a placeholder in
#. a field on the registration form meant to hold the user's username.
#: openedx/core/djangoapps/user_api/views.py
msgid "JaneDoe"
msgstr "홍길동"
msgstr "HongGilDong"
#. Translators: This label appears above a dropdown menu on the registration
#. form used to select the user's highest completed level of education.
@@ -10742,7 +10734,7 @@ msgstr "학습자 상태 삭제"
#: lms/templates/staff_problem_info.html
#: lms/templates/instructor/instructor_dashboard_2/student_admin.html
msgid "Rescore Student Submission"
msgstr "제출 재채점"
msgstr "답안 재채점"
#: lms/templates/staff_problem_info.html
msgid "Module Fields"
@@ -11738,8 +11730,6 @@ msgstr "본 강좌에 등록한 것을 트위터에 트윗하세요."
msgid "Email someone to say you've registered for this course"
msgstr "이 강좌에 등록했음을 누군가에게 이메일하세요"
#. Translators: This text will be automatically posted to the student's
#. Twitter account. {url} should appear at the end of the text.
#: lms/templates/courseware/course_about.html
msgid "I just registered for {number} {title} through {account}: {url}"
msgstr "{number} {title} through {account}: {url} 로 방금 등록 완료 "
@@ -12048,7 +12038,7 @@ msgstr "학습자별 세부 성적 검토 및 조정"
#: lms/templates/courseware/legacy_instructor_dashboard.html
msgid "Select a problem and an action:"
msgstr "문제와 동작을 선택하세요:"
msgstr "문제와 액션을 선택하세요."
#: lms/templates/courseware/legacy_instructor_dashboard.html
msgid ""
@@ -12071,8 +12061,7 @@ msgid ""
"To download a CSV file containing profile information for students who are "
"enrolled in this course, visit the Data Download section of the Instructor "
"Dashboard."
msgstr ""
"강좌에 등록되어 있는 학습자 프로필 정보가 담긴 CSV 파일을 다운로드하기 위해, 교수자 대시보드의 자료 다운로드를 방문하세요. "
msgstr "강좌에 등록되어 있는 학습자 정보가 담긴 CSV 파일을 다운로드 하기 위해, 교수자 대시보드에서 데이터를 클릭하세요. "
#: lms/templates/courseware/legacy_instructor_dashboard.html
msgid ""
@@ -12214,6 +12203,8 @@ msgstr "PDF는 새로운 브라우져 창 혹은 탭에 열릴 것입니다."
msgid "Download Your Certificate"
msgstr "강좌 이수증 다운로드하기"
#. Translators: This message appears to users when the system is processessing
#. course certificates, which can take a few hours.
#: lms/templates/courseware/progress.html
msgid "We're working on it..."
msgstr "작업중입니다."
@@ -13419,7 +13410,7 @@ msgstr "[[성함]]에게:"
msgid ""
"We have provided a course enrollment code for you in {course_name}. To "
"enroll in the course, click the following link:"
msgstr "{course_name}에서 수강신청 코드를 제공했습니다. 강좌에 등록하기 위해 다음 링크를 클릭하세요:"
msgstr "{course_name}에서 수강신청 코드를 제공했습니다. 강좌에 등록하려면 다음 링크를 클릭하세요."
#: lms/templates/emails/registration_codes_sale_email.txt
msgid "HTML link from the attached CSV file"
@@ -13881,7 +13872,7 @@ msgstr ""
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
msgid "Grading Configuration"
msgstr "성적 설정"
msgstr "성적 가중치"
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
msgid "Click to download a CSV of anonymized student IDs:"
@@ -13917,7 +13908,7 @@ msgstr "버튼을 여러번 클릭하지 마세요. 그럴 경우, 생성 과정
msgid ""
"Click to generate a CSV file of all students enrolled in this course, along "
"with profile information such as email address and username:"
msgstr "이 강좌에 등록된 모든 학습자 CSV 파일과 이메일, 아이디 등의 프로필 정보를 생성하려면 클릭하세요."
msgstr "이 강좌에 등록된 모든 학습자 CSV 파일과 이메일, 아이디 등의 학습자 정보 보고서를 생성하려면 클릭하세요."
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
msgid "Download profile information as a CSV"
@@ -13931,7 +13922,7 @@ msgstr "강좌에 등록할 수 있으나 아직 처리가 완료되지 않은
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
msgid "Download a CSV of learners who can enroll"
msgstr "등록할 수 있는 학습자의 CSV 다운로드 합니다."
msgstr "등록할 수 있는 학습자의 CSV 다운로드"
#: lms/templates/instructor/instructor_dashboard_2/data_download.html
msgid ""
@@ -15015,7 +15006,7 @@ msgstr "학습자별 성적 사정"
#: lms/templates/instructor/instructor_dashboard_2/student_admin.html
msgid "Click this link to view the student's progress page:"
msgstr "학습자의 진도 페이지를 보기 위해서 이 링크를 클릭하세요:"
msgstr "학습자의 진도 페이지를 보려면 이 링크를 클릭하세요."
#: lms/templates/instructor/instructor_dashboard_2/student_admin.html
msgid "Student Progress Page"
@@ -15027,7 +15018,7 @@ msgstr "학습자별 성적 조정"
#: lms/templates/instructor/instructor_dashboard_2/student_admin.html
msgid "Specify a problem in the course here with its complete location:"
msgstr "강좌에서 발생한 문제를 정확한 위치와 함께 기술하세요:"
msgstr "강좌에서 발생한 문제를 정확한 위치와 함께 기술하세요."
#: lms/templates/instructor/instructor_dashboard_2/student_admin.html
msgid "Problem location"
@@ -15038,11 +15029,11 @@ msgstr "문제 위치 "
msgid ""
"You must provide the complete location of the problem. In the Staff Debug "
"viewer, the location looks like this:"
msgstr "문제가 발생하는 자세한 위치를 알려주어야 합니다. Staff Debug Viewer에서 위치는 다음과 같습니다: "
msgstr "문제가 발생하는 자세한 위치를 알려주어야 합니다. Staff Debug Viewer에서 위치는 다음과 같습니다."
#: lms/templates/instructor/instructor_dashboard_2/student_admin.html
msgid "Next, select an action to perform for the given user and problem:"
msgstr "다음 작업은 지정된 사용자와 문제에 대한 수행을 선택합니다 :"
msgstr "다음 작업은 지정된 사용자와 문제에 대한 수행을 선택합니다."
#: lms/templates/instructor/instructor_dashboard_2/student_admin.html
msgid ""
@@ -15064,7 +15055,7 @@ msgstr ""
#: lms/templates/instructor/instructor_dashboard_2/student_admin.html
msgid "Show Background Task History for Student"
msgstr "학습자에 대한 배경 작업 이력 보기"
msgstr "학습자 배경 작업 이력 보기"
#: lms/templates/instructor/instructor_dashboard_2/student_admin.html
msgid "Entrance Exam Adjustment"
@@ -15112,11 +15103,11 @@ msgstr "액션을 선택하세요"
#: lms/templates/instructor/instructor_dashboard_2/student_admin.html
msgid "Reset ALL students' attempts"
msgstr "모든 학습자의 시도 초기화"
msgstr "전체 학습자의 문제 풀이 횟수 초기화"
#: lms/templates/instructor/instructor_dashboard_2/student_admin.html
msgid "Rescore ALL students' problem submissions"
msgstr "모든 학습자의 문제 제출 재채점"
msgstr "전체 학습자의 답안 재채점"
#: lms/templates/instructor/instructor_dashboard_2/student_admin.html
msgid ""
@@ -15125,7 +15116,7 @@ msgid ""
"submitted for this problem, click on this button"
msgstr ""
"이 작업은 백그라운드에서 이루어지며, 작업 상태가 공지 사항 탭의 표에 나타날 것입니다. 전체 작업의 상태를 보려면, 이 버튼을 "
"누르세요."
"클릭하세요."
#: lms/templates/instructor/instructor_dashboard_2/student_admin.html
msgid "Show Background Task History for Problem"
@@ -16576,9 +16567,8 @@ msgstr "기관과 강좌 번호, 기관별 강좌 번호는 고유해야 합니
msgid "Required Information to Create a re-run of a course"
msgstr "강좌 재운영을 만드는데 필요한 정보"
#. Translators: This is an example name for a new course, seen when filling
#. out
#. the form to create a new course.
#. Translators: This is an example name for a new course, seen when
#. filling out the form to create a new course.
#: cms/templates/course-create-rerun.html cms/templates/index.html
msgid "e.g. Introduction to Computer Science"
msgstr "예: 컴퓨터 공학 개론"
@@ -17828,8 +17818,8 @@ msgid "Library Name"
msgstr "콘텐츠 보관함명"
#. Translators: This is an example name for a new content library, seen when
#. filling out the form to create a new library. (A library is a collection of
#. content or problems.)
#. filling out the form to create a new library.
#. (A library is a collection of content or problems.)
#: cms/templates/index.html
msgid "e.g. Computer Science Problems"
msgstr "ex 컴퓨터 개론 문제"
@@ -17852,8 +17842,9 @@ msgstr "콘텐츠 보관함 코드"
#. Translators: This is an example for the "code" used to identify a library,
#. seen when filling out the form to create a new library. This example is
#. short for "Computer Science Problems". The example number may contain
#. letters but must not contain spaces.
#. short
#. for "Computer Science Problems". The example number may contain letters
#. but must not contain spaces.
#: cms/templates/index.html
msgid "e.g. CSPROB"
msgstr "예: CSPROB"
@@ -17880,10 +17871,11 @@ msgstr "기관별 강좌 번호"
msgid "This course run is currently being created."
msgstr "기관별 강좌 번호가 만들어지고 있습니다."
#. Translators: This is a status message, used to inform the user of what the
#. system is doing. This status means that the user has requested to re-run an
#. existing course, and the system is currently in the process of duplicating
#. and configuring the existing course so that it can be re-run.
#. Translators: This is a status message, used to inform the user of
#. what the system is doing. This status means that the user has
#. requested to re-run an existing course, and the system is currently
#. in the process of duplicating and configuring the existing course
#. so that it can be re-run.
#: cms/templates/index.html
msgid "Configuring as re-run"
msgstr "다시 시작하기 위한 설정"
@@ -17897,6 +17889,18 @@ msgstr ""
"5-10분 후, 새 강좌가 귀하의 강좌 목록에 추가될 것입니다. 강좌 목록을 업데이트하기 위해, 페이지로 돌아가거나 "
"{link_start} 새로고침{link_end} 하세요. 새 강좌엔 약간의 수동 설정이 필요할 수 있습니다."
#. Translators: This is a status message for the course re-runs feature.
#. When a course admin indicates that a course should be re-run, the system
#. needs to process the request and prepare the new course. The status of
#. the process will follow this text.
#: cms/templates/index.html
msgid "This re-run processing status:"
msgstr ""
#: cms/templates/index.html
msgid "Configuration Error"
msgstr ""
#: cms/templates/index.html
msgid ""
"A system error occurred while your course was being processed. Please go to "
@@ -19366,7 +19370,7 @@ msgstr "글 주소 \"%s\" 가 이미 존재합니다."
#: wiki/forms.py
msgid "Yes, I am sure"
msgstr "예. 확인했습니다."
msgstr "네, 삭제합니다."
#: wiki/forms.py
msgid "Purge"

View File

@@ -53,7 +53,7 @@ msgid ""
msgstr ""
"Project-Id-Version: edx-platform\n"
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
"POT-Creation-Date: 2015-09-11 12:15+0000\n"
"POT-Creation-Date: 2015-09-18 13:22+0000\n"
"PO-Revision-Date: 2015-09-11 12:17+0000\n"
"Last-Translator: Sarina Canelake <sarina@edx.org>\n"
"Language-Team: Korean (Korea) (http://www.transifex.com/open-edx/edx-platform/language/ko_KR/)\n"
@@ -2602,7 +2602,7 @@ msgstr ""
#: lms/static/coffee/src/instructor_dashboard/data_download.js
msgid "Error generating student profile information. Please try again."
msgstr "학습자 프로필 정보를 만드는 중 오류가 발생했습니다. 다시 시도하세요."
msgstr "학습자 정보를 만드는 중 오류가 발생했습니다. 다시 시도하세요."
#: lms/static/coffee/src/instructor_dashboard/data_download.js
#: lms/templates/search/search_loading.underscore

View File

@@ -225,7 +225,7 @@ msgid ""
msgstr ""
"Project-Id-Version: edx-platform\n"
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
"POT-Creation-Date: 2015-09-11 12:16+0000\n"
"POT-Creation-Date: 2015-09-18 13:23+0000\n"
"PO-Revision-Date: 2015-07-20 00:15+0000\n"
"Last-Translator: javiercencig <javier@jecnet.com.br>\n"
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/open-edx/edx-platform/language/pt_BR/)\n"
@@ -3613,9 +3613,7 @@ msgid "Request user's username"
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's username. You must also set Open in New "
"Page to True to get the user's information."
msgid "Select True to request the user's username."
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
@@ -3623,9 +3621,7 @@ msgid "Request user's email"
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
msgid ""
"Select True to request the user's email address. You must also set Open in "
"New Page to True to get the user's information."
msgid "Select True to request the user's email address."
msgstr ""
#: common/lib/xmodule/xmodule/lti_module.py
@@ -7946,10 +7942,6 @@ msgstr ""
msgid "The supplied topic id {topic_id} is not valid"
msgstr ""
#: lms/djangoapps/teams/views.py
msgid "Error connecting to elasticsearch"
msgstr ""
#. Translators: 'ordering' is a string describing a way
#. of ordering a list. For example, {ordering} may be
#. 'name', indicating that the user wants to sort the
@@ -11960,8 +11952,6 @@ msgid "Email someone to say you've registered for this course"
msgstr ""
"Envie um e-mail para alguém dizendo que você se inscreveu neste curso."
#. Translators: This text will be automatically posted to the student's
#. Twitter account. {url} should appear at the end of the text.
#: lms/templates/courseware/course_about.html
msgid "I just registered for {number} {title} through {account}: {url}"
msgstr ""
@@ -12446,6 +12436,8 @@ msgstr ""
msgid "Download Your Certificate"
msgstr ""
#. Translators: This message appears to users when the system is processessing
#. course certificates, which can take a few hours.
#: lms/templates/courseware/progress.html
msgid "We're working on it..."
msgstr ""
@@ -16887,9 +16879,8 @@ msgstr ""
msgid "Required Information to Create a re-run of a course"
msgstr ""
#. Translators: This is an example name for a new course, seen when filling
#. out
#. the form to create a new course.
#. Translators: This is an example name for a new course, seen when
#. filling out the form to create a new course.
#: cms/templates/course-create-rerun.html cms/templates/index.html
msgid "e.g. Introduction to Computer Science"
msgstr ""
@@ -18074,8 +18065,8 @@ msgid "Library Name"
msgstr ""
#. Translators: This is an example name for a new content library, seen when
#. filling out the form to create a new library. (A library is a collection of
#. content or problems.)
#. filling out the form to create a new library.
#. (A library is a collection of content or problems.)
#: cms/templates/index.html
msgid "e.g. Computer Science Problems"
msgstr ""
@@ -18098,8 +18089,9 @@ msgstr ""
#. Translators: This is an example for the "code" used to identify a library,
#. seen when filling out the form to create a new library. This example is
#. short for "Computer Science Problems". The example number may contain
#. letters but must not contain spaces.
#. short
#. for "Computer Science Problems". The example number may contain letters
#. but must not contain spaces.
#: cms/templates/index.html
msgid "e.g. CSPROB"
msgstr ""
@@ -18126,10 +18118,11 @@ msgstr ""
msgid "This course run is currently being created."
msgstr ""
#. Translators: This is a status message, used to inform the user of what the
#. system is doing. This status means that the user has requested to re-run an
#. existing course, and the system is currently in the process of duplicating
#. and configuring the existing course so that it can be re-run.
#. Translators: This is a status message, used to inform the user of
#. what the system is doing. This status means that the user has
#. requested to re-run an existing course, and the system is currently
#. in the process of duplicating and configuring the existing course
#. so that it can be re-run.
#: cms/templates/index.html
msgid "Configuring as re-run"
msgstr ""
@@ -18141,6 +18134,18 @@ msgid ""
" new course will need some manual configuration."
msgstr ""
#. Translators: This is a status message for the course re-runs feature.
#. When a course admin indicates that a course should be re-run, the system
#. needs to process the request and prepare the new course. The status of
#. the process will follow this text.
#: cms/templates/index.html
msgid "This re-run processing status:"
msgstr ""
#: cms/templates/index.html
msgid "Configuration Error"
msgstr ""
#: cms/templates/index.html
msgid ""
"A system error occurred while your course was being processed. Please go to "

View File

@@ -102,6 +102,7 @@
#
# Translators:
# Alan Mól <alan3df@gmail.com>, 2015
# Ana Paula D'Almeida Oliveira <paulladalmeida@gmail.com>, 2015
# Andrea Z. Bitencourt <azbitencourt@gmail.com>, 2015
# Bruno Sette <brunosette@gmail.com>, 2015
# Cleomir Waiczyk <w.cleomir@gmail.com>, 2015
@@ -141,6 +142,7 @@
# Luiz Cardineli <luizcardineli@gmail.com>, 2015
# Magaly Munik da Rocha <maggie.brazil@gmail.com>, 2014
# Marco Túlio Pires <mtrpires@outlook.com>, 2014
# Mariana Jó de Souza <mariana.jsouza@gmail.com>, 2015
# mmauryx <matheus_w_dias@hotmail.com>, 2014
# Maurício Gonçalves Melara Camargo <mauriciogmc@gmail.com>, 2015
# Mike Job Silva <mikejobrn@gmail.com>, 2015
@@ -152,9 +154,9 @@ msgid ""
msgstr ""
"Project-Id-Version: edx-platform\n"
"Report-Msgid-Bugs-To: openedx-translation@googlegroups.com\n"
"POT-Creation-Date: 2015-09-11 12:15+0000\n"
"PO-Revision-Date: 2015-09-11 12:17+0000\n"
"Last-Translator: Sarina Canelake <sarina@edx.org>\n"
"POT-Creation-Date: 2015-09-18 13:22+0000\n"
"PO-Revision-Date: 2015-09-13 01:15+0000\n"
"Last-Translator: Mariana Jó de Souza <mariana.jsouza@gmail.com>\n"
"Language-Team: Portuguese (Brazil) (http://www.transifex.com/open-edx/edx-platform/language/pt_BR/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"

Some files were not shown because too many files have changed in this diff Show More