From 66f3aa5ccf2bba09489c083a3a20b7fdb6f35111 Mon Sep 17 00:00:00 2001 From: John Eskew <jeskew@edx.org> Date: Tue, 23 May 2017 09:47:47 -0400 Subject: [PATCH] Move fields.py, inheritance.py, and partitions to openedx/core. --- .../contentstore/course_group_config.py | 4 +- .../tests/test_course_settings.py | 2 +- .../tests/test_courseware_index.py | 4 +- .../contentstore/tests/test_utils.py | 7 +- cms/djangoapps/contentstore/utils.py | 2 +- cms/djangoapps/contentstore/views/course.py | 2 +- cms/djangoapps/contentstore/views/item.py | 4 +- cms/djangoapps/contentstore/views/preview.py | 2 +- .../views/tests/test_group_configurations.py | 2 +- .../contentstore/views/tests/test_item.py | 12 +- cms/djangoapps/models/settings/encoder.py | 2 +- cms/envs/common.py | 2 +- cms/lib/xblock/test/test_authoring_mixin.py | 2 +- common/lib/xmodule/xmodule/capa_base.py | 2 +- .../xmodule/xmodule/course_metadata_utils.py | 2 +- common/lib/xmodule/xmodule/course_module.py | 4 +- .../xmodule/modulestore/inheritance.py | 230 +---------------- .../xmodule/xmodule/modulestore/mongo/base.py | 5 +- .../split_mongo/caching_descriptor_system.py | 3 +- .../xmodule/modulestore/split_mongo/split.py | 9 +- .../test_cross_modulestore_import_export.py | 2 +- .../tests/test_mixed_modulestore.py | 2 +- .../xmodule/modulestore/tests/test_mongo.py | 29 ++- .../tests/test_split_modulestore.py | 18 +- .../tests/test_split_w_old_mongo.py | 4 +- .../modulestore/tests/test_xml_importer.py | 15 +- .../xmodule/modulestore/tests/utils.py | 4 +- common/lib/xmodule/xmodule/seq_module.py | 4 +- .../lib/xmodule/xmodule/split_test_module.py | 14 +- common/lib/xmodule/xmodule/tests/__init__.py | 3 +- .../tests/test_course_metadata_utils.py | 2 +- .../lib/xmodule/xmodule/tests/test_fields.py | 3 +- .../lib/xmodule/xmodule/tests/test_import.py | 18 +- .../xmodule/xmodule/tests/test_lti_unit.py | 2 +- .../xmodule/tests/test_split_test_module.py | 8 +- .../xmodule/xmodule/tests/test_xml_module.py | 7 +- .../xmodule/xmodule/tests/xml/factories.py | 2 +- common/lib/xmodule/xmodule/timeinfo.py | 38 --- .../xmodule/video_module/video_handlers.py | 4 +- .../xmodule/video_module/video_xfields.py | 2 +- common/lib/xmodule/xmodule/x_module.py | 8 +- .../discussion/test_cohort_management.py | 11 +- common/test/acceptance/tests/helpers.py | 14 +- .../test_lms_split_test_courseware_search.py | 2 +- .../tests/lms/test_lms_user_preview.py | 6 +- .../tests/studio/test_studio_container.py | 2 +- .../tests/studio/test_studio_settings.py | 5 +- .../tests/studio/test_studio_split_test.py | 2 +- .../course_api/tests/test_serializers.py | 2 +- .../course_blocks/transformers/start_date.py | 2 +- .../transformers/tests/test_split_test.py | 2 +- .../tests/test_user_partitions.py | 2 +- .../transformers/user_partitions.py | 2 +- lms/djangoapps/courseware/access.py | 6 +- lms/djangoapps/courseware/access_response.py | 2 +- lms/djangoapps/courseware/field_overrides.py | 2 +- lms/djangoapps/courseware/masquerade.py | 2 +- .../courseware/tests/test_access.py | 2 +- .../courseware/tests/test_group_access.py | 2 +- .../courseware/tests/test_masquerade.py | 2 +- .../courseware/tests/test_split_module.py | 2 +- .../tests/test_submitting_problems.py | 2 +- .../discussion_api/tests/test_api.py | 2 +- lms/djangoapps/instructor/tests/test_api.py | 2 +- lms/djangoapps/instructor/tests/test_tools.py | 2 +- lms/djangoapps/instructor/views/tools.py | 2 +- .../instructor_task/tasks_helper/grades.py | 2 +- .../tests/test_tasks_helper.py | 2 +- lms/djangoapps/lms_xblock/mixin.py | 4 +- lms/djangoapps/lms_xblock/runtime.py | 2 +- lms/djangoapps/mobile_api/users/tests.py | 2 +- .../mobile_api/video_outlines/tests.py | 2 +- lms/envs/common.py | 2 +- lms/lib/xblock/test/test_mixin.py | 2 +- lms/templates/preview_menu.html | 2 +- .../content/course_overviews/models.py | 3 +- .../content/course_overviews/tests.py | 2 +- .../course_groups/partition_scheme.py | 2 +- .../tests/test_partition_scheme.py | 2 +- .../core/djangoapps/models/course_details.py | 2 +- .../djangoapps/user_api/partition_schemes.py | 2 +- .../user_api/tests/test_partition_schemes.py | 4 +- openedx/core/djangoapps/util/testing.py | 2 +- .../partition_scheme.py | 2 +- .../tests/test_partition_scheme.py | 2 +- .../core/lib}/partitions/__init__.py | 0 .../core/lib}/partitions/partitions.py | 0 .../lib}/partitions/partitions_service.py | 2 +- .../core/lib}/partitions/tests/__init__.py | 0 .../lib}/partitions/tests/test_partitions.py | 4 +- openedx/core/lib/xblock_fields/__init__.py | 0 .../core/lib/xblock_fields}/fields.py | 35 +++ .../lib/xblock_fields/inherited_fields.py | 239 ++++++++++++++++++ .../tests/views/test_course_outline.py | 2 +- 94 files changed, 455 insertions(+), 443 deletions(-) delete mode 100644 common/lib/xmodule/xmodule/timeinfo.py rename {common/lib/xmodule/xmodule => openedx/core/lib}/partitions/__init__.py (100%) rename {common/lib/xmodule/xmodule => openedx/core/lib}/partitions/partitions.py (100%) rename {common/lib/xmodule/xmodule => openedx/core/lib}/partitions/partitions_service.py (98%) rename {common/lib/xmodule/xmodule => openedx/core/lib}/partitions/tests/__init__.py (100%) rename {common/lib/xmodule/xmodule => openedx/core/lib}/partitions/tests/test_partitions.py (99%) create mode 100644 openedx/core/lib/xblock_fields/__init__.py rename {common/lib/xmodule/xmodule => openedx/core/lib/xblock_fields}/fields.py (86%) create mode 100644 openedx/core/lib/xblock_fields/inherited_fields.py diff --git a/cms/djangoapps/contentstore/course_group_config.py b/cms/djangoapps/contentstore/course_group_config.py index 6bcbee47a7d..0c083bb4a96 100644 --- a/cms/djangoapps/contentstore/course_group_config.py +++ b/cms/djangoapps/contentstore/course_group_config.py @@ -9,8 +9,8 @@ from util.db import generate_int_id, MYSQL_MAX_INT from django.utils.translation import ugettext as _ from contentstore.utils import reverse_usage_url from openedx.core.djangoapps.course_groups.partition_scheme import get_cohorted_user_partition -from xmodule.partitions.partitions import UserPartition, MINIMUM_STATIC_PARTITION_ID -from xmodule.partitions.partitions_service import get_all_partitions_for_course +from openedx.core.lib.partitions.partitions import UserPartition, MINIMUM_STATIC_PARTITION_ID +from openedx.core.lib.partitions.partitions_service import get_all_partitions_for_course from xmodule.split_test_module import get_split_user_partitions MINIMUM_GROUP_ID = MINIMUM_STATIC_PARTITION_ID diff --git a/cms/djangoapps/contentstore/tests/test_course_settings.py b/cms/djangoapps/contentstore/tests/test_course_settings.py index c7eea5c1f3a..a361f0049a7 100644 --- a/cms/djangoapps/contentstore/tests/test_course_settings.py +++ b/cms/djangoapps/contentstore/tests/test_course_settings.py @@ -19,10 +19,10 @@ from models.settings.course_metadata import CourseMetadata from models.settings.encoder import CourseSettingsEncoder from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.djangoapps.models.course_details import CourseDetails +from openedx.core.lib.xblock_fields.fields import Date from student.roles import CourseInstructorRole, CourseStaffRole from student.tests.factories import UserFactory from xblock_django.models import XBlockStudioConfigurationFlag -from xmodule.fields import Date from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.django import modulestore from xmodule.modulestore.tests.factories import CourseFactory diff --git a/cms/djangoapps/contentstore/tests/test_courseware_index.py b/cms/djangoapps/contentstore/tests/test_courseware_index.py index aaa305f0c3f..b7d60fc02bf 100644 --- a/cms/djangoapps/contentstore/tests/test_courseware_index.py +++ b/cms/djangoapps/contentstore/tests/test_courseware_index.py @@ -16,11 +16,12 @@ from django.conf import settings from course_modes.models import CourseMode from openedx.core.djangoapps.models.course_details import CourseDetails +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin +from openedx.core.lib.partitions.partitions import UserPartition from xmodule.library_tools import normalize_key_for_search from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.django import SignalHandler, modulestore from xmodule.modulestore.edit_info import EditInfoMixin -from xmodule.modulestore.inheritance import InheritanceMixin from xmodule.modulestore.mixed import MixedModuleStore from xmodule.modulestore.tests.django_utils import ( TEST_DATA_MONGO_MODULESTORE, @@ -34,7 +35,6 @@ from xmodule.modulestore.tests.utils import ( ) from xmodule.tests import DATA_DIR from xmodule.x_module import XModuleMixin -from xmodule.partitions.partitions import UserPartition from search.search_engine_base import SearchEngine diff --git a/cms/djangoapps/contentstore/tests/test_utils.py b/cms/djangoapps/contentstore/tests/test_utils.py index f73447e4b25..03bc91f0582 100644 --- a/cms/djangoapps/contentstore/tests/test_utils.py +++ b/cms/djangoapps/contentstore/tests/test_utils.py @@ -4,13 +4,12 @@ from datetime import datetime, timedelta from pytz import UTC from django.test import TestCase +from opaque_keys.edx.locations import SlashSeparatedCourseKey from xmodule.modulestore import ModuleStoreEnum +from xmodule.modulestore.django import modulestore from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase -from opaque_keys.edx.locations import SlashSeparatedCourseKey -from xmodule.modulestore.django import modulestore -from xmodule.partitions.partitions import UserPartition, Group - +from openedx.core.lib.partitions.partitions import UserPartition, Group from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration_context from contentstore import utils diff --git a/cms/djangoapps/contentstore/utils.py b/cms/djangoapps/contentstore/utils.py index a414f5815ce..e2b69a47333 100644 --- a/cms/djangoapps/contentstore/utils.py +++ b/cms/djangoapps/contentstore/utils.py @@ -14,7 +14,7 @@ from django_comment_common.utils import seed_permissions_roles from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.djangoapps.site_configuration.models import SiteConfiguration -from xmodule.partitions.partitions_service import get_all_partitions_for_course +from openedx.core.lib.partitions.partitions_service import get_all_partitions_for_course from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.django import modulestore diff --git a/cms/djangoapps/contentstore/views/course.py b/cms/djangoapps/contentstore/views/course.py index e3a5e45ceaf..3e0d9fc6410 100644 --- a/cms/djangoapps/contentstore/views/course.py +++ b/cms/djangoapps/contentstore/views/course.py @@ -69,6 +69,7 @@ from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers from openedx.core.lib.course_tabs import CourseTabPluginManager from openedx.core.lib.courses import course_image_url +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from openedx.core.djangolib.js_utils import dump_js_escaped_json from student import auth from student.auth import has_course_author_access, has_studio_write_access, has_studio_read_access @@ -93,7 +94,6 @@ from util.string_utils import _has_non_ascii_characters from xblock_django.api import deprecated_xblocks from xmodule.contentstore.content import StaticContent from xmodule.course_module import CourseFields -from xmodule.course_module import DEFAULT_START_DATE from xmodule.error_module import ErrorDescriptor from xmodule.modulestore import EdxJSONEncoder from xmodule.modulestore.django import modulestore diff --git a/cms/djangoapps/contentstore/views/item.py b/cms/djangoapps/contentstore/views/item.py index e6510be15aa..234dc3e223b 100644 --- a/cms/djangoapps/contentstore/views/item.py +++ b/cms/djangoapps/contentstore/views/item.py @@ -38,16 +38,16 @@ from contentstore.views.helpers import is_unit, xblock_studio_url, xblock_primar from contentstore.views.preview import get_preview_fragment from contentstore.utils import is_self_paced -from openedx.core.lib.gating import api as gating_api from edxmako.shortcuts import render_to_string from models.settings.course_grading import CourseGradingModel +from openedx.core.lib.gating import api as gating_api from openedx.core.lib.xblock_utils import wrap_xblock, request_token +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from static_replace import replace_static_urls from student.auth import has_studio_write_access, has_studio_read_access from util.date_utils import get_default_time_display from util.json_request import expect_json, JsonResponse from util.milestones_helpers import is_entrance_exams_enabled -from xmodule.course_module import DEFAULT_START_DATE from xmodule.modulestore import ModuleStoreEnum, EdxJSONEncoder from xmodule.modulestore.django import modulestore from xmodule.modulestore.draft_and_published import DIRECT_ONLY_CATEGORIES diff --git a/cms/djangoapps/contentstore/views/preview.py b/cms/djangoapps/contentstore/views/preview.py index 5d728c4aa99..85062347b85 100644 --- a/cms/djangoapps/contentstore/views/preview.py +++ b/cms/djangoapps/contentstore/views/preview.py @@ -13,11 +13,11 @@ from edxmako.shortcuts import render_to_string from openedx.core.lib.xblock_utils import ( replace_static_urls, wrap_xblock, wrap_fragment, wrap_xblock_aside, request_token, xblock_local_resource_url, ) +from openedx.core.lib.partitions.partitions_service import PartitionService from xmodule.x_module import PREVIEW_VIEWS, STUDENT_VIEW, AUTHOR_VIEW from xmodule.contentstore.django import contentstore from xmodule.error_module import ErrorDescriptor from xmodule.exceptions import NotFoundError, ProcessingError -from xmodule.partitions.partitions_service import PartitionService from xmodule.studio_editable import has_author_view from xmodule.services import SettingsService from xmodule.modulestore.django import modulestore, ModuleI18nService diff --git a/cms/djangoapps/contentstore/views/tests/test_group_configurations.py b/cms/djangoapps/contentstore/views/tests/test_group_configurations.py index ff2710c3ef3..7dabd8ad871 100644 --- a/cms/djangoapps/contentstore/views/tests/test_group_configurations.py +++ b/cms/djangoapps/contentstore/views/tests/test_group_configurations.py @@ -10,7 +10,7 @@ from mock import patch from contentstore.utils import reverse_course_url, reverse_usage_url from contentstore.course_group_config import GroupConfiguration, CONTENT_GROUP_CONFIGURATION_NAME from contentstore.tests.utils import CourseTestCase -from xmodule.partitions.partitions import Group, UserPartition +from openedx.core.lib.partitions.partitions import Group, UserPartition from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from xmodule.validation import StudioValidation, StudioValidationMessage from xmodule.modulestore.django import modulestore diff --git a/cms/djangoapps/contentstore/views/tests/test_item.py b/cms/djangoapps/contentstore/views/tests/test_item.py index 11c675b7196..4686663532e 100644 --- a/cms/djangoapps/contentstore/views/tests/test_item.py +++ b/cms/djangoapps/contentstore/views/tests/test_item.py @@ -16,7 +16,13 @@ from django.core.urlresolvers import reverse from contentstore.utils import reverse_usage_url, reverse_course_url from opaque_keys import InvalidKeyError +from opaque_keys.edx.keys import UsageKey, CourseKey +from opaque_keys.edx.locations import Location from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration +from openedx.core.lib.partitions.partitions import ( + Group, UserPartition, ENROLLMENT_TRACK_PARTITION_ID, MINIMUM_STATIC_PARTITION_ID +) +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from contentstore.views.component import ( component_handler, get_component_templates ) @@ -35,7 +41,6 @@ from xmodule.modulestore.exceptions import ItemNotFoundError from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, TEST_DATA_SPLIT_MODULESTORE from xmodule.modulestore.tests.factories import ItemFactory, LibraryFactory, check_mongo_calls, CourseFactory from xmodule.x_module import STUDIO_VIEW, STUDENT_VIEW -from xmodule.course_module import DEFAULT_START_DATE from xblock.core import XBlockAside from xblock.fields import Scope, String, ScopeIds from xblock.fragment import Fragment @@ -43,11 +48,6 @@ from xblock.runtime import DictKeyValueStore, KvsFieldData from xblock.test.tools import TestRuntime from xblock.exceptions import NoSuchHandlerError from xblock_django.user_service import DjangoXBlockUserService -from opaque_keys.edx.keys import UsageKey, CourseKey -from opaque_keys.edx.locations import Location -from xmodule.partitions.partitions import ( - Group, UserPartition, ENROLLMENT_TRACK_PARTITION_ID, MINIMUM_STATIC_PARTITION_ID -) class AsideTest(XBlockAside): diff --git a/cms/djangoapps/models/settings/encoder.py b/cms/djangoapps/models/settings/encoder.py index 36b6e1fb441..f048d3c15f1 100644 --- a/cms/djangoapps/models/settings/encoder.py +++ b/cms/djangoapps/models/settings/encoder.py @@ -7,7 +7,7 @@ from json.encoder import JSONEncoder from opaque_keys.edx.locations import Location from openedx.core.djangoapps.models.course_details import CourseDetails -from xmodule.fields import Date +from openedx.core.lib.xblock_fields.fields import Date from .course_grading import CourseGradingModel diff --git a/cms/envs/common.py b/cms/envs/common.py index e8579c8f3aa..58146b8e28f 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -432,7 +432,7 @@ P3P_HEADER = 'CP="Open EdX does not have a P3P policy."' ############# XBlock Configuration ########## # Import after sys.path fixup -from xmodule.modulestore.inheritance import InheritanceMixin +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.modulestore import prefer_xmodules from xmodule.x_module import XModuleMixin diff --git a/cms/lib/xblock/test/test_authoring_mixin.py b/cms/lib/xblock/test/test_authoring_mixin.py index c45270c70a2..3d77163dee8 100644 --- a/cms/lib/xblock/test/test_authoring_mixin.py +++ b/cms/lib/xblock/test/test_authoring_mixin.py @@ -8,7 +8,7 @@ from course_modes.tests.factories import CourseModeFactory from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from xmodule.partitions.partitions import ( +from openedx.core.lib.partitions.partitions import ( Group, UserPartition, ENROLLMENT_TRACK_PARTITION_ID, MINIMUM_STATIC_PARTITION_ID ) diff --git a/common/lib/xmodule/xmodule/capa_base.py b/common/lib/xmodule/xmodule/capa_base.py index 492e97ec38e..fea7d858bcc 100644 --- a/common/lib/xmodule/xmodule/capa_base.py +++ b/common/lib/xmodule/xmodule/capa_base.py @@ -27,9 +27,9 @@ from xblock.fields import Boolean, Dict, Float, Integer, Scope, String, XMLStrin from xblock.scorable import ScorableXBlockMixin, Score from xmodule.capa_base_constants import RANDOMIZATION, SHOWANSWER, SHOW_CORRECTNESS from xmodule.exceptions import NotFoundError -from .fields import Date, Timedelta from .progress import Progress +from openedx.core.lib.xblock_fields.fields import Date, Timedelta from openedx.core.djangolib.markup import HTML, Text log = logging.getLogger("edx.courseware") diff --git a/common/lib/xmodule/xmodule/course_metadata_utils.py b/common/lib/xmodule/xmodule/course_metadata_utils.py index e0a2e996edb..cdf4d48bcdd 100644 --- a/common/lib/xmodule/xmodule/course_metadata_utils.py +++ b/common/lib/xmodule/xmodule/course_metadata_utils.py @@ -12,7 +12,7 @@ from math import exp from pytz import utc -DEFAULT_START_DATE = datetime(2030, 1, 1, tzinfo=utc) +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE def clean_course_key(course_key, padding_char): diff --git a/common/lib/xmodule/xmodule/course_module.py b/common/lib/xmodule/xmodule/course_module.py index e32356062f8..88159314317 100644 --- a/common/lib/xmodule/xmodule/course_module.py +++ b/common/lib/xmodule/xmodule/course_module.py @@ -14,12 +14,12 @@ from pytz import utc from xblock.fields import Scope, List, String, Dict, Boolean, Integer, Float from xmodule import course_metadata_utils -from xmodule.course_metadata_utils import DEFAULT_START_DATE from xmodule.graders import grader_from_conf from xmodule.mixin import LicenseMixin from xmodule.seq_module import SequenceDescriptor, SequenceModule from xmodule.tabs import CourseTabList, InvalidTabsException -from .fields import Date +from openedx.core.lib.xblock_fields.fields import Date +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE log = logging.getLogger(__name__) diff --git a/common/lib/xmodule/xmodule/modulestore/inheritance.py b/common/lib/xmodule/xmodule/modulestore/inheritance.py index 91c2811b35c..65321d222b5 100644 --- a/common/lib/xmodule/xmodule/modulestore/inheritance.py +++ b/common/lib/xmodule/xmodule/modulestore/inheritance.py @@ -5,235 +5,9 @@ from __future__ import absolute_import from django.conf import settings -from xmodule.partitions.partitions import UserPartition -from xblock.fields import Scope, Boolean, String, Float, XBlockMixin, Dict, Integer, List +from xblock.fields import Scope from xblock.runtime import KeyValueStore, KvsFieldData -from xmodule.fields import Date, Timedelta -from ..course_metadata_utils import DEFAULT_START_DATE - - -# 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 UserPartitionList(List): - """Special List class for listing UserPartitions""" - def from_json(self, values): - return [UserPartition.from_json(v) for v in values] - - def to_json(self, values): - return [user_partition.to_json() - for user_partition in values] - - -class InheritanceMixin(XBlockMixin): - """Field definitions for inheritable fields.""" - - graded = Boolean( - help="Whether this module contributes to the final course grade", - scope=Scope.settings, - default=False, - ) - start = Date( - help="Start time when this module is visible", - default=DEFAULT_START_DATE, - scope=Scope.settings - ) - due = Date( - display_name=_("Due Date"), - help=_("Enter the default date by which problems are due."), - scope=Scope.settings, - ) - visible_to_staff_only = Boolean( - help=_("If true, can be seen only by course staff, regardless of start date."), - default=False, - scope=Scope.settings, - ) - course_edit_method = String( - display_name=_("Course Editor"), - help=_("Enter the method by which this course is edited (\"XML\" or \"Studio\")."), - default="Studio", - scope=Scope.settings, - deprecated=True # Deprecated because user would not change away from Studio within Studio. - ) - giturl = String( - display_name=_("GIT URL"), - help=_("Enter the URL for the course data GIT repository."), - scope=Scope.settings - ) - xqa_key = String( - display_name=_("XQA Key"), - help=_("This setting is not currently supported."), scope=Scope.settings, - deprecated=True - ) - annotation_storage_url = String( - help=_("Enter the location of the annotation storage server. The textannotation, videoannotation, and imageannotation advanced modules require this setting."), - scope=Scope.settings, - default="http://your_annotation_storage.com", - display_name=_("URL for Annotation Storage") - ) - annotation_token_secret = String( - help=_("Enter the secret string for annotation storage. The textannotation, videoannotation, and imageannotation advanced modules require this string."), - scope=Scope.settings, - default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", - display_name=_("Secret Token String for Annotation") - ) - graceperiod = Timedelta( - help="Amount of time after the due date that submissions will be accepted", - scope=Scope.settings, - ) - group_access = Dict( - help=_("Enter the ids for the content groups this problem belongs to."), - scope=Scope.settings, - ) - - showanswer = String( - display_name=_("Show Answer"), - help=_( - # Translators: DO NOT translate the words in quotes here, they are - # specific words for the acceptable values. - 'Specify when the Show Answer button appears for each problem. ' - 'Valid values are "always", "answered", "attempted", "closed", ' - '"finished", "past_due", "correct_or_past_due", and "never".' - ), - scope=Scope.settings, - default="finished", - ) - - show_correctness = String( - display_name=_("Show Results"), - help=_( - # Translators: DO NOT translate the words in quotes here, they are - # specific words for the acceptable values. - 'Specify when to show answer correctness and score to learners. ' - 'Valid values are "always", "never", and "past_due".' - ), - scope=Scope.settings, - default="always", - ) - - rerandomize = String( - display_name=_("Randomization"), - help=_( - # Translators: DO NOT translate the words in quotes here, they are - # specific words for the acceptable values. - 'Specify the default for how often variable values in a problem are randomized. ' - 'This setting should be set to "never" unless you plan to provide a Python ' - 'script to identify and randomize values in most of the problems in your course. ' - 'Valid values are "always", "onreset", "never", and "per_student".' - ), - scope=Scope.settings, - default="never", - ) - days_early_for_beta = Float( - display_name=_("Days Early for Beta Users"), - help=_("Enter the number of days before the start date that beta users can access the course."), - scope=Scope.settings, - default=None, - ) - static_asset_path = String( - display_name=_("Static Asset Path"), - help=_("Enter the path to use for files on the Files & Uploads page. This value overrides the Studio default, c4x://."), - scope=Scope.settings, - default='', - ) - use_latex_compiler = Boolean( - display_name=_("Enable LaTeX Compiler"), - help=_("Enter true or false. If true, you can use the LaTeX templates for HTML components and advanced Problem components."), - default=False, - scope=Scope.settings - ) - max_attempts = Integer( - display_name=_("Maximum Attempts"), - help=_("Enter the maximum number of times a student can try to answer problems. By default, Maximum Attempts is set to null, meaning that students have an unlimited number of attempts for problems. You can override this course-wide setting for individual problems. However, if the course-wide setting is a specific number, you cannot set the Maximum Attempts for individual problems to unlimited."), - values={"min": 0}, scope=Scope.settings - ) - matlab_api_key = String( - display_name=_("Matlab API key"), - help=_("Enter the API key provided by MathWorks for accessing the MATLAB Hosted Service. " - "This key is granted for exclusive use in this course for the specified duration. " - "Do not share the API key with other courses. Notify MathWorks immediately " - "if you believe the key is exposed or compromised. To obtain a key for your course, " - "or to report an issue, please contact moocsupport@mathworks.com"), - scope=Scope.settings - ) - # This is should be scoped to content, but since it's defined in the policy - # file, it is currently scoped to settings. - user_partitions = UserPartitionList( - display_name=_("Group Configurations"), - help=_("Enter the configurations that govern how students are grouped together."), - default=[], - scope=Scope.settings - ) - video_speed_optimizations = Boolean( - display_name=_("Enable video caching system"), - help=_("Enter true or false. If true, video caching will be used for HTML5 videos."), - default=True, - scope=Scope.settings - ) - video_bumper = Dict( - display_name=_("Video Pre-Roll"), - help=_( - "Identify a video, 5-10 seconds in length, to play before course videos. Enter the video ID from " - "the Video Uploads page and one or more transcript files in the following format: {format}. " - "For example, an entry for a video with two transcripts looks like this: {example}" - ).format( - format='{"video_id": "ID", "transcripts": {"language": "/static/filename.srt"}}', - example=( - '{' - '"video_id": "77cef264-d6f5-4cf2-ad9d-0178ab8c77be", ' - '"transcripts": {"en": "/static/DemoX-D01_1.srt", "uk": "/static/DemoX-D01_1_uk.srt"}' - '}' - ), - ), - scope=Scope.settings - ) - - reset_key = "DEFAULT_SHOW_RESET_BUTTON" - default_reset_button = getattr(settings, reset_key) if hasattr(settings, reset_key) else False - show_reset_button = Boolean( - display_name=_("Show Reset Button for Problems"), - help=_( - "Enter true or false. If true, problems in the course default to always displaying a 'Reset' button. " - "You can override this in each problem's settings. All existing problems are affected when " - "this course-wide setting is changed." - ), - scope=Scope.settings, - default=default_reset_button - ) - edxnotes = Boolean( - display_name=_("Enable Student Notes"), - help=_("Enter true or false. If true, students can use the Student Notes feature."), - default=False, - scope=Scope.settings - ) - edxnotes_visibility = Boolean( - display_name="Student Notes Visibility", - help=_("Indicates whether Student Notes are visible in the course. " - "Students can also show or hide their notes in the courseware."), - default=True, - scope=Scope.user_info - ) - - in_entrance_exam = Boolean( - display_name=_("Tag this module as part of an Entrance Exam section"), - help=_("Enter true or false. If true, answer submissions for problem modules will be " - "considered in the Entrance Exam scoring/gating algorithm."), - scope=Scope.settings, - default=False - ) - - self_paced = Boolean( - display_name=_('Self Paced'), - help=_( - 'Set this to "true" to mark this course as self-paced. Self-paced courses do not have ' - 'due dates for assignments, and students can progress through the course at any rate before ' - 'the course ends.' - ), - default=False, - scope=Scope.settings - ) +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin def compute_inherited_metadata(descriptor): diff --git a/common/lib/xmodule/xmodule/modulestore/mongo/base.py b/common/lib/xmodule/xmodule/modulestore/mongo/base.py index aad2b8c2362..efc0e270773 100644 --- a/common/lib/xmodule/xmodule/modulestore/mongo/base.py +++ b/common/lib/xmodule/xmodule/modulestore/mongo/base.py @@ -35,6 +35,8 @@ from xblock.exceptions import InvalidScopeError from xblock.fields import Scope, ScopeIds, Reference, ReferenceList, ReferenceValueDict from xblock.runtime import KvsFieldData +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin +from openedx.core.lib.partitions.partitions_service import PartitionService from xmodule.assetstore import AssetMetadata, CourseAssetsFromStorage from xmodule.course_module import CourseSummary from xmodule.error_module import ErrorDescriptor @@ -46,8 +48,7 @@ from xmodule.modulestore import ModuleStoreWriteBase, ModuleStoreEnum, BulkOpera from xmodule.modulestore.draft_and_published import ModuleStoreDraftAndPublished, DIRECT_ONLY_CATEGORIES from xmodule.modulestore.edit_info import EditInfoRuntimeMixin from xmodule.modulestore.exceptions import ItemNotFoundError, DuplicateCourseError, ReferentialIntegrityError -from xmodule.modulestore.inheritance import InheritanceMixin, inherit_metadata, InheritanceKeyValueStore -from xmodule.partitions.partitions_service import PartitionService +from xmodule.modulestore.inheritance import inherit_metadata, InheritanceKeyValueStore from xmodule.modulestore.xml import CourseLocationManager from xmodule.modulestore.store_utilities import DETACHED_XBLOCK_TYPES from xmodule.services import SettingsService diff --git a/common/lib/xmodule/xmodule/modulestore/split_mongo/caching_descriptor_system.py b/common/lib/xmodule/xmodule/modulestore/split_mongo/caching_descriptor_system.py index 2e5d3f7cfed..02afd65c24a 100644 --- a/common/lib/xmodule/xmodule/modulestore/split_mongo/caching_descriptor_system.py +++ b/common/lib/xmodule/xmodule/modulestore/split_mongo/caching_descriptor_system.py @@ -9,6 +9,7 @@ from xblock.fields import ScopeIds from xblock.core import XBlock from opaque_keys.edx.locator import BlockUsageLocator, LocalId, CourseLocator, LibraryLocator, DefinitionLocator +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.library_tools import LibraryToolsService from xmodule.mako_module import MakoDescriptorSystem from xmodule.error_module import ErrorDescriptor @@ -16,7 +17,7 @@ from xmodule.errortracker import exc_info_to_str from xmodule.modulestore import BlockData from xmodule.modulestore.edit_info import EditInfoRuntimeMixin from xmodule.modulestore.exceptions import ItemNotFoundError -from xmodule.modulestore.inheritance import inheriting_field_data, InheritanceMixin +from xmodule.modulestore.inheritance import inheriting_field_data from xmodule.modulestore.split_mongo import BlockKey, CourseEnvelope from xmodule.modulestore.split_mongo.id_manager import SplitMongoIdManager from xmodule.modulestore.split_mongo.definition_lazy_loader import DefinitionLazyLoader diff --git a/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py b/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py index 3e1a393f52a..53c64984fd2 100644 --- a/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py +++ b/common/lib/xmodule/xmodule/modulestore/split_mongo/split.py @@ -77,13 +77,14 @@ from ccx_keys.locator import CCXLocator, CCXBlockUsageLocator from xmodule.modulestore.exceptions import InsufficientSpecificationError, VersionConflictError, DuplicateItemError, \ DuplicateCourseError, MultipleCourseBlocksFound from xmodule.modulestore import ( - inheritance, ModuleStoreWriteBase, ModuleStoreEnum, + ModuleStoreWriteBase, ModuleStoreEnum, BulkOpsRecord, BulkOperationsMixin, SortedAssetList, BlockData ) +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin +from openedx.core.lib.partitions.partitions_service import PartitionService from ..exceptions import ItemNotFoundError from .caching_descriptor_system import CachingDescriptorSystem -from xmodule.partitions.partitions_service import PartitionService from xmodule.modulestore.split_mongo.mongo_connection import MongoConnection, DuplicateKeyError from xmodule.modulestore.split_mongo import BlockKey, CourseEnvelope from xmodule.modulestore.store_utilities import DETACHED_XBLOCK_TYPES @@ -2149,7 +2150,7 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase): else: inherited_settings = parent_xblock.xblock_kvs.inherited_settings.copy() if fields is not None: - for field_name in inheritance.InheritanceMixin.fields: + for field_name in InheritanceMixin.fields: if field_name in fields: inherited_settings[field_name] = fields[field_name] @@ -2698,7 +2699,7 @@ class SplitMongoModuleStore(SplitBulkWriteMixin, ModuleStoreWriteBase): # update the inheriting w/ what should pass to children inheriting_settings = inherited_settings_map[block_key].copy() block_fields = block_data.fields - for field_name in inheritance.InheritanceMixin.fields: + for field_name in InheritanceMixin.fields: if field_name in block_fields: inheriting_settings[field_name] = block_fields[field_name] diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_cross_modulestore_import_export.py b/common/lib/xmodule/xmodule/modulestore/tests/test_cross_modulestore_import_export.py index 042198113fb..a8ca08ef29f 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_cross_modulestore_import_export.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_cross_modulestore_import_export.py @@ -22,11 +22,11 @@ import ddt from nose.plugins.attrib import attr from mock import patch +from openedx.core.lib.partitions.tests.test_partitions import PartitionTestCase from xmodule.tests import CourseComparisonTest from xmodule.modulestore.xml_importer import import_course_from_xml from xmodule.modulestore.xml_exporter import export_course_to_xml from xmodule.modulestore.tests.utils import mock_tab_from_json -from xmodule.partitions.tests.test_partitions import PartitionTestCase from xmodule.modulestore.tests.utils import ( MongoContentstoreBuilder, MODULESTORE_SETUPS, SPLIT_MODULESTORE_SETUP, CONTENTSTORE_SETUPS, TEST_DATA_DIR diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py index 59917387f51..0b916d85c4c 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mixed_modulestore.py @@ -23,9 +23,9 @@ from pytz import UTC from shutil import rmtree from tempfile import mkdtemp +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.x_module import XModuleMixin from xmodule.modulestore.edit_info import EditInfoMixin -from xmodule.modulestore.inheritance import InheritanceMixin from xmodule.modulestore.tests.utils import MongoContentstoreBuilder from xmodule.contentstore.content import StaticContent from xmodule.modulestore.xml_importer import import_course_from_xml diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py b/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py index 90b6fd395b2..ee7bad069ca 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_mongo.py @@ -4,8 +4,10 @@ Unit tests for the Mongo modulestore # pylint: disable=protected-access # pylint: disable=no-name-in-module # pylint: disable=bad-continuation -from nose.tools import assert_equals, assert_raises, \ +from nose.tools import ( + assert_equals, assert_raises, assert_in, assert_not_equals, assert_false, assert_true, assert_greater, assert_is_instance, assert_is_none +) # pylint: enable=E0611 from path import Path as path import pymongo @@ -17,35 +19,34 @@ from datetime import datetime from pytz import UTC import unittest from mock import patch -from xblock.core import XBlock +from git.test.lib.asserts import assert_not_none +from xblock.core import XBlock from xblock.fields import Scope, Reference, ReferenceList, ReferenceValueDict from xblock.runtime import KeyValueStore from xblock.exceptions import InvalidScopeError -from xmodule.tests import DATA_DIR from opaque_keys.edx.keys import CourseKey from opaque_keys.edx.locations import Location -from xmodule.modulestore import ModuleStoreEnum -from xmodule.modulestore.mongo import MongoKeyValueStore -from xmodule.modulestore.draft import DraftModuleStore from opaque_keys.edx.locations import SlashSeparatedCourseKey, AssetLocation from opaque_keys.edx.locator import LibraryLocator, CourseLocator from opaque_keys.edx.keys import UsageKey -from xmodule.modulestore.xml_exporter import export_course_to_xml -from xmodule.modulestore.xml_importer import import_course_from_xml, perform_xlint -from xmodule.contentstore.mongo import MongoContentStore -from nose.tools import assert_in +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.exceptions import NotFoundError -from git.test.lib.asserts import assert_not_none +from xmodule.tests import DATA_DIR from xmodule.x_module import XModuleMixin +from xmodule.contentstore.mongo import MongoContentStore +from xmodule.modulestore import ModuleStoreEnum +from xmodule.modulestore.draft import DraftModuleStore +from xmodule.modulestore.edit_info import EditInfoMixin +from xmodule.modulestore.exceptions import ItemNotFoundError +from xmodule.modulestore.mongo import MongoKeyValueStore from xmodule.modulestore.mongo.base import as_draft from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST from xmodule.modulestore.tests.utils import LocationMixin, mock_tab_from_json -from xmodule.modulestore.edit_info import EditInfoMixin -from xmodule.modulestore.exceptions import ItemNotFoundError -from xmodule.modulestore.inheritance import InheritanceMixin +from xmodule.modulestore.xml_exporter import export_course_to_xml +from xmodule.modulestore.xml_importer import import_course_from_xml, perform_xlint log = logging.getLogger(__name__) diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py b/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py index 42835c42223..bdaf3aa5ecf 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_split_modulestore.py @@ -15,27 +15,27 @@ from contracts import contract from nose.plugins.attrib import attr from django.core.cache import caches, InvalidCacheBackendError -from openedx.core.lib import tempdir +from opaque_keys.edx.locator import CourseKey, CourseLocator, BlockUsageLocator, VersionTree, LocalId +from ccx_keys.locator import CCXBlockUsageLocator from xblock.fields import Reference, ReferenceList, ReferenceValueDict +from openedx.core.lib import tempdir +from openedx.core.lib.xblock_fields.fields import Date, Timedelta +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.course_module import CourseDescriptor +from xmodule.x_module import XModuleMixin from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.exceptions import ( ItemNotFoundError, VersionConflictError, DuplicateItemError, DuplicateCourseError, InsufficientSpecificationError ) -from opaque_keys.edx.locator import CourseKey, CourseLocator, BlockUsageLocator, VersionTree, LocalId -from ccx_keys.locator import CCXBlockUsageLocator -from xmodule.modulestore.inheritance import InheritanceMixin -from xmodule.x_module import XModuleMixin -from xmodule.fields import Date, Timedelta -from xmodule.modulestore.split_mongo.split import SplitMongoModuleStore -from xmodule.modulestore.tests.test_modulestore import check_has_course_method +from xmodule.modulestore.edit_info import EditInfoMixin from xmodule.modulestore.split_mongo import BlockKey +from xmodule.modulestore.split_mongo.split import SplitMongoModuleStore from xmodule.modulestore.tests.factories import check_mongo_calls from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST +from xmodule.modulestore.tests.test_modulestore import check_has_course_method from xmodule.modulestore.tests.utils import mock_tab_from_json -from xmodule.modulestore.edit_info import EditInfoMixin BRANCH_NAME_DRAFT = ModuleStoreEnum.BranchName.draft diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_split_w_old_mongo.py b/common/lib/xmodule/xmodule/modulestore/tests/test_split_w_old_mongo.py index a9e92b12119..72816c81ee4 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_split_w_old_mongo.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_split_w_old_mongo.py @@ -7,13 +7,13 @@ from nose.plugins.attrib import attr import mock from opaque_keys.edx.locator import CourseLocator, BlockUsageLocator +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.modulestore import ModuleStoreEnum -from xmodule.x_module import XModuleMixin -from xmodule.modulestore.inheritance import InheritanceMixin from xmodule.modulestore.mongo import DraftMongoModuleStore from xmodule.modulestore.split_mongo.split import SplitMongoModuleStore from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST from xmodule.modulestore.tests.utils import MemoryCache +from xmodule.x_module import XModuleMixin @attr('mongo') diff --git a/common/lib/xmodule/xmodule/modulestore/tests/test_xml_importer.py b/common/lib/xmodule/xmodule/modulestore/tests/test_xml_importer.py index 6cc5913374f..f056f2f9f62 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/test_xml_importer.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/test_xml_importer.py @@ -1,21 +1,22 @@ """ Tests for XML importer. """ +from uuid import uuid4 +import unittest +import importlib import mock + from opaque_keys.edx.locator import BlockUsageLocator, CourseLocator +from opaque_keys.edx.locations import Location, SlashSeparatedCourseKey from xblock.fields import String, Scope, ScopeIds, List from xblock.runtime import Runtime, KvsFieldData, DictKeyValueStore -from xmodule.x_module import XModuleMixin -from opaque_keys.edx.locations import Location + +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.modulestore import ModuleStoreEnum -from xmodule.modulestore.inheritance import InheritanceMixin from xmodule.modulestore.xml_importer import _update_and_import_module, _update_module_location from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST -from opaque_keys.edx.locations import SlashSeparatedCourseKey from xmodule.tests import DATA_DIR -from uuid import uuid4 -import unittest -import importlib +from xmodule.x_module import XModuleMixin class ModuleStoreNoSettings(unittest.TestCase): diff --git a/common/lib/xmodule/xmodule/modulestore/tests/utils.py b/common/lib/xmodule/xmodule/modulestore/tests/utils.py index e9666423c72..913afd9d669 100644 --- a/common/lib/xmodule/xmodule/modulestore/tests/utils.py +++ b/common/lib/xmodule/xmodule/modulestore/tests/utils.py @@ -12,12 +12,11 @@ from tempfile import mkdtemp from unittest import TestCase from xblock.fields import XBlockMixin -from xmodule.x_module import XModuleMixin +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.contentstore.mongo import MongoContentStore from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.draft_and_published import ModuleStoreDraftAndPublished from xmodule.modulestore.edit_info import EditInfoMixin -from xmodule.modulestore.inheritance import InheritanceMixin from xmodule.modulestore.mixed import MixedModuleStore from xmodule.modulestore.mongo.base import ModuleStoreEnum from xmodule.modulestore.mongo.draft import DraftModuleStore @@ -26,6 +25,7 @@ from xmodule.modulestore.tests.factories import ItemFactory from xmodule.modulestore.tests.mongo_connection import MONGO_PORT_NUM, MONGO_HOST from xmodule.modulestore.xml import XMLModuleStore from xmodule.tests import DATA_DIR +from xmodule.x_module import XModuleMixin def load_function(path): diff --git a/common/lib/xmodule/xmodule/seq_module.py b/common/lib/xmodule/xmodule/seq_module.py index ecda5cc4503..c79dc7c1238 100644 --- a/common/lib/xmodule/xmodule/seq_module.py +++ b/common/lib/xmodule/xmodule/seq_module.py @@ -9,14 +9,14 @@ from django.utils.timezone import UTC import json import logging from pkg_resources import resource_string - from lxml import etree + from xblock.core import XBlock from xblock.fields import Integer, Scope, Boolean, String from xblock.fragment import Fragment +from openedx.core.lib.xblock_fields.fields import Date from .exceptions import NotFoundError -from .fields import Date from .mako_module import MakoModuleDescriptor from .progress import Progress from .x_module import XModule, STUDENT_VIEW diff --git a/common/lib/xmodule/xmodule/split_test_module.py b/common/lib/xmodule/xmodule/split_test_module.py index 58aebaa7f51..5ea218264d8 100644 --- a/common/lib/xmodule/xmodule/split_test_module.py +++ b/common/lib/xmodule/xmodule/split_test_module.py @@ -7,19 +7,19 @@ import json from webob import Response from uuid import uuid4 from operator import itemgetter +from lxml import etree + +from xblock.core import XBlock +from xblock.fields import Scope, Integer, String, ReferenceValueDict +from xblock.fragment import Fragment +from openedx.core.lib.xblock_fields.inherited_fields import UserPartitionList from xmodule.progress import Progress from xmodule.seq_module import SequenceDescriptor from xmodule.studio_editable import StudioEditableModule, StudioEditableDescriptor -from xmodule.x_module import XModule, module_attr, STUDENT_VIEW from xmodule.validation import StudioValidation, StudioValidationMessage -from xmodule.modulestore.inheritance import UserPartitionList - -from lxml import etree +from xmodule.x_module import XModule, module_attr, STUDENT_VIEW -from xblock.core import XBlock -from xblock.fields import Scope, Integer, String, ReferenceValueDict -from xblock.fragment import Fragment log = logging.getLogger('edx.' + __name__) diff --git a/common/lib/xmodule/xmodule/tests/__init__.py b/common/lib/xmodule/xmodule/tests/__init__.py index 498e145479c..e34e2709149 100644 --- a/common/lib/xmodule/xmodule/tests/__init__.py +++ b/common/lib/xmodule/xmodule/tests/__init__.py @@ -25,12 +25,13 @@ from path import Path as path from opaque_keys.edx.locations import SlashSeparatedCourseKey from xblock.field_data import DictFieldData from xblock.fields import ScopeIds, Scope, Reference, ReferenceList, ReferenceValueDict +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.assetstore import AssetMetadata from xmodule.error_module import ErrorDescriptor from xmodule.mako_module import MakoDescriptorSystem from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.draft_and_published import DIRECT_ONLY_CATEGORIES, ModuleStoreDraftAndPublished -from xmodule.modulestore.inheritance import InheritanceMixin, own_metadata +from xmodule.modulestore.inheritance import own_metadata from xmodule.modulestore.mongo.draft import DraftModuleStore from xmodule.modulestore.xml import CourseLocationManager from xmodule.x_module import ModuleSystem, XModuleDescriptor, XModuleMixin diff --git a/common/lib/xmodule/xmodule/tests/test_course_metadata_utils.py b/common/lib/xmodule/xmodule/tests/test_course_metadata_utils.py index 06014a9bd71..3074fea4f2b 100644 --- a/common/lib/xmodule/xmodule/tests/test_course_metadata_utils.py +++ b/common/lib/xmodule/xmodule/tests/test_course_metadata_utils.py @@ -6,6 +6,7 @@ from datetime import timedelta, datetime from unittest import TestCase from pytz import utc +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from xmodule.block_metadata_utils import ( url_name_for_block, display_name_with_default, @@ -16,7 +17,6 @@ from xmodule.course_metadata_utils import ( number_for_course_location, has_course_started, has_course_ended, - DEFAULT_START_DATE, course_start_date_is_default, may_certify_for_course, ) diff --git a/common/lib/xmodule/xmodule/tests/test_fields.py b/common/lib/xmodule/xmodule/tests/test_fields.py index 4464470eab9..7d1de0bce2d 100644 --- a/common/lib/xmodule/xmodule/tests/test_fields.py +++ b/common/lib/xmodule/xmodule/tests/test_fields.py @@ -5,8 +5,7 @@ import unittest from django.utils.timezone import UTC -from xmodule.fields import Date, Timedelta, RelativeTime -from xmodule.timeinfo import TimeInfo +from openedx.core.lib.xblock_fields.fields import Date, Timedelta, RelativeTime, TimeInfo class DateTest(unittest.TestCase): diff --git a/common/lib/xmodule/xmodule/tests/test_import.py b/common/lib/xmodule/xmodule/tests/test_import.py index f557d7959ae..e17f1459af4 100644 --- a/common/lib/xmodule/xmodule/tests/test_import.py +++ b/common/lib/xmodule/xmodule/tests/test_import.py @@ -10,20 +10,20 @@ from mock import Mock, patch from django.utils.timezone import UTC -from xmodule.xml_module import is_pointer_tag +from xblock.core import XBlock +from xblock.fields import Scope, String, Integer +from xblock.runtime import KvsFieldData, DictKeyValueStore + from opaque_keys.edx.locations import Location +from opaque_keys.edx.locations import SlashSeparatedCourseKey +from openedx.core.lib.xblock_fields.fields import Date +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.modulestore import only_xmodules from xmodule.modulestore.xml import ImportSystem, XMLModuleStore, LibraryXMLModuleStore from xmodule.modulestore.inheritance import compute_inherited_metadata -from xmodule.x_module import XModuleMixin -from xmodule.fields import Date from xmodule.tests import DATA_DIR -from xmodule.modulestore.inheritance import InheritanceMixin -from opaque_keys.edx.locations import SlashSeparatedCourseKey - -from xblock.core import XBlock -from xblock.fields import Scope, String, Integer -from xblock.runtime import KvsFieldData, DictKeyValueStore +from xmodule.x_module import XModuleMixin +from xmodule.xml_module import is_pointer_tag ORG = 'test_org' diff --git a/common/lib/xmodule/xmodule/tests/test_lti_unit.py b/common/lib/xmodule/xmodule/tests/test_lti_unit.py index ce83fed6031..65114d4a989 100644 --- a/common/lib/xmodule/xmodule/tests/test_lti_unit.py +++ b/common/lib/xmodule/xmodule/tests/test_lti_unit.py @@ -10,7 +10,7 @@ from webob.request import Request from copy import copy import urllib -from xmodule.fields import Timedelta +from openedx.core.lib.xblock_fields.fields import Timedelta from xmodule.lti_module import LTIDescriptor from xmodule.lti_2_util import LTIError diff --git a/common/lib/xmodule/xmodule/tests/test_split_test_module.py b/common/lib/xmodule/xmodule/tests/test_split_test_module.py index ba23497d85b..bfe6262b88d 100644 --- a/common/lib/xmodule/xmodule/tests/test_split_test_module.py +++ b/common/lib/xmodule/xmodule/tests/test_split_test_module.py @@ -6,14 +6,14 @@ import lxml from mock import Mock, patch from fs.memoryfs import MemoryFS -from xmodule.partitions.tests.test_partitions import MockPartitionService, PartitionTestCase, MockUserPartitionScheme +from openedx.core.lib.partitions.tests.test_partitions import MockPartitionService, PartitionTestCase, MockUserPartitionScheme +from openedx.core.lib.partitions.partitions import Group, UserPartition, MINIMUM_STATIC_PARTITION_ID +from xmodule.split_test_module import SplitTestDescriptor, SplitTestFields, get_split_user_partitions from xmodule.tests.xml import factories as xml from xmodule.tests.xml import XModuleXmlImportTest from xmodule.tests import get_test_system -from xmodule.x_module import AUTHOR_VIEW, STUDENT_VIEW from xmodule.validation import StudioValidationMessage -from xmodule.split_test_module import SplitTestDescriptor, SplitTestFields, get_split_user_partitions -from xmodule.partitions.partitions import Group, UserPartition, MINIMUM_STATIC_PARTITION_ID +from xmodule.x_module import AUTHOR_VIEW, STUDENT_VIEW class SplitTestModuleFactory(xml.XmlImportFactory): diff --git a/common/lib/xmodule/xmodule/tests/test_xml_module.py b/common/lib/xmodule/xmodule/tests/test_xml_module.py index 290d5b1000f..55081a26610 100644 --- a/common/lib/xmodule/xmodule/tests/test_xml_module.py +++ b/common/lib/xmodule/xmodule/tests/test_xml_module.py @@ -11,13 +11,14 @@ from xblock.field_data import DictFieldData from xblock.fields import Scope, String, Dict, Boolean, Integer, Float, Any, List from xblock.runtime import KvsFieldData, DictKeyValueStore -from xmodule.fields import Date, Timedelta, RelativeTime -from xmodule.modulestore.inheritance import InheritanceKeyValueStore, InheritanceMixin, InheritingFieldData +from openedx.core.lib.xblock_fields.fields import Date, Timedelta, RelativeTime +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin +from xmodule.modulestore.inheritance import InheritanceKeyValueStore, InheritingFieldData from xmodule.modulestore.split_mongo.split_mongo_kvs import SplitMongoKVS -from xmodule.xml_module import XmlDescriptor, serialize_field, deserialize_field from xmodule.course_module import CourseDescriptor from xmodule.seq_module import SequenceDescriptor from xmodule.x_module import XModuleMixin +from xmodule.xml_module import XmlDescriptor, serialize_field, deserialize_field from xmodule.tests import get_test_descriptor_system from xmodule.tests.xml import XModuleXmlImportTest diff --git a/common/lib/xmodule/xmodule/tests/xml/factories.py b/common/lib/xmodule/xmodule/tests/xml/factories.py index 903f2d925ea..20e798d46d1 100644 --- a/common/lib/xmodule/xmodule/tests/xml/factories.py +++ b/common/lib/xmodule/xmodule/tests/xml/factories.py @@ -9,7 +9,7 @@ from factory import Factory, lazy_attribute, post_generation, Sequence from lxml import etree from xblock.mixins import HierarchyMixin -from xmodule.modulestore.inheritance import InheritanceMixin +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.x_module import XModuleMixin from xmodule.modulestore import only_xmodules diff --git a/common/lib/xmodule/xmodule/timeinfo.py b/common/lib/xmodule/xmodule/timeinfo.py deleted file mode 100644 index 17ac38de52f..00000000000 --- a/common/lib/xmodule/xmodule/timeinfo.py +++ /dev/null @@ -1,38 +0,0 @@ -import logging -from xmodule.fields import Timedelta -log = logging.getLogger(__name__) - - -class TimeInfo(object): - """ - This is a simple object that calculates and stores datetime information for an XModule - based on the due date and the grace period string - - So far it parses out three different pieces of time information: - self.display_due_date - the 'official' due date that gets displayed to students - self.grace_period - the length of the grace period - self.close_date - the real due date - - """ - _delta_standin = Timedelta() - - def __init__(self, due_date, grace_period_string_or_timedelta): - if due_date is not None: - self.display_due_date = due_date - - else: - self.display_due_date = None - - if grace_period_string_or_timedelta is not None and self.display_due_date: - if isinstance(grace_period_string_or_timedelta, basestring): - try: - self.grace_period = TimeInfo._delta_standin.from_json(grace_period_string_or_timedelta) - except: - log.error("Error parsing the grace period {0}".format(grace_period_string_or_timedelta)) - raise - else: - self.grace_period = grace_period_string_or_timedelta - self.close_date = self.display_due_date + self.grace_period - else: - self.grace_period = None - self.close_date = self.display_due_date diff --git a/common/lib/xmodule/xmodule/video_module/video_handlers.py b/common/lib/xmodule/xmodule/video_module/video_handlers.py index be70ef0a757..737b761d9d2 100644 --- a/common/lib/xmodule/xmodule/video_module/video_handlers.py +++ b/common/lib/xmodule/xmodule/video_module/video_handlers.py @@ -10,11 +10,11 @@ import logging from datetime import datetime from webob import Response +from opaque_keys.edx.locator import CourseLocator from xblock.core import XBlock +from openedx.core.lib.xblock_fields.fields import RelativeTime from xmodule.exceptions import NotFoundError -from xmodule.fields import RelativeTime -from opaque_keys.edx.locator import CourseLocator from .transcripts_utils import ( get_or_create_sjson, diff --git a/common/lib/xmodule/xmodule/video_module/video_xfields.py b/common/lib/xmodule/xmodule/video_module/video_xfields.py index cec00363918..a46cea38e34 100644 --- a/common/lib/xmodule/xmodule/video_module/video_xfields.py +++ b/common/lib/xmodule/xmodule/video_module/video_xfields.py @@ -4,7 +4,7 @@ XFields for video module. import datetime from xblock.fields import Scope, String, Float, Boolean, List, Dict, DateTime -from xmodule.fields import RelativeTime +from openedx.core.lib.xblock_fields.fields import RelativeTime # 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 diff --git a/common/lib/xmodule/xmodule/x_module.py b/common/lib/xmodule/xmodule/x_module.py index 7e707f48848..a246fd49f68 100644 --- a/common/lib/xmodule/xmodule/x_module.py +++ b/common/lib/xmodule/xmodule/x_module.py @@ -27,14 +27,14 @@ from xblock.fields import ( from xblock.fragment import Fragment from xblock.runtime import Runtime, IdReader, IdGenerator +from opaque_keys.edx.keys import UsageKey +from opaque_keys.edx.asides import AsideUsageKeyV2, AsideDefinitionKeyV2 +from openedx.core.lib.xblock_fields.fields import RelativeTime from xmodule import block_metadata_utils -from xmodule.fields import RelativeTime from xmodule.errortracker import exc_info_to_str +from xmodule.exceptions import UndefinedContext from xmodule.modulestore.exceptions import ItemNotFoundError -from opaque_keys.edx.keys import UsageKey -from opaque_keys.edx.asides import AsideUsageKeyV2, AsideDefinitionKeyV2 -from xmodule.exceptions import UndefinedContext import dogstats_wrapper as dog_stats_api log = logging.getLogger(__name__) diff --git a/common/test/acceptance/tests/discussion/test_cohort_management.py b/common/test/acceptance/tests/discussion/test_cohort_management.py index 5d0319ea901..2df8d1a9071 100644 --- a/common/test/acceptance/tests/discussion/test_cohort_management.py +++ b/common/test/acceptance/tests/discussion/test_cohort_management.py @@ -4,21 +4,20 @@ End-to-end tests related to the cohort management on the LMS Instructor Dashboar """ from datetime import datetime - +import os +import unicodecsv +import uuid from pytz import UTC, utc from bok_choy.promise import EmptyPromise from nose.plugins.attrib import attr + from common.test.acceptance.tests.discussion.helpers import CohortTestMixin from common.test.acceptance.tests.helpers import UniqueCourseTest, EventsTestMixin, create_user_partition_json -from xmodule.partitions.partitions import Group from common.test.acceptance.fixtures.course import CourseFixture, XBlockFixtureDesc from common.test.acceptance.pages.lms.auto_auth import AutoAuthPage from common.test.acceptance.pages.lms.instructor_dashboard import InstructorDashboardPage, DataDownloadPage from common.test.acceptance.pages.studio.settings_group_configurations import GroupConfigurationsPage - -import os -import unicodecsv -import uuid +from openedx.core.lib.partitions.partitions import Group @attr(shard=8) diff --git a/common/test/acceptance/tests/helpers.py b/common/test/acceptance/tests/helpers.py index da988ec6a37..bb8f193e135 100644 --- a/common/test/acceptance/tests/helpers.py +++ b/common/test/acceptance/tests/helpers.py @@ -14,29 +14,27 @@ import urlparse from contextlib import contextmanager from datetime import datetime from path import Path as path +from pymongo import MongoClient, ASCENDING +from unittest import TestCase from bok_choy.javascript import js_defined from bok_choy.web_app_test import WebAppTest from bok_choy.promise import EmptyPromise, Promise from bok_choy.page_object import XSS_INJECTION from capa.tests.response_xml_factory import MultipleChoiceResponseXMLFactory -from common.test.acceptance.pages.studio.auto_auth import AutoAuthPage from common.test.acceptance.fixtures.course import XBlockFixtureDesc +from common.test.acceptance.pages.studio.auto_auth import AutoAuthPage +from common.test.acceptance.pages.common import BASE_URL from opaque_keys.edx.locator import CourseLocator -from pymongo import MongoClient, ASCENDING from openedx.core.lib.tests.assertions.events import assert_event_matches, is_matching_event, EventMatchTolerates -from xmodule.partitions.partitions import UserPartition +from openedx.core.lib.partitions.partitions import UserPartition +from openedx.core.release import doc_version, RELEASE_LINE from selenium.common.exceptions import StaleElementReferenceException from selenium.webdriver.common.desired_capabilities import DesiredCapabilities from selenium.webdriver.common.keys import Keys from selenium.webdriver.support.select import Select from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC -from unittest import TestCase - -from openedx.core.release import doc_version, RELEASE_LINE - -from common.test.acceptance.pages.common import BASE_URL MAX_EVENTS_IN_FAILURE_OUTPUT = 20 diff --git a/common/test/acceptance/tests/lms/test_lms_split_test_courseware_search.py b/common/test/acceptance/tests/lms/test_lms_split_test_courseware_search.py index 265f2874a0e..ca04c75b91e 100644 --- a/common/test/acceptance/tests/lms/test_lms_split_test_courseware_search.py +++ b/common/test/acceptance/tests/lms/test_lms_split_test_courseware_search.py @@ -11,7 +11,7 @@ from common.test.acceptance.pages.lms.courseware_search import CoursewareSearchP from common.test.acceptance.fixtures.course import XBlockFixtureDesc from common.test.acceptance.tests.helpers import create_user_partition_json -from xmodule.partitions.partitions import Group +from openedx.core.lib.partitions.partitions import Group from nose.plugins.attrib import attr diff --git a/common/test/acceptance/tests/lms/test_lms_user_preview.py b/common/test/acceptance/tests/lms/test_lms_user_preview.py index e7ad6484eee..91e8869e7e2 100644 --- a/common/test/acceptance/tests/lms/test_lms_user_preview.py +++ b/common/test/acceptance/tests/lms/test_lms_user_preview.py @@ -4,6 +4,8 @@ Tests the "preview" selector in the LMS that allows changing between Staff, Lear """ +from bok_choy.promise import EmptyPromise +from textwrap import dedent from nose.plugins.attrib import attr from common.test.acceptance.tests.helpers import UniqueCourseTest, create_user_partition_json @@ -12,9 +14,7 @@ from common.test.acceptance.pages.lms.courseware import CoursewarePage from common.test.acceptance.pages.lms.instructor_dashboard import InstructorDashboardPage from common.test.acceptance.pages.lms.staff_view import StaffCoursewarePage from common.test.acceptance.fixtures.course import CourseFixture, XBlockFixtureDesc -from bok_choy.promise import EmptyPromise -from xmodule.partitions.partitions import (Group, ENROLLMENT_TRACK_PARTITION_ID, MINIMUM_STATIC_PARTITION_ID) -from textwrap import dedent +from openedx.core.lib.partitions.partitions import Group, ENROLLMENT_TRACK_PARTITION_ID, MINIMUM_STATIC_PARTITION_ID @attr(shard=10) diff --git a/common/test/acceptance/tests/studio/test_studio_container.py b/common/test/acceptance/tests/studio/test_studio_container.py index 8ba505561e9..1e672fdec53 100644 --- a/common/test/acceptance/tests/studio/test_studio_container.py +++ b/common/test/acceptance/tests/studio/test_studio_container.py @@ -21,7 +21,7 @@ from common.test.acceptance.pages.lms.courseware import CoursewarePage from common.test.acceptance.pages.lms.staff_view import StaffCoursewarePage from common.test.acceptance.tests.helpers import create_user_partition_json -from xmodule.partitions.partitions import ( +from openedx.core.lib.partitions.partitions import ( Group, ENROLLMENT_TRACK_PARTITION_ID, MINIMUM_STATIC_PARTITION_ID ) diff --git a/common/test/acceptance/tests/studio/test_studio_settings.py b/common/test/acceptance/tests/studio/test_studio_settings.py index e329c36e9c2..33769f2bdd7 100644 --- a/common/test/acceptance/tests/studio/test_studio_settings.py +++ b/common/test/acceptance/tests/studio/test_studio_settings.py @@ -7,6 +7,7 @@ import os from mock import patch from nose.plugins.attrib import attr +from textwrap import dedent from base_studio_test import StudioCourseTest from bok_choy.promise import EmptyPromise @@ -19,9 +20,7 @@ from common.test.acceptance.pages.studio.settings_group_configurations import Gr from common.test.acceptance.pages.lms.courseware import CoursewarePage from common.test.acceptance.pages.studio.utils import get_input_value from common.test.acceptance.pages.common.utils import add_enrollment_course_modes - -from textwrap import dedent -from xmodule.partitions.partitions import Group +from openedx.core.lib.partitions.partitions import Group @attr(shard=8) diff --git a/common/test/acceptance/tests/studio/test_studio_split_test.py b/common/test/acceptance/tests/studio/test_studio_split_test.py index 9bc0c4d90bb..6d844fb1e24 100644 --- a/common/test/acceptance/tests/studio/test_studio_split_test.py +++ b/common/test/acceptance/tests/studio/test_studio_split_test.py @@ -7,7 +7,6 @@ from unittest import skip from nose.plugins.attrib import attr from selenium.webdriver.support.ui import Select -from xmodule.partitions.partitions import Group from bok_choy.promise import Promise, EmptyPromise from common.test.acceptance.fixtures.course import XBlockFixtureDesc @@ -19,6 +18,7 @@ from common.test.acceptance.pages.studio.utils import add_advanced_component from common.test.acceptance.pages.xblock.utils import wait_for_xblock_initialization from common.test.acceptance.pages.lms.courseware import CoursewarePage from common.test.acceptance.tests.helpers import create_user_partition_json +from openedx.core.lib.partitions.partitions import Group from base_studio_test import StudioCourseTest diff --git a/lms/djangoapps/course_api/tests/test_serializers.py b/lms/djangoapps/course_api/tests/test_serializers.py index b1d1e76bb6a..b6e850a954c 100644 --- a/lms/djangoapps/course_api/tests/test_serializers.py +++ b/lms/djangoapps/course_api/tests/test_serializers.py @@ -9,11 +9,11 @@ import ddt from nose.plugins.attrib import attr from openedx.core.djangoapps.models.course_details import CourseDetails from openedx.core.djangoapps.content.course_overviews.models import CourseOverview +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from rest_framework.test import APIRequestFactory from rest_framework.request import Request from xblock.core import XBlock -from xmodule.course_module import DEFAULT_START_DATE from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import check_mongo_calls diff --git a/lms/djangoapps/course_blocks/transformers/start_date.py b/lms/djangoapps/course_blocks/transformers/start_date.py index 561d3c31532..40e7cdd125f 100644 --- a/lms/djangoapps/course_blocks/transformers/start_date.py +++ b/lms/djangoapps/course_blocks/transformers/start_date.py @@ -6,7 +6,7 @@ from openedx.core.djangoapps.content.block_structure.transformer import ( FilteringTransformerMixin, ) from lms.djangoapps.courseware.access_utils import check_start_date -from xmodule.course_metadata_utils import DEFAULT_START_DATE +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from .utils import collect_merged_date_field diff --git a/lms/djangoapps/course_blocks/transformers/tests/test_split_test.py b/lms/djangoapps/course_blocks/transformers/tests/test_split_test.py index f5110868f5a..8fa6aef8991 100644 --- a/lms/djangoapps/course_blocks/transformers/tests/test_split_test.py +++ b/lms/djangoapps/course_blocks/transformers/tests/test_split_test.py @@ -6,8 +6,8 @@ from nose.plugins.attrib import attr import openedx.core.djangoapps.user_api.course_tag.api as course_tag_api from openedx.core.djangoapps.user_api.partition_schemes import RandomUserPartitionScheme +from openedx.core.lib.partitions.partitions import Group, UserPartition from student.tests.factories import CourseEnrollmentFactory -from xmodule.partitions.partitions import Group, UserPartition from xmodule.modulestore.tests.factories import check_mongo_calls from ...api import get_course_blocks diff --git a/lms/djangoapps/course_blocks/transformers/tests/test_user_partitions.py b/lms/djangoapps/course_blocks/transformers/tests/test_user_partitions.py index 2d51078a3b2..a203a1a9b86 100644 --- a/lms/djangoapps/course_blocks/transformers/tests/test_user_partitions.py +++ b/lms/djangoapps/course_blocks/transformers/tests/test_user_partitions.py @@ -11,8 +11,8 @@ from openedx.core.djangoapps.course_groups.partition_scheme import CohortPartiti from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory, config_course_cohorts from openedx.core.djangoapps.course_groups.cohorts import add_user_to_cohort from openedx.core.djangoapps.course_groups.views import link_cohort_to_partition_group +from openedx.core.lib.partitions.partitions import Group, UserPartition from student.tests.factories import CourseEnrollmentFactory -from xmodule.partitions.partitions import Group, UserPartition from xmodule.modulestore.tests.factories import CourseFactory from ...api import get_course_blocks diff --git a/lms/djangoapps/course_blocks/transformers/user_partitions.py b/lms/djangoapps/course_blocks/transformers/user_partitions.py index a01cdf3b54a..8a62908281f 100644 --- a/lms/djangoapps/course_blocks/transformers/user_partitions.py +++ b/lms/djangoapps/course_blocks/transformers/user_partitions.py @@ -5,7 +5,7 @@ from openedx.core.djangoapps.content.block_structure.transformer import ( BlockStructureTransformer, FilteringTransformerMixin, ) -from xmodule.partitions.partitions_service import get_all_partitions_for_course +from openedx.core.lib.partitions.partitions_service import get_all_partitions_for_course from .split_test import SplitTestTransformer from .utils import get_field_on_block diff --git a/lms/djangoapps/courseware/access.py b/lms/djangoapps/courseware/access.py index c60368fe1da..785160a8a13 100644 --- a/lms/djangoapps/courseware/access.py +++ b/lms/djangoapps/courseware/access.py @@ -30,7 +30,9 @@ from xmodule.course_module import ( ) from xmodule.error_module import ErrorDescriptor from xmodule.x_module import XModule -from xmodule.partitions.partitions import NoSuchUserPartitionError, NoSuchUserPartitionGroupError +from openedx.core.lib.partitions.partitions import NoSuchUserPartitionError, NoSuchUserPartitionGroupError +from openedx.core.djangoapps.content.course_overviews.models import CourseOverview +from openedx.core.djangoapps.external_auth.models import ExternalAuthMap from courseware.access_response import ( MilestoneError, @@ -49,8 +51,6 @@ from courseware.masquerade import get_masquerade_role, is_masquerading_as_studen from lms.djangoapps.ccx.custom_exception import CCXLocatorValidationException from lms.djangoapps.ccx.models import CustomCourseForEdX from mobile_api.models import IgnoreMobileAvailableFlagConfig -from openedx.core.djangoapps.content.course_overviews.models import CourseOverview -from openedx.core.djangoapps.external_auth.models import ExternalAuthMap from student import auth from student.models import CourseEnrollmentAllowed from student.roles import ( diff --git a/lms/djangoapps/courseware/access_response.py b/lms/djangoapps/courseware/access_response.py index 976571cf241..75c86547d1a 100644 --- a/lms/djangoapps/courseware/access_response.py +++ b/lms/djangoapps/courseware/access_response.py @@ -3,7 +3,7 @@ This file contains all the classes used by has_access for error handling """ from django.utils.translation import ugettext as _ -from xmodule.course_metadata_utils import DEFAULT_START_DATE +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE class AccessResponse(object): diff --git a/lms/djangoapps/courseware/field_overrides.py b/lms/djangoapps/courseware/field_overrides.py index 02417d95157..59df70e9332 100644 --- a/lms/djangoapps/courseware/field_overrides.py +++ b/lms/djangoapps/courseware/field_overrides.py @@ -22,7 +22,7 @@ from django.conf import settings from xblock.field_data import FieldData from request_cache.middleware import RequestCache -from xmodule.modulestore.inheritance import InheritanceMixin +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin NOTSET = object() diff --git a/lms/djangoapps/courseware/masquerade.py b/lms/djangoapps/courseware/masquerade.py index 5cfeac5c109..caf9f00c94b 100644 --- a/lms/djangoapps/courseware/masquerade.py +++ b/lms/djangoapps/courseware/masquerade.py @@ -17,7 +17,7 @@ from util.json_request import expect_json, JsonResponse from opaque_keys.edx.keys import CourseKey from xblock.fragment import Fragment from xblock.runtime import KeyValueStore -from xmodule.partitions.partitions import NoSuchUserPartitionGroupError +from openedx.core.lib.partitions.partitions import NoSuchUserPartitionGroupError log = logging.getLogger(__name__) diff --git a/lms/djangoapps/courseware/tests/test_access.py b/lms/djangoapps/courseware/tests/test_access.py index f509c9f6feb..a824681837e 100644 --- a/lms/djangoapps/courseware/tests/test_access.py +++ b/lms/djangoapps/courseware/tests/test_access.py @@ -29,6 +29,7 @@ from courseware.tests.factories import ( ) from courseware.tests.helpers import LoginEnrollmentTestCase, masquerade_as_group_member from openedx.core.djangoapps.content.course_overviews.models import CourseOverview +from openedx.core.lib.partitions.partitions import Group, UserPartition, MINIMUM_STATIC_PARTITION_ID from student.models import CourseEnrollment from student.roles import CourseCcxCoachRole, CourseStaffRole from student.tests.factories import ( @@ -44,7 +45,6 @@ from xmodule.course_module import ( CATALOG_VISIBILITY_NONE, ) from xmodule.error_module import ErrorDescriptor -from xmodule.partitions.partitions import Group, UserPartition, MINIMUM_STATIC_PARTITION_ID from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.django import modulestore from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory diff --git a/lms/djangoapps/courseware/tests/test_group_access.py b/lms/djangoapps/courseware/tests/test_group_access.py index a762e4d88bb..6890749bd34 100644 --- a/lms/djangoapps/courseware/tests/test_group_access.py +++ b/lms/djangoapps/courseware/tests/test_group_access.py @@ -7,9 +7,9 @@ import ddt from nose.plugins.attrib import attr from stevedore.extension import Extension, ExtensionManager +from openedx.core.lib.partitions.partitions import Group, UserPartition, USER_PARTITION_SCHEME_NAMESPACE from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from xmodule.partitions.partitions import Group, UserPartition, USER_PARTITION_SCHEME_NAMESPACE from xmodule.modulestore.django import modulestore import courseware.access as access diff --git a/lms/djangoapps/courseware/tests/test_masquerade.py b/lms/djangoapps/courseware/tests/test_masquerade.py index 64f175cf0d2..9f309f67aff 100644 --- a/lms/djangoapps/courseware/tests/test_masquerade.py +++ b/lms/djangoapps/courseware/tests/test_masquerade.py @@ -27,7 +27,7 @@ from xblock.runtime import DictKeyValueStore from xmodule.modulestore.django import modulestore from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import ItemFactory, CourseFactory -from xmodule.partitions.partitions import Group, UserPartition +from openedx.core.lib.partitions.partitions import Group, UserPartition from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration diff --git a/lms/djangoapps/courseware/tests/test_split_module.py b/lms/djangoapps/courseware/tests/test_split_module.py index c7aa323170d..d4216288142 100644 --- a/lms/djangoapps/courseware/tests/test_split_module.py +++ b/lms/djangoapps/courseware/tests/test_split_module.py @@ -10,7 +10,7 @@ from courseware.model_data import FieldDataCache from student.tests.factories import UserFactory, CourseEnrollmentFactory from xmodule.modulestore.tests.factories import ItemFactory, CourseFactory from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase -from xmodule.partitions.partitions import Group, UserPartition +from openedx.core.lib.partitions.partitions import Group, UserPartition from openedx.core.djangoapps.user_api.tests.factories import UserCourseTagFactory diff --git a/lms/djangoapps/courseware/tests/test_submitting_problems.py b/lms/djangoapps/courseware/tests/test_submitting_problems.py index 2532e67d551..6d8efe62248 100644 --- a/lms/djangoapps/courseware/tests/test_submitting_problems.py +++ b/lms/djangoapps/courseware/tests/test_submitting_problems.py @@ -33,11 +33,11 @@ from openedx.core.djangoapps.credit.api import ( from openedx.core.djangoapps.credit.models import CreditCourse, CreditProvider from openedx.core.djangoapps.user_api.tests.factories import UserCourseTagFactory from openedx.core.lib.url_utils import quote_slashes +from openedx.core.lib.partitions.partitions import Group, UserPartition from student.models import anonymous_id_for_user, CourseEnrollment from submissions import api as submissions_api from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from xmodule.partitions.partitions import Group, UserPartition class ProblemSubmissionTestMixin(TestCase): diff --git a/lms/djangoapps/discussion_api/tests/test_api.py b/lms/djangoapps/discussion_api/tests/test_api.py index 32b818906d0..5bc28ac2769 100644 --- a/lms/djangoapps/discussion_api/tests/test_api.py +++ b/lms/djangoapps/discussion_api/tests/test_api.py @@ -53,12 +53,12 @@ from django_comment_client.tests.utils import ForumsEnableMixin from openedx.core.djangoapps.course_groups.models import CourseUserGroupPartitionGroup from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory from openedx.core.lib.exceptions import CourseNotFoundError, PageNotFoundError +from openedx.core.lib.partitions.partitions import Group, UserPartition from student.tests.factories import CourseEnrollmentFactory, UserFactory from util.testing import UrlResetMixin from xmodule.modulestore.django import modulestore from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from xmodule.partitions.partitions import Group, UserPartition def _remove_discussion_tab(course, user_id): diff --git a/lms/djangoapps/instructor/tests/test_api.py b/lms/djangoapps/instructor/tests/test_api.py index b06a99bd7db..d8e3cdc8ac5 100644 --- a/lms/djangoapps/instructor/tests/test_api.py +++ b/lms/djangoapps/instructor/tests/test_api.py @@ -54,7 +54,6 @@ from student.tests.factories import UserFactory, CourseModeFactory, AdminFactory from student.roles import CourseBetaTesterRole, CourseSalesAdminRole, CourseFinanceAdminRole, CourseInstructorRole from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase, ModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from xmodule.fields import Date from courseware.models import StudentFieldOverride @@ -68,6 +67,7 @@ from certificates.tests.factories import GeneratedCertificateFactory from certificates.models import CertificateStatuses from openedx.core.djangoapps.course_groups.cohorts import set_course_cohort_settings +from openedx.core.lib.xblock_fields.fields import Date from openedx.core.lib.xblock_utils import grade_histogram from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers from openedx.core.djangoapps.site_configuration.tests.mixins import SiteMixin diff --git a/lms/djangoapps/instructor/tests/test_tools.py b/lms/djangoapps/instructor/tests/test_tools.py index da8fe04d483..750d7be7e7e 100644 --- a/lms/djangoapps/instructor/tests/test_tools.py +++ b/lms/djangoapps/instructor/tests/test_tools.py @@ -14,7 +14,7 @@ from nose.plugins.attrib import attr from courseware.field_overrides import OverrideFieldData from lms.djangoapps.ccx.tests.test_overrides import inject_field_overrides from student.tests.factories import UserFactory -from xmodule.fields import Date +from openedx.core.lib.xblock_fields.fields import Date from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from opaque_keys.edx.keys import CourseKey diff --git a/lms/djangoapps/instructor/views/tools.py b/lms/djangoapps/instructor/views/tools.py index 9d6daa511d6..7fea17b8500 100644 --- a/lms/djangoapps/instructor/views/tools.py +++ b/lms/djangoapps/instructor/views/tools.py @@ -16,7 +16,7 @@ from courseware.student_field_overrides import ( get_override_for_user, override_field_for_user, ) -from xmodule.fields import Date +from openedx.core.lib.xblock_fields.fields import Date from opaque_keys.edx.keys import UsageKey DATE_FIELD = Date() diff --git a/lms/djangoapps/instructor_task/tasks_helper/grades.py b/lms/djangoapps/instructor_task/tasks_helper/grades.py index b2cdcc69611..71aa19e66d9 100644 --- a/lms/djangoapps/instructor_task/tasks_helper/grades.py +++ b/lms/djangoapps/instructor_task/tasks_helper/grades.py @@ -22,10 +22,10 @@ from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification from openedx.core.djangoapps.content.block_structure.api import get_course_in_cache from openedx.core.djangoapps.course_groups.cohorts import get_cohort, is_course_cohorted, bulk_cache_cohorts from openedx.core.djangoapps.user_api.course_tag.api import BulkCourseTags +from openedx.core.lib.partitions.partitions_service import PartitionService from student.models import CourseEnrollment from student.roles import BulkRoleCache from xmodule.modulestore.django import modulestore -from xmodule.partitions.partitions_service import PartitionService from xmodule.split_test_module import get_split_user_partitions from .runner import TaskProgress diff --git a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py index 2f4d5fde7c4..0e46f5f8a5d 100644 --- a/lms/djangoapps/instructor_task/tests/test_tasks_helper.py +++ b/lms/djangoapps/instructor_task/tests/test_tasks_helper.py @@ -40,6 +40,7 @@ from openedx.core.djangoapps.credit.tests.factories import CreditCourseFactory import openedx.core.djangoapps.user_api.course_tag.api as course_tag_api from openedx.core.djangoapps.user_api.partition_schemes import RandomUserPartitionScheme from openedx.core.djangoapps.util.testing import ContentGroupTestCase, TestConditionalContent +from openedx.core.lib.partitions.partitions import Group, UserPartition from request_cache.middleware import RequestCache from shoppingcart.models import ( Order, PaidCourseRegistration, CourseRegistrationCode, Invoice, @@ -51,7 +52,6 @@ from survey.models import SurveyForm, SurveyAnswer from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory, check_mongo_calls -from xmodule.partitions.partitions import Group, UserPartition from ..models import ReportStore from lms.djangoapps.instructor_task.tasks_helper.certs import ( diff --git a/lms/djangoapps/lms_xblock/mixin.py b/lms/djangoapps/lms_xblock/mixin.py index 7bf2ed4f7a9..d7855d372d5 100644 --- a/lms/djangoapps/lms_xblock/mixin.py +++ b/lms/djangoapps/lms_xblock/mixin.py @@ -8,8 +8,8 @@ from lazy import lazy from xblock.core import XBlock from xblock.fields import Boolean, Scope, String, XBlockMixin, Dict from xblock.validation import ValidationMessage -from xmodule.modulestore.inheritance import UserPartitionList -from xmodule.partitions.partitions import NoSuchUserPartitionError, NoSuchUserPartitionGroupError +from openedx.core.lib.xblock_fields.inherited_fields import UserPartitionList +from openedx.core.lib.partitions.partitions import NoSuchUserPartitionError, NoSuchUserPartitionGroupError # Please do not remove, this is a workaround for Django 1.8. # more information can be found here: https://openedx.atlassian.net/browse/PLAT-902 diff --git a/lms/djangoapps/lms_xblock/runtime.py b/lms/djangoapps/lms_xblock/runtime.py index 58bf0f1f96c..b42e3e04cbf 100644 --- a/lms/djangoapps/lms_xblock/runtime.py +++ b/lms/djangoapps/lms_xblock/runtime.py @@ -13,7 +13,7 @@ from request_cache.middleware import RequestCache import xblock.reference.plugins from xmodule.library_tools import LibraryToolsService from xmodule.modulestore.django import modulestore, ModuleI18nService -from xmodule.partitions.partitions_service import PartitionService +from openedx.core.lib.partitions.partitions_service import PartitionService from xmodule.services import SettingsService from xmodule.x_module import ModuleSystem diff --git a/lms/djangoapps/mobile_api/users/tests.py b/lms/djangoapps/mobile_api/users/tests.py index 2cb0e642634..c57ea6ccd8d 100644 --- a/lms/djangoapps/mobile_api/users/tests.py +++ b/lms/djangoapps/mobile_api/users/tests.py @@ -13,7 +13,6 @@ from django.utils import timezone from django.template import defaultfilters from django.test import RequestFactory, override_settings from milestones.tests.utils import MilestonesTestCaseMixin -from xmodule.course_module import DEFAULT_START_DATE from xmodule.modulestore.tests.factories import ItemFactory, CourseFactory from certificates.api import generate_user_certificates @@ -27,6 +26,7 @@ from courseware.access_response import ( from course_modes.models import CourseMode from lms.djangoapps.grades.tests.utils import mock_passing_grade from openedx.core.lib.courses import course_image_url +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from student.models import CourseEnrollment from util.milestones_helpers import set_prerequisite_courses from util.testing import UrlResetMixin diff --git a/lms/djangoapps/mobile_api/video_outlines/tests.py b/lms/djangoapps/mobile_api/video_outlines/tests.py index 877bb87b7cc..a3fa6b45335 100644 --- a/lms/djangoapps/mobile_api/video_outlines/tests.py +++ b/lms/djangoapps/mobile_api/video_outlines/tests.py @@ -13,10 +13,10 @@ from edxval import api from xmodule.modulestore.tests.factories import ItemFactory from xmodule.video_module import transcripts_utils from xmodule.modulestore.django import modulestore -from xmodule.partitions.partitions import Group, UserPartition from milestones.tests.utils import MilestonesTestCaseMixin from mobile_api.models import MobileApiConfig +from openedx.core.lib.partitions.partitions import Group, UserPartition from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory from openedx.core.djangoapps.course_groups.models import CourseUserGroupPartitionGroup from openedx.core.djangoapps.course_groups.cohorts import add_user_to_cohort, remove_user_from_cohort diff --git a/lms/envs/common.py b/lms/envs/common.py index a67449c721a..f205f0778b3 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -727,7 +727,7 @@ VIRTUAL_UNIVERSITIES = [] ############# XBlock Configuration ########## # Import after sys.path fixup -from xmodule.modulestore.inheritance import InheritanceMixin +from openedx.core.lib.xblock_fields.inherited_fields import InheritanceMixin from xmodule.modulestore import prefer_xmodules from xmodule.x_module import XModuleMixin diff --git a/lms/lib/xblock/test/test_mixin.py b/lms/lib/xblock/test/test_mixin.py index f6cd9d68e99..c09d336ca4b 100644 --- a/lms/lib/xblock/test/test_mixin.py +++ b/lms/lib/xblock/test/test_mixin.py @@ -9,7 +9,7 @@ from xblock.validation import ValidationMessage from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.tests.factories import CourseFactory, ToyCourseFactory, ItemFactory from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, TEST_DATA_MIXED_MODULESTORE -from xmodule.partitions.partitions import Group, UserPartition +from openedx.core.lib.partitions.partitions import Group, UserPartition class LmsXBlockMixinTestCase(ModuleStoreTestCase): diff --git a/lms/templates/preview_menu.html b/lms/templates/preview_menu.html index d5de16c7b7a..297de686308 100644 --- a/lms/templates/preview_menu.html +++ b/lms/templates/preview_menu.html @@ -7,7 +7,7 @@ from django.utils.translation import ugettext as _ from django.conf import settings from openedx.core.djangolib.js_utils import dump_js_escaped_json from openedx.core.djangolib.markup import HTML, Text -from xmodule.partitions.partitions_service import get_all_partitions_for_course +from openedx.core.lib.partitions.partitions_service import get_all_partitions_for_course %> <% diff --git a/openedx/core/djangoapps/content/course_overviews/models.py b/openedx/core/djangoapps/content/course_overviews/models.py index 20330043ac3..f61d994f3b2 100644 --- a/openedx/core/djangoapps/content/course_overviews/models.py +++ b/openedx/core/djangoapps/content/course_overviews/models.py @@ -20,10 +20,11 @@ from lms.djangoapps import django_comment_client from openedx.core.djangoapps.models.course_details import CourseDetails from static_replace.models import AssetBaseUrlConfig from xmodule import course_metadata_utils, block_metadata_utils -from xmodule.course_module import CourseDescriptor, DEFAULT_START_DATE +from xmodule.course_module import CourseDescriptor from xmodule.error_module import ErrorDescriptor from xmodule.modulestore.django import modulestore from openedx.core.djangoapps.xmodule_django.models import CourseKeyField, UsageKeyField +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE log = logging.getLogger(__name__) diff --git a/openedx/core/djangoapps/content/course_overviews/tests.py b/openedx/core/djangoapps/content/course_overviews/tests.py index 103db6d1403..741951ad6d2 100644 --- a/openedx/core/djangoapps/content/course_overviews/tests.py +++ b/openedx/core/djangoapps/content/course_overviews/tests.py @@ -19,11 +19,11 @@ from PIL import Image from lms.djangoapps.certificates.api import get_active_web_certificate from openedx.core.djangoapps.models.course_details import CourseDetails from openedx.core.lib.courses import course_image_url +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from static_replace.models import AssetBaseUrlConfig from xmodule.assetstore.assetmgr import AssetManager from xmodule.contentstore.django import contentstore from xmodule.contentstore.content import StaticContent -from xmodule.course_metadata_utils import DEFAULT_START_DATE from xmodule.course_module import ( CATALOG_VISIBILITY_CATALOG_AND_ABOUT, CATALOG_VISIBILITY_ABOUT, diff --git a/openedx/core/djangoapps/course_groups/partition_scheme.py b/openedx/core/djangoapps/course_groups/partition_scheme.py index e47981a5f06..ad6968ff52e 100644 --- a/openedx/core/djangoapps/course_groups/partition_scheme.py +++ b/openedx/core/djangoapps/course_groups/partition_scheme.py @@ -8,7 +8,7 @@ from courseware.masquerade import ( # pylint: disable=import-error get_masquerading_user_group, is_masquerading_as_specific_student ) -from xmodule.partitions.partitions import NoSuchUserPartitionGroupError +from openedx.core.lib.partitions.partitions import NoSuchUserPartitionGroupError from .cohorts import get_cohort, get_group_info_for_cohort diff --git a/openedx/core/djangoapps/course_groups/tests/test_partition_scheme.py b/openedx/core/djangoapps/course_groups/tests/test_partition_scheme.py index 1e28ad2afda..285ed77c1cb 100644 --- a/openedx/core/djangoapps/course_groups/tests/test_partition_scheme.py +++ b/openedx/core/djangoapps/course_groups/tests/test_partition_scheme.py @@ -8,13 +8,13 @@ from nose.plugins.attrib import attr from courseware.tests.test_masquerade import StaffMasqueradeTestCase from student.tests.factories import UserFactory -from xmodule.partitions.partitions import Group, UserPartition, UserPartitionError from xmodule.modulestore.django import modulestore from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase, TEST_DATA_MIXED_MODULESTORE from xmodule.modulestore.tests.factories import ToyCourseFactory from openedx.core.djangoapps.user_api.partition_schemes import RandomUserPartitionScheme from openedx.core.djangolib.testing.utils import skip_unless_lms +from openedx.core.lib.partitions.partitions import Group, UserPartition, UserPartitionError from ..partition_scheme import CohortPartitionScheme, get_cohorted_user_partition from ..models import CourseUserGroupPartitionGroup from ..views import link_cohort_to_partition_group, unlink_cohort_partition_group diff --git a/openedx/core/djangoapps/models/course_details.py b/openedx/core/djangoapps/models/course_details.py index 6f0a2de2508..db87026384f 100644 --- a/openedx/core/djangoapps/models/course_details.py +++ b/openedx/core/djangoapps/models/course_details.py @@ -6,7 +6,7 @@ import logging from django.conf import settings -from xmodule.fields import Date +from openedx.core.lib.xblock_fields.fields import Date from xmodule.modulestore.exceptions import ItemNotFoundError from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration from openedx.core.lib.courses import course_image_url diff --git a/openedx/core/djangoapps/user_api/partition_schemes.py b/openedx/core/djangoapps/user_api/partition_schemes.py index 070acbd0cc5..ea6c08865f3 100644 --- a/openedx/core/djangoapps/user_api/partition_schemes.py +++ b/openedx/core/djangoapps/user_api/partition_schemes.py @@ -5,7 +5,7 @@ import logging import random import course_tag.api as course_tag_api -from xmodule.partitions.partitions import UserPartitionError, NoSuchUserPartitionGroupError +from openedx.core.lib.partitions.partitions import UserPartitionError, NoSuchUserPartitionGroupError log = logging.getLogger(__name__) diff --git a/openedx/core/djangoapps/user_api/tests/test_partition_schemes.py b/openedx/core/djangoapps/user_api/tests/test_partition_schemes.py index d12bc3f8c67..7ce38aa570a 100644 --- a/openedx/core/djangoapps/user_api/tests/test_partition_schemes.py +++ b/openedx/core/djangoapps/user_api/tests/test_partition_schemes.py @@ -6,9 +6,9 @@ from mock import patch from unittest import TestCase from openedx.core.djangoapps.user_api.partition_schemes import RandomUserPartitionScheme, UserPartitionError +from openedx.core.lib.partitions.partitions import Group, UserPartition +from openedx.core.lib.partitions.tests.test_partitions import PartitionTestCase from student.tests.factories import UserFactory -from xmodule.partitions.partitions import Group, UserPartition -from xmodule.partitions.tests.test_partitions import PartitionTestCase class MemoryCourseTagAPI(object): diff --git a/openedx/core/djangoapps/util/testing.py b/openedx/core/djangoapps/util/testing.py index 380c8cdfcfd..e78644a4502 100644 --- a/openedx/core/djangoapps/util/testing.py +++ b/openedx/core/djangoapps/util/testing.py @@ -6,9 +6,9 @@ from pytz import UTC from openedx.core.djangoapps.course_groups.models import CourseUserGroupPartitionGroup from openedx.core.djangoapps.course_groups.tests.helpers import CohortFactory from openedx.core.djangoapps.user_api.tests.factories import UserCourseTagFactory +from openedx.core.lib.partitions.partitions import UserPartition, Group from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase -from xmodule.partitions.partitions import UserPartition, Group from student.tests.factories import CourseEnrollmentFactory, UserFactory diff --git a/openedx/core/djangoapps/verified_track_content/partition_scheme.py b/openedx/core/djangoapps/verified_track_content/partition_scheme.py index 2260265b12b..01e3a5365e8 100644 --- a/openedx/core/djangoapps/verified_track_content/partition_scheme.py +++ b/openedx/core/djangoapps/verified_track_content/partition_scheme.py @@ -12,7 +12,7 @@ from course_modes.models import CourseMode from student.models import CourseEnrollment from opaque_keys.edx.keys import CourseKey from openedx.core.djangoapps.verified_track_content.models import VerifiedTrackCohortedCourse -from xmodule.partitions.partitions import NoSuchUserPartitionGroupError, Group, UserPartition +from openedx.core.lib.partitions.partitions import NoSuchUserPartitionGroupError, Group, UserPartition # These IDs must be less than 100 so that they do not overlap with Groups in diff --git a/openedx/core/djangoapps/verified_track_content/tests/test_partition_scheme.py b/openedx/core/djangoapps/verified_track_content/tests/test_partition_scheme.py index 0e007e2697b..f7a076eaca4 100644 --- a/openedx/core/djangoapps/verified_track_content/tests/test_partition_scheme.py +++ b/openedx/core/djangoapps/verified_track_content/tests/test_partition_scheme.py @@ -12,7 +12,7 @@ from student.models import CourseEnrollment from student.tests.factories import UserFactory from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory -from xmodule.partitions.partitions import UserPartition, MINIMUM_STATIC_PARTITION_ID +from openedx.core.lib.partitions.partitions import UserPartition, MINIMUM_STATIC_PARTITION_ID class EnrollmentTrackUserPartitionTest(SharedModuleStoreTestCase): diff --git a/common/lib/xmodule/xmodule/partitions/__init__.py b/openedx/core/lib/partitions/__init__.py similarity index 100% rename from common/lib/xmodule/xmodule/partitions/__init__.py rename to openedx/core/lib/partitions/__init__.py diff --git a/common/lib/xmodule/xmodule/partitions/partitions.py b/openedx/core/lib/partitions/partitions.py similarity index 100% rename from common/lib/xmodule/xmodule/partitions/partitions.py rename to openedx/core/lib/partitions/partitions.py diff --git a/common/lib/xmodule/xmodule/partitions/partitions_service.py b/openedx/core/lib/partitions/partitions_service.py similarity index 98% rename from common/lib/xmodule/xmodule/partitions/partitions_service.py rename to openedx/core/lib/partitions/partitions_service.py index 39c8dbe9300..de5d5b7ab13 100644 --- a/common/lib/xmodule/xmodule/partitions/partitions_service.py +++ b/openedx/core/lib/partitions/partitions_service.py @@ -7,7 +7,7 @@ from django.conf import settings from django.utils.translation import ugettext_lazy as _ import logging -from xmodule.partitions.partitions import UserPartition, UserPartitionError, ENROLLMENT_TRACK_PARTITION_ID +from .partitions import UserPartition, UserPartitionError, ENROLLMENT_TRACK_PARTITION_ID from xmodule.modulestore.django import modulestore diff --git a/common/lib/xmodule/xmodule/partitions/tests/__init__.py b/openedx/core/lib/partitions/tests/__init__.py similarity index 100% rename from common/lib/xmodule/xmodule/partitions/tests/__init__.py rename to openedx/core/lib/partitions/tests/__init__.py diff --git a/common/lib/xmodule/xmodule/partitions/tests/test_partitions.py b/openedx/core/lib/partitions/tests/test_partitions.py similarity index 99% rename from common/lib/xmodule/xmodule/partitions/tests/test_partitions.py rename to openedx/core/lib/partitions/tests/test_partitions.py index 3b37bbb4d85..2d3aaf1ee17 100644 --- a/common/lib/xmodule/xmodule/partitions/tests/test_partitions.py +++ b/openedx/core/lib/partitions/tests/test_partitions.py @@ -8,11 +8,11 @@ from mock import Mock from opaque_keys.edx.locator import CourseLocator from stevedore.extension import Extension, ExtensionManager -from xmodule.partitions.partitions import ( +from openedx.core.lib.partitions.partitions import ( Group, UserPartition, UserPartitionError, NoSuchUserPartitionGroupError, USER_PARTITION_SCHEME_NAMESPACE, ENROLLMENT_TRACK_PARTITION_ID ) -from xmodule.partitions.partitions_service import ( +from openedx.core.lib.partitions.partitions_service import ( PartitionService, get_all_partitions_for_course, FEATURES ) diff --git a/openedx/core/lib/xblock_fields/__init__.py b/openedx/core/lib/xblock_fields/__init__.py new file mode 100644 index 00000000000..e69de29bb2d diff --git a/common/lib/xmodule/xmodule/fields.py b/openedx/core/lib/xblock_fields/fields.py similarity index 86% rename from common/lib/xmodule/xmodule/fields.py rename to openedx/core/lib/xblock_fields/fields.py index 2b73d5b63f7..fe27225a16f 100644 --- a/common/lib/xmodule/xmodule/fields.py +++ b/openedx/core/lib/xblock_fields/fields.py @@ -253,3 +253,38 @@ class RelativeTime(JSONField): return value return self.from_json(value) + + +class TimeInfo(object): + """ + This is a simple object that calculates and stores datetime information for an XModule + based on the due date and the grace period string + + So far it parses out three different pieces of time information: + self.display_due_date - the 'official' due date that gets displayed to students + self.grace_period - the length of the grace period + self.close_date - the real due date + + """ + _delta_standin = Timedelta() + + def __init__(self, due_date, grace_period_string_or_timedelta): + if due_date is not None: + self.display_due_date = due_date + + else: + self.display_due_date = None + + if grace_period_string_or_timedelta is not None and self.display_due_date: + if isinstance(grace_period_string_or_timedelta, basestring): + try: + self.grace_period = TimeInfo._delta_standin.from_json(grace_period_string_or_timedelta) + except: + log.error("Error parsing the grace period {0}".format(grace_period_string_or_timedelta)) + raise + else: + self.grace_period = grace_period_string_or_timedelta + self.close_date = self.display_due_date + self.grace_period + else: + self.grace_period = None + self.close_date = self.display_due_date diff --git a/openedx/core/lib/xblock_fields/inherited_fields.py b/openedx/core/lib/xblock_fields/inherited_fields.py new file mode 100644 index 00000000000..0486c086ec1 --- /dev/null +++ b/openedx/core/lib/xblock_fields/inherited_fields.py @@ -0,0 +1,239 @@ +""" +Inherited fields for all XBlocks. +""" +from __future__ import absolute_import +from datetime import datetime + +from django.conf import settings +from pytz import utc + +from xblock.fields import Scope, Boolean, String, Float, XBlockMixin, Dict, Integer, List +from openedx.core.lib.partitions.partitions import UserPartition +from .fields import Date, Timedelta + + +DEFAULT_START_DATE = datetime(2030, 1, 1, tzinfo=utc) + +# 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 UserPartitionList(List): + """Special List class for listing UserPartitions""" + def from_json(self, values): + return [UserPartition.from_json(v) for v in values] + + def to_json(self, values): + return [user_partition.to_json() + for user_partition in values] + + +class InheritanceMixin(XBlockMixin): + """Field definitions for inheritable fields.""" + + graded = Boolean( + help="Whether this module contributes to the final course grade", + scope=Scope.settings, + default=False, + ) + start = Date( + help="Start time when this module is visible", + default=DEFAULT_START_DATE, + scope=Scope.settings + ) + due = Date( + display_name=_("Due Date"), + help=_("Enter the default date by which problems are due."), + scope=Scope.settings, + ) + visible_to_staff_only = Boolean( + help=_("If true, can be seen only by course staff, regardless of start date."), + default=False, + scope=Scope.settings, + ) + course_edit_method = String( + display_name=_("Course Editor"), + help=_("Enter the method by which this course is edited (\"XML\" or \"Studio\")."), + default="Studio", + scope=Scope.settings, + deprecated=True # Deprecated because user would not change away from Studio within Studio. + ) + giturl = String( + display_name=_("GIT URL"), + help=_("Enter the URL for the course data GIT repository."), + scope=Scope.settings + ) + xqa_key = String( + display_name=_("XQA Key"), + help=_("This setting is not currently supported."), scope=Scope.settings, + deprecated=True + ) + annotation_storage_url = String( + help=_("Enter the location of the annotation storage server. The textannotation, videoannotation, and imageannotation advanced modules require this setting."), + scope=Scope.settings, + default="http://your_annotation_storage.com", + display_name=_("URL for Annotation Storage") + ) + annotation_token_secret = String( + help=_("Enter the secret string for annotation storage. The textannotation, videoannotation, and imageannotation advanced modules require this string."), + scope=Scope.settings, + default="xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", + display_name=_("Secret Token String for Annotation") + ) + graceperiod = Timedelta( + help="Amount of time after the due date that submissions will be accepted", + scope=Scope.settings, + ) + group_access = Dict( + help=_("Enter the ids for the content groups this problem belongs to."), + scope=Scope.settings, + ) + + showanswer = String( + display_name=_("Show Answer"), + help=_( + # Translators: DO NOT translate the words in quotes here, they are + # specific words for the acceptable values. + 'Specify when the Show Answer button appears for each problem. ' + 'Valid values are "always", "answered", "attempted", "closed", ' + '"finished", "past_due", "correct_or_past_due", and "never".' + ), + scope=Scope.settings, + default="finished", + ) + + show_correctness = String( + display_name=_("Show Results"), + help=_( + # Translators: DO NOT translate the words in quotes here, they are + # specific words for the acceptable values. + 'Specify when to show answer correctness and score to learners. ' + 'Valid values are "always", "never", and "past_due".' + ), + scope=Scope.settings, + default="always", + ) + + rerandomize = String( + display_name=_("Randomization"), + help=_( + # Translators: DO NOT translate the words in quotes here, they are + # specific words for the acceptable values. + 'Specify the default for how often variable values in a problem are randomized. ' + 'This setting should be set to "never" unless you plan to provide a Python ' + 'script to identify and randomize values in most of the problems in your course. ' + 'Valid values are "always", "onreset", "never", and "per_student".' + ), + scope=Scope.settings, + default="never", + ) + days_early_for_beta = Float( + display_name=_("Days Early for Beta Users"), + help=_("Enter the number of days before the start date that beta users can access the course."), + scope=Scope.settings, + default=None, + ) + static_asset_path = String( + display_name=_("Static Asset Path"), + help=_("Enter the path to use for files on the Files & Uploads page. This value overrides the Studio default, c4x://."), + scope=Scope.settings, + default='', + ) + use_latex_compiler = Boolean( + display_name=_("Enable LaTeX Compiler"), + help=_("Enter true or false. If true, you can use the LaTeX templates for HTML components and advanced Problem components."), + default=False, + scope=Scope.settings + ) + max_attempts = Integer( + display_name=_("Maximum Attempts"), + help=_("Enter the maximum number of times a student can try to answer problems. By default, Maximum Attempts is set to null, meaning that students have an unlimited number of attempts for problems. You can override this course-wide setting for individual problems. However, if the course-wide setting is a specific number, you cannot set the Maximum Attempts for individual problems to unlimited."), + values={"min": 0}, scope=Scope.settings + ) + matlab_api_key = String( + display_name=_("Matlab API key"), + help=_("Enter the API key provided by MathWorks for accessing the MATLAB Hosted Service. " + "This key is granted for exclusive use in this course for the specified duration. " + "Do not share the API key with other courses. Notify MathWorks immediately " + "if you believe the key is exposed or compromised. To obtain a key for your course, " + "or to report an issue, please contact moocsupport@mathworks.com"), + scope=Scope.settings + ) + # This is should be scoped to content, but since it's defined in the policy + # file, it is currently scoped to settings. + user_partitions = UserPartitionList( + display_name=_("Group Configurations"), + help=_("Enter the configurations that govern how students are grouped together."), + default=[], + scope=Scope.settings + ) + video_speed_optimizations = Boolean( + display_name=_("Enable video caching system"), + help=_("Enter true or false. If true, video caching will be used for HTML5 videos."), + default=True, + scope=Scope.settings + ) + video_bumper = Dict( + display_name=_("Video Pre-Roll"), + help=_( + "Identify a video, 5-10 seconds in length, to play before course videos. Enter the video ID from " + "the Video Uploads page and one or more transcript files in the following format: {format}. " + "For example, an entry for a video with two transcripts looks like this: {example}" + ).format( + format='{"video_id": "ID", "transcripts": {"language": "/static/filename.srt"}}', + example=( + '{' + '"video_id": "77cef264-d6f5-4cf2-ad9d-0178ab8c77be", ' + '"transcripts": {"en": "/static/DemoX-D01_1.srt", "uk": "/static/DemoX-D01_1_uk.srt"}' + '}' + ), + ), + scope=Scope.settings + ) + + # TODO: Remove this Django dependency! It really doesn't belong here. + reset_key = "DEFAULT_SHOW_RESET_BUTTON" + default_reset_button = getattr(settings, reset_key) if hasattr(settings, reset_key) else False + show_reset_button = Boolean( + display_name=_("Show Reset Button for Problems"), + help=_( + "Enter true or false. If true, problems in the course default to always displaying a 'Reset' button. " + "You can override this in each problem's settings. All existing problems are affected when " + "this course-wide setting is changed." + ), + scope=Scope.settings, + default=default_reset_button + ) + edxnotes = Boolean( + display_name=_("Enable Student Notes"), + help=_("Enter true or false. If true, students can use the Student Notes feature."), + default=False, + scope=Scope.settings + ) + edxnotes_visibility = Boolean( + display_name="Student Notes Visibility", + help=_("Indicates whether Student Notes are visible in the course. " + "Students can also show or hide their notes in the courseware."), + default=True, + scope=Scope.user_info + ) + + in_entrance_exam = Boolean( + display_name=_("Tag this module as part of an Entrance Exam section"), + help=_("Enter true or false. If true, answer submissions for problem modules will be " + "considered in the Entrance Exam scoring/gating algorithm."), + scope=Scope.settings, + default=False + ) + + self_paced = Boolean( + display_name=_('Self Paced'), + help=_( + 'Set this to "true" to mark this course as self-paced. Self-paced courses do not have ' + 'due dates for assignments, and students can progress through the course at any rate before ' + 'the course ends.' + ), + default=False, + scope=Scope.settings + ) diff --git a/openedx/features/course_experience/tests/views/test_course_outline.py b/openedx/features/course_experience/tests/views/test_course_outline.py index 8e518bb621b..bd9a2c95280 100644 --- a/openedx/features/course_experience/tests/views/test_course_outline.py +++ b/openedx/features/course_experience/tests/views/test_course_outline.py @@ -16,7 +16,7 @@ from student.tests.factories import UserFactory from xmodule.modulestore import ModuleStoreEnum from xmodule.modulestore.tests.django_utils import SharedModuleStoreTestCase from xmodule.modulestore.tests.factories import CourseFactory, ItemFactory -from xmodule.course_module import DEFAULT_START_DATE +from openedx.core.lib.xblock_fields.inherited_fields import DEFAULT_START_DATE from .test_course_home import course_home_url -- GitLab