Merge pull request #14329 from edx/release-candidate
Merge release-candidate to release
This commit is contained in:
@@ -39,7 +39,7 @@ class AnnotatableFields(object):
|
||||
)
|
||||
display_name = String(
|
||||
display_name=_("Display Name"),
|
||||
help=_("Display name for this module"),
|
||||
help=_("The display name for this component."),
|
||||
scope=Scope.settings,
|
||||
default=_('Annotation'),
|
||||
)
|
||||
|
||||
@@ -92,7 +92,7 @@ class CapaFields(object):
|
||||
"""
|
||||
display_name = String(
|
||||
display_name=_("Display Name"),
|
||||
help=_("This name appears in the horizontal navigation at the top of the page."),
|
||||
help=_("The display name for this component."),
|
||||
scope=Scope.settings,
|
||||
# it'd be nice to have a useful default but it screws up other things; so,
|
||||
# use display_name_with_default for those
|
||||
|
||||
@@ -27,7 +27,7 @@ class ConditionalFields(object):
|
||||
has_children = True
|
||||
display_name = String(
|
||||
display_name=_("Display Name"),
|
||||
help=_("This name appears in the horizontal navigation at the top of the page."),
|
||||
help=_("The display name for this component."),
|
||||
scope=Scope.settings,
|
||||
default=_('Conditional')
|
||||
)
|
||||
|
||||
@@ -38,7 +38,7 @@ class HtmlBlock(object):
|
||||
"""
|
||||
display_name = String(
|
||||
display_name=_("Display Name"),
|
||||
help=_("This name appears in the horizontal navigation at the top of the page."),
|
||||
help=_("The display name for this component."),
|
||||
scope=Scope.settings,
|
||||
# it'd be nice to have a useful default but it screws up other things; so,
|
||||
# use display_name_with_default for those
|
||||
@@ -329,7 +329,7 @@ class HtmlDescriptor(HtmlBlock, XmlDescriptor, EditingDescriptor): # pylint: di
|
||||
|
||||
class AboutFields(object):
|
||||
display_name = String(
|
||||
help=_("Display name for this module"),
|
||||
help=_("The display name for this component."),
|
||||
scope=Scope.settings,
|
||||
default="overview",
|
||||
)
|
||||
@@ -364,7 +364,7 @@ class StaticTabFields(object):
|
||||
"""
|
||||
display_name = String(
|
||||
display_name=_("Display Name"),
|
||||
help=_("This name appears in the horizontal navigation at the top of the page."),
|
||||
help=_("The display name for this component."),
|
||||
scope=Scope.settings,
|
||||
default="Empty",
|
||||
)
|
||||
|
||||
@@ -45,7 +45,7 @@ class AnnotatableFields(object):
|
||||
"""))
|
||||
display_name = String(
|
||||
display_name=_("Display Name"),
|
||||
help=_("Display name for this module"),
|
||||
help=_("The display name for this component."),
|
||||
scope=Scope.settings,
|
||||
default=_('Image Annotation'),
|
||||
)
|
||||
|
||||
@@ -60,7 +60,7 @@ class LibraryContentFields(object):
|
||||
# to locate input elements - keep synchronized
|
||||
display_name = String(
|
||||
display_name=_("Display Name"),
|
||||
help=_("Display name for this module"),
|
||||
help=_("The display name for this component."),
|
||||
default="Randomized Content Block",
|
||||
scope=Scope.settings,
|
||||
)
|
||||
|
||||
@@ -25,7 +25,7 @@ class LibraryRoot(XBlock):
|
||||
resources_dir = None
|
||||
|
||||
display_name = String(
|
||||
help=_("Enter the name of the library as it should appear in Studio."),
|
||||
help=_("The display name for this component."),
|
||||
default="Library",
|
||||
display_name=_("Library Display Name"),
|
||||
scope=Scope.settings
|
||||
|
||||
@@ -109,7 +109,7 @@ class LTIFields(object):
|
||||
display_name = String(
|
||||
display_name=_("Display Name"),
|
||||
help=_(
|
||||
"Enter the name that students see for this component. "
|
||||
"The display name for this component. "
|
||||
"Analytics reports may also use the display name to identify this component."
|
||||
),
|
||||
scope=Scope.settings,
|
||||
|
||||
@@ -23,20 +23,43 @@ from xmodule.xml_module import XmlDescriptor
|
||||
from xblock.fields import Scope, String, Dict, Boolean, List
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
_ = lambda text: text
|
||||
|
||||
|
||||
class PollFields(object):
|
||||
# Name of poll to use in links to this poll
|
||||
display_name = String(help="Display name for this module", scope=Scope.settings)
|
||||
display_name = String(
|
||||
help=_("The display name for this component."),
|
||||
scope=Scope.settings
|
||||
)
|
||||
|
||||
voted = Boolean(help="Whether this student has voted on the poll", scope=Scope.user_state, default=False)
|
||||
poll_answer = String(help="Student answer", scope=Scope.user_state, default='')
|
||||
poll_answers = Dict(help="Poll answers from all students", scope=Scope.user_state_summary)
|
||||
voted = Boolean(
|
||||
help=_("Whether this student has voted on the poll"),
|
||||
scope=Scope.user_state,
|
||||
default=False
|
||||
)
|
||||
poll_answer = String(
|
||||
help=_("Student answer"),
|
||||
scope=Scope.user_state,
|
||||
default=''
|
||||
)
|
||||
poll_answers = Dict(
|
||||
help=_("Poll answers from all students"),
|
||||
scope=Scope.user_state_summary
|
||||
)
|
||||
|
||||
# List of answers, in the form {'id': 'some id', 'text': 'the answer text'}
|
||||
answers = List(help="Poll answers from xml", scope=Scope.content, default=[])
|
||||
answers = List(
|
||||
help=_("Poll answers from xml"),
|
||||
scope=Scope.content,
|
||||
default=[]
|
||||
)
|
||||
|
||||
question = String(help="Poll question", scope=Scope.content, default='')
|
||||
question = String(
|
||||
help=_("Poll question"),
|
||||
scope=Scope.content,
|
||||
default=''
|
||||
)
|
||||
|
||||
|
||||
class PollModule(PollFields, XModule):
|
||||
|
||||
@@ -58,7 +58,7 @@ class SplitTestFields(object):
|
||||
|
||||
display_name = String(
|
||||
display_name=_("Display Name"),
|
||||
help=_("This name is used for organizing your course content, but is not shown to students."),
|
||||
help=_("The display name for this component. (Not shown to learners)"),
|
||||
scope=Scope.settings,
|
||||
default=_("Content Experiment")
|
||||
)
|
||||
|
||||
@@ -37,8 +37,12 @@ class TestFields(object):
|
||||
# Will not be returned by editable_metadata_fields because is not Scope.settings.
|
||||
student_answers = Dict(scope=Scope.user_state)
|
||||
# Will be returned, and can override the inherited value from XModule.
|
||||
display_name = String(scope=Scope.settings, default='local default', display_name='Local Display Name',
|
||||
help='local help')
|
||||
display_name = String(
|
||||
scope=Scope.settings,
|
||||
default='local default',
|
||||
display_name='Local Display Name',
|
||||
help='local help'
|
||||
)
|
||||
# Used for testing select type, effect of to_json method
|
||||
string_select = CrazyJsonString(
|
||||
scope=Scope.settings,
|
||||
|
||||
@@ -34,7 +34,7 @@ class AnnotatableFields(object):
|
||||
"""))
|
||||
display_name = String(
|
||||
display_name=_("Display Name"),
|
||||
help=_("Display name for this module"),
|
||||
help=_("The display name for this component."),
|
||||
scope=Scope.settings,
|
||||
default=_('Text Annotation'),
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@ _ = lambda text: text
|
||||
class VideoFields(object):
|
||||
"""Fields for `VideoModule` and `VideoDescriptor`."""
|
||||
display_name = String(
|
||||
help=_("The name students see. This name appears in the course ribbon and as a header for the video."),
|
||||
help=_("The display name for this component."),
|
||||
display_name=_("Component Display Name"),
|
||||
default="Video",
|
||||
scope=Scope.settings
|
||||
|
||||
@@ -34,7 +34,7 @@ class AnnotatableFields(object):
|
||||
"""))
|
||||
display_name = String(
|
||||
display_name=_("Display Name"),
|
||||
help=_("Display name for this module"),
|
||||
help=_("The display name for this component."),
|
||||
scope=Scope.settings,
|
||||
default=_('Video Annotation'),
|
||||
)
|
||||
|
||||
@@ -38,7 +38,7 @@ class WordCloudFields(object):
|
||||
"""XFields for word cloud."""
|
||||
display_name = String(
|
||||
display_name=_("Display Name"),
|
||||
help=_("The label for this word cloud on the course page."),
|
||||
help=_("The display name for this component."),
|
||||
scope=Scope.settings,
|
||||
default="Word cloud"
|
||||
)
|
||||
|
||||
@@ -66,6 +66,11 @@ STUDIO_VIEW = 'studio_view'
|
||||
PREVIEW_VIEWS = [STUDENT_VIEW, AUTHOR_VIEW]
|
||||
|
||||
|
||||
# Make '_' a no-op so we can scrape strings. Using lambda instead of
|
||||
# `django.utils.translation.ugettext_noop` because Django cannot be imported in this file
|
||||
_ = lambda text: text
|
||||
|
||||
|
||||
class OpaqueKeyReader(IdReader):
|
||||
"""
|
||||
IdReader for :class:`DefinitionKey` and :class:`UsageKey`s.
|
||||
@@ -256,8 +261,8 @@ class XModuleFields(object):
|
||||
Common fields for XModules.
|
||||
"""
|
||||
display_name = String(
|
||||
display_name="Display Name",
|
||||
help="This name appears in the horizontal navigation at the top of the page.",
|
||||
display_name=_("Display Name"),
|
||||
help=_("The display name for this component."),
|
||||
scope=Scope.settings,
|
||||
# it'd be nice to have a useful default but it screws up other things; so,
|
||||
# use display_name_with_default for those
|
||||
|
||||
22
lms/djangoapps/grades/migrations/0009_auto_20170111_1507.py
Normal file
22
lms/djangoapps/grades/migrations/0009_auto_20170111_1507.py
Normal file
@@ -0,0 +1,22 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('grades', '0008_persistentsubsectiongrade_first_attempted'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterIndexTogether(
|
||||
name='persistentcoursegrade',
|
||||
index_together=set([('passed_timestamp', 'course_id'), ('modified', 'course_id')]),
|
||||
),
|
||||
migrations.AlterIndexTogether(
|
||||
name='persistentsubsectiongrade',
|
||||
index_together=set([('modified', 'course_id', 'usage_key')]),
|
||||
),
|
||||
]
|
||||
18
lms/djangoapps/grades/migrations/0010_auto_20170112_1156.py
Normal file
18
lms/djangoapps/grades/migrations/0010_auto_20170112_1156.py
Normal file
@@ -0,0 +1,18 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
('grades', '0009_auto_20170111_1507'),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AlterIndexTogether(
|
||||
name='persistentsubsectiongrade',
|
||||
index_together=set([('modified', 'course_id', 'usage_key'), ('first_attempted', 'course_id', 'user_id')]),
|
||||
),
|
||||
]
|
||||
@@ -253,6 +253,17 @@ class PersistentSubsectionGrade(DeleteGradesMixin, TimeStampedModel):
|
||||
# * Course staff can see all grades for a course using (course_id,)
|
||||
('course_id', 'user_id', 'usage_key'),
|
||||
]
|
||||
# Allows querying in the following ways:
|
||||
# (modified): find all the grades updated within a certain timespan
|
||||
# (modified, course_id): find all the grades updated within a timespan for a certain course
|
||||
# (modified, course_id, usage_key): find all the grades updated within a timespan for a subsection
|
||||
# in a course
|
||||
# (first_attempted, course_id, user_id): find all attempted subsections in a course for a user
|
||||
# (first_attempted, course_id): find all attempted subsections in a course for all users
|
||||
index_together = [
|
||||
('modified', 'course_id', 'usage_key'),
|
||||
('first_attempted', 'course_id', 'user_id')
|
||||
]
|
||||
|
||||
# primary key will need to be large for this table
|
||||
id = UnsignedBigIntAutoField(primary_key=True) # pylint: disable=invalid-name
|
||||
@@ -502,11 +513,14 @@ class PersistentCourseGrade(DeleteGradesMixin, TimeStampedModel):
|
||||
# (course_id) for instructors to see all course grades, implicitly created via the unique_together constraint
|
||||
# (user_id) for course dashboard; explicitly declared as an index below
|
||||
# (passed_timestamp, course_id) for tracking when users first earned a passing grade.
|
||||
# (modified): find all the grades updated within a certain timespan
|
||||
# (modified, course_id): find all the grades updated within a certain timespan for a course
|
||||
unique_together = [
|
||||
('course_id', 'user_id'),
|
||||
]
|
||||
index_together = [
|
||||
('passed_timestamp', 'course_id'),
|
||||
('modified', 'course_id')
|
||||
]
|
||||
|
||||
# primary key will need to be large for this table
|
||||
|
||||
@@ -193,7 +193,7 @@ def calculate_problem_grade_report(entry_id, xmodule_instance_args):
|
||||
return run_main_task(entry_id, task_fn, action_name)
|
||||
|
||||
|
||||
@task(base=BaseInstructorTask, routing_key=settings.GRADES_DOWNLOAD_ROUTING_KEY) # pylint: disable=not-callable
|
||||
@task(base=BaseInstructorTask) # pylint: disable=not-callable
|
||||
def calculate_students_features_csv(entry_id, xmodule_instance_args):
|
||||
"""
|
||||
Compute student profile information for a course and upload the
|
||||
@@ -252,7 +252,7 @@ def proctored_exam_results_csv(entry_id, xmodule_instance_args):
|
||||
return run_main_task(entry_id, task_fn, action_name)
|
||||
|
||||
|
||||
@task(base=BaseInstructorTask, routing_key=settings.GRADES_DOWNLOAD_ROUTING_KEY) # pylint: disable=not-callable
|
||||
@task(base=BaseInstructorTask) # pylint: disable=not-callable
|
||||
def calculate_may_enroll_csv(entry_id, xmodule_instance_args):
|
||||
"""
|
||||
Compute information about invited students who have not enrolled
|
||||
@@ -293,7 +293,7 @@ def cohort_students(entry_id, xmodule_instance_args):
|
||||
return run_main_task(entry_id, task_fn, action_name)
|
||||
|
||||
|
||||
@task(base=BaseInstructorTask, routing_key=settings.GRADES_DOWNLOAD_ROUTING_KEY) # pylint: disable=not-callable
|
||||
@task(base=BaseInstructorTask) # pylint: disable=not-callable
|
||||
def export_ora2_data(entry_id, xmodule_instance_args):
|
||||
"""
|
||||
Generate a CSV of ora2 responses and push it to S3.
|
||||
|
||||
@@ -39,7 +39,7 @@ class DiscussionXBlock(XBlock, StudioEditableXBlockMixin, XmlParserMixin):
|
||||
discussion_id = String(scope=Scope.settings, default=UNIQUE_ID)
|
||||
display_name = String(
|
||||
display_name=_("Display Name"),
|
||||
help=_("Display name for this component"),
|
||||
help=_("The display name for this component."),
|
||||
default="Discussion",
|
||||
scope=Scope.settings
|
||||
)
|
||||
|
||||
@@ -72,7 +72,7 @@ git+https://github.com/edx/lettuce.git@0.2.20.002#egg=lettuce==0.2.20.002
|
||||
|
||||
# Our libraries:
|
||||
git+https://github.com/edx/XBlock.git@xblock-0.4.13#egg=XBlock==0.4.13
|
||||
-e git+https://github.com/edx/codejail.git@6b17c33a89bef0ac510926b1d7fea2748b73aadd#egg=codejail
|
||||
-e git+https://github.com/edx/codejail.git@0b2dc694f05ddc8fee3e65d837cee57b6ce51a6b#egg=codejail==0.0
|
||||
-e git+https://github.com/edx/event-tracking.git@0.2.1#egg=event-tracking==0.2.1
|
||||
-e git+https://github.com/edx/django-splash.git@v0.2#egg=django-splash==0.2
|
||||
-e git+https://github.com/edx/acid-block.git@e46f9cda8a03e121a00c7e347084d142d22ebfb7#egg=acid-xblock
|
||||
@@ -91,7 +91,7 @@ git+https://github.com/edx/xblock-utils.git@v1.0.3#egg=xblock-utils==1.0.3
|
||||
-e git+https://github.com/edx/edx-reverification-block.git@0.0.5#egg=edx-reverification-block==0.0.5
|
||||
git+https://github.com/edx/edx-user-state-client.git@1.0.1#egg=edx-user-state-client==1.0.1
|
||||
git+https://github.com/edx/xblock-lti-consumer.git@v1.1.0#egg=xblock-lti-consumer==1.1.0
|
||||
git+https://github.com/edx/edx-proctoring.git@0.16.2#egg=edx-proctoring==0.16.2
|
||||
git+https://github.com/edx/edx-proctoring.git@0.17.0#egg=edx-proctoring==0.17.0
|
||||
|
||||
# Third Party XBlocks
|
||||
-e git+https://github.com/mitodl/edx-sga@172a90fd2738f8142c10478356b2d9ed3e55334a#egg=edx-sga
|
||||
|
||||
Reference in New Issue
Block a user