Commit 3ea2d725 by Calen Pennington Committed by GitHub

Merge pull request #14329 from edx/release-candidate

Merge release-candidate to release
parents 0dad9f61 57b88abf
...@@ -39,7 +39,7 @@ class AnnotatableFields(object): ...@@ -39,7 +39,7 @@ class AnnotatableFields(object):
) )
display_name = String( display_name = String(
display_name=_("Display Name"), display_name=_("Display Name"),
help=_("Display name for this module"), help=_("The display name for this component."),
scope=Scope.settings, scope=Scope.settings,
default=_('Annotation'), default=_('Annotation'),
) )
......
...@@ -92,7 +92,7 @@ class CapaFields(object): ...@@ -92,7 +92,7 @@ class CapaFields(object):
""" """
display_name = String( display_name = String(
display_name=_("Display Name"), 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, scope=Scope.settings,
# it'd be nice to have a useful default but it screws up other things; so, # it'd be nice to have a useful default but it screws up other things; so,
# use display_name_with_default for those # use display_name_with_default for those
......
...@@ -27,7 +27,7 @@ class ConditionalFields(object): ...@@ -27,7 +27,7 @@ class ConditionalFields(object):
has_children = True has_children = True
display_name = String( display_name = String(
display_name=_("Display Name"), 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, scope=Scope.settings,
default=_('Conditional') default=_('Conditional')
) )
......
...@@ -38,7 +38,7 @@ class HtmlBlock(object): ...@@ -38,7 +38,7 @@ class HtmlBlock(object):
""" """
display_name = String( display_name = String(
display_name=_("Display Name"), 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, scope=Scope.settings,
# it'd be nice to have a useful default but it screws up other things; so, # it'd be nice to have a useful default but it screws up other things; so,
# use display_name_with_default for those # use display_name_with_default for those
...@@ -329,7 +329,7 @@ class HtmlDescriptor(HtmlBlock, XmlDescriptor, EditingDescriptor): # pylint: di ...@@ -329,7 +329,7 @@ class HtmlDescriptor(HtmlBlock, XmlDescriptor, EditingDescriptor): # pylint: di
class AboutFields(object): class AboutFields(object):
display_name = String( display_name = String(
help=_("Display name for this module"), help=_("The display name for this component."),
scope=Scope.settings, scope=Scope.settings,
default="overview", default="overview",
) )
...@@ -364,7 +364,7 @@ class StaticTabFields(object): ...@@ -364,7 +364,7 @@ class StaticTabFields(object):
""" """
display_name = String( display_name = String(
display_name=_("Display Name"), 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, scope=Scope.settings,
default="Empty", default="Empty",
) )
......
...@@ -45,7 +45,7 @@ class AnnotatableFields(object): ...@@ -45,7 +45,7 @@ class AnnotatableFields(object):
""")) """))
display_name = String( display_name = String(
display_name=_("Display Name"), display_name=_("Display Name"),
help=_("Display name for this module"), help=_("The display name for this component."),
scope=Scope.settings, scope=Scope.settings,
default=_('Image Annotation'), default=_('Image Annotation'),
) )
......
...@@ -60,7 +60,7 @@ class LibraryContentFields(object): ...@@ -60,7 +60,7 @@ class LibraryContentFields(object):
# to locate input elements - keep synchronized # to locate input elements - keep synchronized
display_name = String( display_name = String(
display_name=_("Display Name"), display_name=_("Display Name"),
help=_("Display name for this module"), help=_("The display name for this component."),
default="Randomized Content Block", default="Randomized Content Block",
scope=Scope.settings, scope=Scope.settings,
) )
......
...@@ -25,7 +25,7 @@ class LibraryRoot(XBlock): ...@@ -25,7 +25,7 @@ class LibraryRoot(XBlock):
resources_dir = None resources_dir = None
display_name = String( 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", default="Library",
display_name=_("Library Display Name"), display_name=_("Library Display Name"),
scope=Scope.settings scope=Scope.settings
......
...@@ -109,7 +109,7 @@ class LTIFields(object): ...@@ -109,7 +109,7 @@ class LTIFields(object):
display_name = String( display_name = String(
display_name=_("Display Name"), display_name=_("Display Name"),
help=_( 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." "Analytics reports may also use the display name to identify this component."
), ),
scope=Scope.settings, scope=Scope.settings,
......
...@@ -23,20 +23,43 @@ from xmodule.xml_module import XmlDescriptor ...@@ -23,20 +23,43 @@ from xmodule.xml_module import XmlDescriptor
from xblock.fields import Scope, String, Dict, Boolean, List from xblock.fields import Scope, String, Dict, Boolean, List
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
_ = lambda text: text
class PollFields(object): class PollFields(object):
# Name of poll to use in links to this poll # 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."),
voted = Boolean(help="Whether this student has voted on the poll", scope=Scope.user_state, default=False) scope=Scope.settings
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'} # 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"),
question = String(help="Poll question", scope=Scope.content, default='') scope=Scope.content,
default=[]
)
question = String(
help=_("Poll question"),
scope=Scope.content,
default=''
)
class PollModule(PollFields, XModule): class PollModule(PollFields, XModule):
......
...@@ -58,7 +58,7 @@ class SplitTestFields(object): ...@@ -58,7 +58,7 @@ class SplitTestFields(object):
display_name = String( display_name = String(
display_name=_("Display Name"), 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, scope=Scope.settings,
default=_("Content Experiment") default=_("Content Experiment")
) )
......
...@@ -37,8 +37,12 @@ class TestFields(object): ...@@ -37,8 +37,12 @@ class TestFields(object):
# Will not be returned by editable_metadata_fields because is not Scope.settings. # Will not be returned by editable_metadata_fields because is not Scope.settings.
student_answers = Dict(scope=Scope.user_state) student_answers = Dict(scope=Scope.user_state)
# Will be returned, and can override the inherited value from XModule. # 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', display_name = String(
help='local help') scope=Scope.settings,
default='local default',
display_name='Local Display Name',
help='local help'
)
# Used for testing select type, effect of to_json method # Used for testing select type, effect of to_json method
string_select = CrazyJsonString( string_select = CrazyJsonString(
scope=Scope.settings, scope=Scope.settings,
......
...@@ -34,7 +34,7 @@ class AnnotatableFields(object): ...@@ -34,7 +34,7 @@ class AnnotatableFields(object):
""")) """))
display_name = String( display_name = String(
display_name=_("Display Name"), display_name=_("Display Name"),
help=_("Display name for this module"), help=_("The display name for this component."),
scope=Scope.settings, scope=Scope.settings,
default=_('Text Annotation'), default=_('Text Annotation'),
) )
......
...@@ -14,7 +14,7 @@ _ = lambda text: text ...@@ -14,7 +14,7 @@ _ = lambda text: text
class VideoFields(object): class VideoFields(object):
"""Fields for `VideoModule` and `VideoDescriptor`.""" """Fields for `VideoModule` and `VideoDescriptor`."""
display_name = String( 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"), display_name=_("Component Display Name"),
default="Video", default="Video",
scope=Scope.settings scope=Scope.settings
......
...@@ -34,7 +34,7 @@ class AnnotatableFields(object): ...@@ -34,7 +34,7 @@ class AnnotatableFields(object):
""")) """))
display_name = String( display_name = String(
display_name=_("Display Name"), display_name=_("Display Name"),
help=_("Display name for this module"), help=_("The display name for this component."),
scope=Scope.settings, scope=Scope.settings,
default=_('Video Annotation'), default=_('Video Annotation'),
) )
......
...@@ -38,7 +38,7 @@ class WordCloudFields(object): ...@@ -38,7 +38,7 @@ class WordCloudFields(object):
"""XFields for word cloud.""" """XFields for word cloud."""
display_name = String( display_name = String(
display_name=_("Display Name"), 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, scope=Scope.settings,
default="Word cloud" default="Word cloud"
) )
......
...@@ -66,6 +66,11 @@ STUDIO_VIEW = 'studio_view' ...@@ -66,6 +66,11 @@ STUDIO_VIEW = 'studio_view'
PREVIEW_VIEWS = [STUDENT_VIEW, AUTHOR_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): class OpaqueKeyReader(IdReader):
""" """
IdReader for :class:`DefinitionKey` and :class:`UsageKey`s. IdReader for :class:`DefinitionKey` and :class:`UsageKey`s.
...@@ -256,8 +261,8 @@ class XModuleFields(object): ...@@ -256,8 +261,8 @@ class XModuleFields(object):
Common fields for XModules. Common fields for XModules.
""" """
display_name = String( display_name = String(
display_name="Display Name", 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, scope=Scope.settings,
# it'd be nice to have a useful default but it screws up other things; so, # it'd be nice to have a useful default but it screws up other things; so,
# use display_name_with_default for those # use display_name_with_default for those
......
# -*- 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')]),
),
]
# -*- 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): ...@@ -253,6 +253,17 @@ class PersistentSubsectionGrade(DeleteGradesMixin, TimeStampedModel):
# * Course staff can see all grades for a course using (course_id,) # * Course staff can see all grades for a course using (course_id,)
('course_id', 'user_id', 'usage_key'), ('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 # primary key will need to be large for this table
id = UnsignedBigIntAutoField(primary_key=True) # pylint: disable=invalid-name id = UnsignedBigIntAutoField(primary_key=True) # pylint: disable=invalid-name
...@@ -502,11 +513,14 @@ class PersistentCourseGrade(DeleteGradesMixin, TimeStampedModel): ...@@ -502,11 +513,14 @@ class PersistentCourseGrade(DeleteGradesMixin, TimeStampedModel):
# (course_id) for instructors to see all course grades, implicitly created via the unique_together constraint # (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 # (user_id) for course dashboard; explicitly declared as an index below
# (passed_timestamp, course_id) for tracking when users first earned a passing grade. # (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 = [ unique_together = [
('course_id', 'user_id'), ('course_id', 'user_id'),
] ]
index_together = [ index_together = [
('passed_timestamp', 'course_id'), ('passed_timestamp', 'course_id'),
('modified', 'course_id')
] ]
# primary key will need to be large for this table # primary key will need to be large for this table
......
...@@ -193,7 +193,7 @@ def calculate_problem_grade_report(entry_id, xmodule_instance_args): ...@@ -193,7 +193,7 @@ def calculate_problem_grade_report(entry_id, xmodule_instance_args):
return run_main_task(entry_id, task_fn, action_name) 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): def calculate_students_features_csv(entry_id, xmodule_instance_args):
""" """
Compute student profile information for a course and upload the Compute student profile information for a course and upload the
...@@ -252,7 +252,7 @@ def proctored_exam_results_csv(entry_id, xmodule_instance_args): ...@@ -252,7 +252,7 @@ def proctored_exam_results_csv(entry_id, xmodule_instance_args):
return run_main_task(entry_id, task_fn, action_name) 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): def calculate_may_enroll_csv(entry_id, xmodule_instance_args):
""" """
Compute information about invited students who have not enrolled Compute information about invited students who have not enrolled
...@@ -293,7 +293,7 @@ def cohort_students(entry_id, xmodule_instance_args): ...@@ -293,7 +293,7 @@ def cohort_students(entry_id, xmodule_instance_args):
return run_main_task(entry_id, task_fn, action_name) 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): def export_ora2_data(entry_id, xmodule_instance_args):
""" """
Generate a CSV of ora2 responses and push it to S3. Generate a CSV of ora2 responses and push it to S3.
......
...@@ -39,7 +39,7 @@ class DiscussionXBlock(XBlock, StudioEditableXBlockMixin, XmlParserMixin): ...@@ -39,7 +39,7 @@ class DiscussionXBlock(XBlock, StudioEditableXBlockMixin, XmlParserMixin):
discussion_id = String(scope=Scope.settings, default=UNIQUE_ID) discussion_id = String(scope=Scope.settings, default=UNIQUE_ID)
display_name = String( display_name = String(
display_name=_("Display Name"), display_name=_("Display Name"),
help=_("Display name for this component"), help=_("The display name for this component."),
default="Discussion", default="Discussion",
scope=Scope.settings scope=Scope.settings
) )
......
...@@ -72,7 +72,7 @@ git+https://github.com/edx/lettuce.git@0.2.20.002#egg=lettuce==0.2.20.002 ...@@ -72,7 +72,7 @@ git+https://github.com/edx/lettuce.git@0.2.20.002#egg=lettuce==0.2.20.002
# Our libraries: # Our libraries:
git+https://github.com/edx/XBlock.git@xblock-0.4.13#egg=XBlock==0.4.13 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/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/django-splash.git@v0.2#egg=django-splash==0.2
-e git+https://github.com/edx/acid-block.git@e46f9cda8a03e121a00c7e347084d142d22ebfb7#egg=acid-xblock -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 ...@@ -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 -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/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/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 # Third Party XBlocks
-e git+https://github.com/mitodl/edx-sga@172a90fd2738f8142c10478356b2d9ed3e55334a#egg=edx-sga -e git+https://github.com/mitodl/edx-sga@172a90fd2738f8142c10478356b2d9ed3e55334a#egg=edx-sga
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment