Commit cc2d0697 by cahrens

Remove duplicated StringyX definitions.

parent 9e988633
...@@ -4,22 +4,8 @@ Namespace defining common fields used by Studio for all blocks ...@@ -4,22 +4,8 @@ Namespace defining common fields used by Studio for all blocks
import datetime import datetime
from xblock.core import Namespace, Boolean, Scope, ModelType, String from xblock.core import Namespace, Scope, ModelType, String
from xmodule.fields import StringyBoolean
class StringyBoolean(Boolean):
"""
Reads strings from JSON as booleans.
If the string is 'true' (case insensitive), then return True,
otherwise False.
JSON values that aren't strings are returned as is
"""
def from_json(self, value):
if isinstance(value, basestring):
return value.lower() == 'true'
return value
class DateTuple(ModelType): class DateTuple(ModelType):
......
...@@ -16,36 +16,13 @@ from .progress import Progress ...@@ -16,36 +16,13 @@ from .progress import Progress
from xmodule.x_module import XModule from xmodule.x_module import XModule
from xmodule.raw_module import RawDescriptor from xmodule.raw_module import RawDescriptor
from xmodule.exceptions import NotFoundError, ProcessingError from xmodule.exceptions import NotFoundError, ProcessingError
from xblock.core import Integer, Scope, String, Boolean, Object, Float from xblock.core import Scope, String, Boolean, Object
from .fields import Timedelta, Date from .fields import Timedelta, Date, StringyInteger, StringyFloat
from xmodule.util.date_utils import time_to_datetime from xmodule.util.date_utils import time_to_datetime
log = logging.getLogger("mitx.courseware") log = logging.getLogger("mitx.courseware")
class StringyInteger(Integer):
"""
A model type that converts from strings to integers when reading from json
"""
def from_json(self, value):
try:
return int(value)
except:
return None
# TODO: move to fields.py and remove duplicated code.
class StringyFloat(Float):
"""
A model type that converts from string to floats when reading from json
"""
def from_json(self, value):
try:
return float(value)
except:
return None
# Generated this many different variants of problems with rerandomize=per_student # Generated this many different variants of problems with rerandomize=per_student
NUM_RANDOMIZATION_BINS = 20 NUM_RANDOMIZATION_BINS = 20
......
...@@ -8,8 +8,7 @@ from .x_module import XModule ...@@ -8,8 +8,7 @@ from .x_module import XModule
from xblock.core import Integer, Scope, String, Boolean, List from xblock.core import Integer, Scope, String, Boolean, List
from xmodule.open_ended_grading_classes.combined_open_ended_modulev1 import CombinedOpenEndedV1Module, CombinedOpenEndedV1Descriptor from xmodule.open_ended_grading_classes.combined_open_ended_modulev1 import CombinedOpenEndedV1Module, CombinedOpenEndedV1Descriptor
from collections import namedtuple from collections import namedtuple
from .fields import Date from .fields import Date, StringyFloat
from xmodule.open_ended_grading_classes.xblock_field_types import StringyFloat
log = logging.getLogger("mitx.courseware") log = logging.getLogger("mitx.courseware")
......
...@@ -7,6 +7,8 @@ from xblock.core import ModelType ...@@ -7,6 +7,8 @@ from xblock.core import ModelType
import datetime import datetime
import dateutil.parser import dateutil.parser
from xblock.core import Integer, Float, Boolean
log = logging.getLogger(__name__) log = logging.getLogger(__name__)
...@@ -81,3 +83,42 @@ class Timedelta(ModelType): ...@@ -81,3 +83,42 @@ class Timedelta(ModelType):
if cur_value > 0: if cur_value > 0:
values.append("%d %s" % (cur_value, attr)) values.append("%d %s" % (cur_value, attr))
return ' '.join(values) return ' '.join(values)
class StringyInteger(Integer):
"""
A model type that converts from strings to integers when reading from json.
If value does not parse as an int, returns None.
"""
def from_json(self, value):
try:
return int(value)
except:
return None
class StringyFloat(Float):
"""
A model type that converts from string to floats when reading from json.
If value does not parse as a float, returns None.
"""
def from_json(self, value):
try:
return float(value)
except:
return None
class StringyBoolean(Boolean):
"""
Reads strings from JSON as booleans.
If the string is 'true' (case insensitive), then return True,
otherwise False.
JSON values that aren't strings are returned as-is.
"""
def from_json(self, value):
if isinstance(value, basestring):
return value.lower() == 'true'
return value
from .x_module import XModuleDescriptor, DescriptorSystem from .x_module import XModuleDescriptor, DescriptorSystem
from .modulestore.inheritance import own_metadata from .modulestore.inheritance import own_metadata
from xblock.core import Scope
class MakoDescriptorSystem(DescriptorSystem): class MakoDescriptorSystem(DescriptorSystem):
...@@ -46,26 +44,10 @@ class MakoModuleDescriptor(XModuleDescriptor): ...@@ -46,26 +44,10 @@ class MakoModuleDescriptor(XModuleDescriptor):
# cdodge: encapsulate a means to expose "editable" metadata fields (i.e. not internal system metadata) # cdodge: encapsulate a means to expose "editable" metadata fields (i.e. not internal system metadata)
@property @property
def editable_metadata_fields(self): def editable_metadata_fields(self):
# fields = {} fields = {}
# for field, value in own_metadata(self).items(): for field, value in own_metadata(self).items():
# if field in self.system_metadata_fields: if field in self.system_metadata_fields:
# continue
#
# fields[field] = value
# return fields
inherited_metadata = getattr(self, '_inherited_metadata', {})
metadata = {}
for field in self.fields:
# Only save metadata that wasn't inherited
if field.scope != Scope.settings or field.name in self.system_metadata_fields:
continue continue
if field.name in self._model_data: fields[field] = value
metadata[field.name] = self._model_data[field.name] return fields
if field.name in inherited_metadata and self._model_data.get(field.name) == inherited_metadata.get(
field.name):
metadata[field.name] = str(metadata[field.name]) + ' INHERITED'
else:
metadata[field.name] = str(getattr(self, field.name)) + ' DEFAULT'
return metadata
...@@ -11,8 +11,7 @@ from xmodule.raw_module import RawDescriptor ...@@ -11,8 +11,7 @@ from xmodule.raw_module import RawDescriptor
from xmodule.modulestore.django import modulestore from xmodule.modulestore.django import modulestore
from .timeinfo import TimeInfo from .timeinfo import TimeInfo
from xblock.core import Object, Integer, Boolean, String, Scope from xblock.core import Object, Integer, Boolean, String, Scope
from xmodule.open_ended_grading_classes.xblock_field_types import StringyFloat from xmodule.fields import Date, StringyFloat
from xmodule.fields import Date
from xmodule.open_ended_grading_classes.peer_grading_service import PeerGradingService, GradingServiceError, MockPeerGradingService from xmodule.open_ended_grading_classes.peer_grading_service import PeerGradingService, GradingServiceError, MockPeerGradingService
from open_ended_grading_classes import combined_open_ended_rubric from open_ended_grading_classes import combined_open_ended_rubric
......
"""Tests for Date class defined in fields.py.""" """Tests for classes defined in fields.py."""
import datetime import datetime
import unittest import unittest
from django.utils.timezone import UTC from django.utils.timezone import UTC
from xmodule.fields import Date from xmodule.fields import Date, StringyFloat, StringyInteger, StringyBoolean
import time import time
class DateTest(unittest.TestCase): class DateTest(unittest.TestCase):
...@@ -78,3 +78,55 @@ class DateTest(unittest.TestCase): ...@@ -78,3 +78,55 @@ class DateTest(unittest.TestCase):
DateTest.date.from_json("2012-12-31T23:00:01-01:00")), DateTest.date.from_json("2012-12-31T23:00:01-01:00")),
"2013-01-01T00:00:01Z") "2013-01-01T00:00:01Z")
class StringyIntegerTest(unittest.TestCase):
def assertEquals(self, expected, arg):
self.assertEqual(expected, StringyInteger().from_json(arg))
def test_integer(self):
self.assertEquals(5, '5')
self.assertEquals(0, '0')
self.assertEquals(-1023, '-1023')
def test_none(self):
self.assertEquals(None, None)
self.assertEquals(None, 'abc')
self.assertEquals(None, '[1]')
self.assertEquals(None, '1.023')
class StringyFloatTest(unittest.TestCase):
def assertEquals(self, expected, arg):
self.assertEqual(expected, StringyFloat().from_json(arg))
def test_float(self):
self.assertEquals(.23, '.23')
self.assertEquals(5, '5')
self.assertEquals(0, '0.0')
self.assertEquals(-1023.22, '-1023.22')
def test_none(self):
self.assertEquals(None, None)
self.assertEquals(None, 'abc')
self.assertEquals(None, '[1]')
class StringyBooleanTest(unittest.TestCase):
def assertEquals(self, expected, arg):
self.assertEqual(expected, StringyBoolean().from_json(arg))
def test_false(self):
self.assertEquals(False, "false")
self.assertEquals(False, "False")
self.assertEquals(False, "")
self.assertEquals(False, "hahahahah")
def test_true(self):
self.assertEquals(True, "true")
self.assertEquals(True, "TruE")
def test_pass_through(self):
self.assertEquals(123, 123)
...@@ -20,7 +20,8 @@ log = logging.getLogger(__name__) ...@@ -20,7 +20,8 @@ log = logging.getLogger(__name__)
class VideoFields(object): class VideoFields(object):
data = String(help="XML data for the problem", scope=Scope.content) data = String(help="XML data for the problem", scope=Scope.content)
position = Integer(help="Current position in the video", scope=Scope.user_state, default=0) position = Integer(help="Current position in the video", scope=Scope.user_state, default=0)
display_name = String(help="Display name for this module", scope=Scope.settings) # display_name is used by the LMS on the sequential ribbon (displayed as a tooltip)
display_name = XModule.display_name
class VideoModule(VideoFields, XModule): class VideoModule(VideoFields, XModule):
......
""" """
Namespace that defines fields common to all blocks used in the LMS Namespace that defines fields common to all blocks used in the LMS
""" """
from xblock.core import Namespace, Boolean, Scope, String, Float from xblock.core import Namespace, Boolean, Scope, String
from xmodule.fields import Date, Timedelta from xmodule.fields import Date, Timedelta, StringyFloat, StringyBoolean
class StringyBoolean(Boolean):
"""
Reads strings from JSON as booleans.
'true' (case insensitive) return True, other strings return False
Other types are returned unchanged
"""
def from_json(self, value):
if isinstance(value, basestring):
return value.lower() == 'true'
return value
class StringyFloat(Float):
"""
Reads values as floats. If the value parses as a float, returns
that, otherwise returns None
"""
def from_json(self, value):
try:
return float(value)
except:
return None
class LmsNamespace(Namespace): class LmsNamespace(Namespace):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment