Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-ora2
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-ora2
Commits
4c473af4
Commit
4c473af4
authored
Mar 11, 2014
by
Will Daly
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Make start/end date fields store datetime objects internally
parent
74af9d4a
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
66 additions
and
29 deletions
+66
-29
apps/openassessment/xblock/openassessmentblock.py
+9
-11
apps/openassessment/xblock/resolve_dates.py
+16
-9
apps/openassessment/xblock/test/test_openassessment.py
+11
-0
apps/openassessment/xblock/test/test_studio.py
+1
-1
apps/openassessment/xblock/test/test_xml.py
+28
-7
requirements/base.txt
+1
-1
No files found.
apps/openassessment/xblock/openassessmentblock.py
View file @
4c473af4
"""An XBlock where students can read a question and compose their response"""
"""An XBlock where students can read a question and compose their response"""
import
datetime
as
dt
import
datetime
as
dt
import
json
import
pkg_resources
import
pkg_resources
import
pytz
import
pytz
...
@@ -11,7 +12,7 @@ from django.template.loader import get_template
...
@@ -11,7 +12,7 @@ from django.template.loader import get_template
from
webob
import
Response
from
webob
import
Response
from
xblock.core
import
XBlock
from
xblock.core
import
XBlock
from
xblock.fields
import
List
,
Scope
,
String
,
Boolean
from
xblock.fields
import
DateTime
,
List
,
Scope
,
String
,
Boolean
from
xblock.fragment
import
Fragment
from
xblock.fragment
import
Fragment
from
openassessment.xblock.grade_mixin
import
GradeMixin
from
openassessment.xblock.grade_mixin
import
GradeMixin
...
@@ -168,12 +169,12 @@ class OpenAssessmentBlock(
...
@@ -168,12 +169,12 @@ class OpenAssessmentBlock(
WorkflowMixin
):
WorkflowMixin
):
"""Displays a question and gives an area where students can compose a response."""
"""Displays a question and gives an area where students can compose a response."""
start
=
String
(
start
=
DateTime
(
default
=
None
,
scope
=
Scope
.
settings
,
default
=
None
,
scope
=
Scope
.
settings
,
help
=
"ISO-8601 formatted string representing the start date of this assignment."
help
=
"ISO-8601 formatted string representing the start date of this assignment."
)
)
due
=
String
(
due
=
DateTime
(
default
=
None
,
scope
=
Scope
.
settings
,
default
=
None
,
scope
=
Scope
.
settings
,
help
=
"ISO-8601 formatted string representing the due date of this assignment."
help
=
"ISO-8601 formatted string representing the due date of this assignment."
)
)
...
@@ -379,13 +380,11 @@ class OpenAssessmentBlock(
...
@@ -379,13 +380,11 @@ class OpenAssessmentBlock(
context_dict
[
"xblock_trace"
]
=
self
.
get_xblock_trace
()
context_dict
[
"xblock_trace"
]
=
self
.
get_xblock_trace
()
if
self
.
start
:
if
self
.
start
:
start
=
dateutil
.
parser
.
parse
(
self
.
start
)
context_dict
[
"formatted_start_date"
]
=
self
.
start
.
strftime
(
"
%
A,
%
B
%
d,
%
Y"
)
context_dict
[
"formatted_start_date"
]
=
start
.
strftime
(
"
%
A,
%
B
%
d,
%
Y"
)
context_dict
[
"formatted_start_datetime"
]
=
self
.
start
.
strftime
(
"
%
A,
%
B
%
d,
%
Y
%
X"
)
context_dict
[
"formatted_start_datetime"
]
=
start
.
strftime
(
"
%
A,
%
B
%
d,
%
Y
%
X"
)
if
self
.
due
:
if
self
.
due
:
due
=
dateutil
.
parser
.
parse
(
self
.
due
)
context_dict
[
"formatted_due_date"
]
=
self
.
due
.
strftime
(
"
%
A,
%
B
%
d,
%
Y"
)
context_dict
[
"formatted_due_date"
]
=
due
.
strftime
(
"
%
A,
%
B
%
d,
%
Y"
)
context_dict
[
"formatted_due_datetime"
]
=
self
.
due
.
strftime
(
"
%
A,
%
B
%
d,
%
Y
%
X"
)
context_dict
[
"formatted_due_datetime"
]
=
due
.
strftime
(
"
%
A,
%
B
%
d,
%
Y
%
X"
)
template
=
get_template
(
path
)
template
=
get_template
(
path
)
context
=
Context
(
context_dict
)
context
=
Context
(
context_dict
)
...
@@ -503,4 +502,4 @@ class OpenAssessmentBlock(
...
@@ -503,4 +502,4 @@ class OpenAssessmentBlock(
"""
"""
for
assessment
in
self
.
rubric_assessments
:
for
assessment
in
self
.
rubric_assessments
:
if
assessment
[
"name"
]
==
mixin_name
:
if
assessment
[
"name"
]
==
mixin_name
:
return
assessment
return
assessment
\ No newline at end of file
apps/openassessment/xblock/resolve_dates.py
View file @
4c473af4
...
@@ -25,12 +25,12 @@ DISTANT_PAST = dt.datetime(dt.MINYEAR, 1, 1, tzinfo=pytz.utc)
...
@@ -25,12 +25,12 @@ DISTANT_PAST = dt.datetime(dt.MINYEAR, 1, 1, tzinfo=pytz.utc)
DISTANT_FUTURE
=
dt
.
datetime
(
dt
.
MAXYEAR
,
1
,
1
,
tzinfo
=
pytz
.
utc
)
DISTANT_FUTURE
=
dt
.
datetime
(
dt
.
MAXYEAR
,
1
,
1
,
tzinfo
=
pytz
.
utc
)
def
_parse_date
(
date_string
):
def
_parse_date
(
value
):
"""
"""
Parse an ISO formatted datestring into a datetime object with timezone set to UTC.
Parse an ISO formatted datestring into a datetime object with timezone set to UTC.
Args:
Args:
date_string (str): The ISO formatted date string
.
value (str or datetime): The ISO formatted date string or datetime object
.
Returns:
Returns:
datetime.datetime
datetime.datetime
...
@@ -38,10 +38,17 @@ def _parse_date(date_string):
...
@@ -38,10 +38,17 @@ def _parse_date(date_string):
Raises:
Raises:
InvalidDateFormat: The date string could not be parsed.
InvalidDateFormat: The date string could not be parsed.
"""
"""
try
:
if
isinstance
(
value
,
dt
.
datetime
):
return
parse_date
(
date_string
)
.
replace
(
tzinfo
=
pytz
.
utc
)
return
value
.
replace
(
tzinfo
=
pytz
.
utc
)
except
ValueError
:
raise
InvalidDateFormat
(
_
(
"Could not parse date '{date}'"
)
.
format
(
date
=
date_string
))
elif
isinstance
(
value
,
basestring
):
try
:
return
parse_date
(
value
)
.
replace
(
tzinfo
=
pytz
.
utc
)
except
ValueError
:
raise
InvalidDateFormat
(
_
(
"Could not parse date '{date}'"
)
.
format
(
date
=
value
))
else
:
raise
InvalidDateFormat
(
_
(
"'{date}' must be a date string or datetime"
)
.
format
(
date
=
value
))
def
resolve_dates
(
start
,
end
,
date_ranges
):
def
resolve_dates
(
start
,
end
,
date_ranges
):
...
@@ -90,10 +97,10 @@ def resolve_dates(start, end, date_ranges):
...
@@ -90,10 +97,10 @@ def resolve_dates(start, end, date_ranges):
Args:
Args:
start (str, ISO date format): When the problem opens. A value of None indicates that the problem is always open.
start (str, ISO date format
, or datetime
): When the problem opens. A value of None indicates that the problem is always open.
end (str, ISO date format): When the problem closes. A value of None indicates that the problem never closes.
end (str, ISO date format
, or datetime
): When the problem closes. A value of None indicates that the problem never closes.
date_ranges (list of tuples): list of (start, end) ISO date string tuples indicating
date_ranges (list of tuples): list of (start, end) ISO date string tuples indicating
the start/end timestamps of each submission/assessment.
the start/end timestamps
(date string or datetime)
of each submission/assessment.
Returns:
Returns:
start (datetime): The resolved start date
start (datetime): The resolved start date
...
...
apps/openassessment/xblock/test/test_openassessment.py
View file @
4c473af4
...
@@ -63,6 +63,17 @@ class TestOpenAssessment(XBlockHandlerTestCase):
...
@@ -63,6 +63,17 @@ class TestOpenAssessment(XBlockHandlerTestCase):
self
.
assertTrue
(
submission_response
.
body
.
find
(
"openassessment__response"
))
self
.
assertTrue
(
submission_response
.
body
.
find
(
"openassessment__response"
))
self
.
assertTrue
(
submission_response
.
body
.
find
(
"April"
))
self
.
assertTrue
(
submission_response
.
body
.
find
(
"April"
))
@scenario
(
'data/basic_scenario.xml'
)
def
test_formatted_dates
(
self
,
xblock
):
# Set start/due dates
xblock
.
start
=
dt
.
datetime
(
2014
,
4
,
1
,
1
,
1
,
1
)
xblock
.
due
=
dt
.
datetime
(
2014
,
5
,
1
)
resp
=
xblock
.
render_peer_assessment
({})
self
.
assertTrue
(
resp
.
body
.
find
(
'Tuesday, April 01, 2014'
))
self
.
assertTrue
(
resp
.
body
.
find
(
'Thursday, May 01, 2014'
))
@scenario
(
'data/basic_scenario.xml'
,
user_id
=
'Bob'
)
@scenario
(
'data/basic_scenario.xml'
,
user_id
=
'Bob'
)
def
test_default_fields
(
self
,
xblock
):
def
test_default_fields
(
self
,
xblock
):
...
...
apps/openassessment/xblock/test/test_studio.py
View file @
4c473af4
...
@@ -48,7 +48,7 @@ class StudioViewTest(XBlockHandlerTestCase):
...
@@ -48,7 +48,7 @@ class StudioViewTest(XBlockHandlerTestCase):
# Set the XBlock's release date to the future,
# Set the XBlock's release date to the future,
# so we are not restricted in what we can edit
# so we are not restricted in what we can edit
xblock
.
start
=
dt
.
datetime
(
3000
,
1
,
1
)
.
replace
(
tzinfo
=
pytz
.
utc
)
.
isoformat
()
xblock
.
start
=
dt
.
datetime
(
3000
,
1
,
1
)
.
replace
(
tzinfo
=
pytz
.
utc
)
request
=
json
.
dumps
({
'xml'
:
self
.
load_fixture_str
(
'data/updated_block.xml'
)})
request
=
json
.
dumps
({
'xml'
:
self
.
load_fixture_str
(
'data/updated_block.xml'
)})
...
...
apps/openassessment/xblock/test/test_xml.py
View file @
4c473af4
...
@@ -2,8 +2,11 @@
...
@@ -2,8 +2,11 @@
Tests for serializing to/from XML.
Tests for serializing to/from XML.
"""
"""
import
copy
import
copy
import
datetime
as
dt
import
mock
import
mock
import
lxml.etree
as
etree
import
lxml.etree
as
etree
import
pytz
import
dateutil.parser
from
django.test
import
TestCase
from
django.test
import
TestCase
from
ddt
import
ddt
,
data
,
file_data
,
unpack
from
ddt
import
ddt
,
data
,
file_data
,
unpack
from
openassessment.xblock.openassessmentblock
import
OpenAssessmentBlock
,
UI_MODELS
from
openassessment.xblock.openassessmentblock
import
OpenAssessmentBlock
,
UI_MODELS
...
@@ -12,6 +15,22 @@ from openassessment.xblock.xml import (
...
@@ -12,6 +15,22 @@ from openassessment.xblock.xml import (
)
)
def
_parse_date
(
value
):
"""
Parse test-data date into a TZ-aware datetime.
Args:
value (string or None): The value to parse.
Returns:
TZ-aware datetime or None.
"""
if
value
is
None
:
return
value
else
:
return
dateutil
.
parser
.
parse
(
value
)
.
replace
(
tzinfo
=
pytz
.
utc
)
@ddt
@ddt
class
TestSerializeContent
(
TestCase
):
class
TestSerializeContent
(
TestCase
):
"""
"""
...
@@ -56,12 +75,13 @@ class TestSerializeContent(TestCase):
...
@@ -56,12 +75,13 @@ class TestSerializeContent(TestCase):
"""
"""
self
.
oa_block
=
mock
.
MagicMock
(
OpenAssessmentBlock
)
self
.
oa_block
=
mock
.
MagicMock
(
OpenAssessmentBlock
)
@file_data
(
'data/serialize.json'
)
@file_data
(
'data/serialize.json'
)
def
test_serialize
(
self
,
data
):
def
test_serialize
(
self
,
data
):
self
.
oa_block
.
title
=
data
[
'title'
]
self
.
oa_block
.
title
=
data
[
'title'
]
self
.
oa_block
.
prompt
=
data
[
'prompt'
]
self
.
oa_block
.
prompt
=
data
[
'prompt'
]
self
.
oa_block
.
start
=
data
[
'start'
]
self
.
oa_block
.
start
=
_parse_date
(
data
[
'start'
])
self
.
oa_block
.
due
=
data
[
'due'
]
self
.
oa_block
.
due
=
_parse_date
(
data
[
'due'
])
self
.
oa_block
.
submission_due
=
data
[
'submission_due'
]
self
.
oa_block
.
submission_due
=
data
[
'submission_due'
]
self
.
oa_block
.
rubric_criteria
=
data
[
'criteria'
]
self
.
oa_block
.
rubric_criteria
=
data
[
'criteria'
]
self
.
oa_block
.
rubric_assessments
=
data
[
'assessments'
]
self
.
oa_block
.
rubric_assessments
=
data
[
'assessments'
]
...
@@ -278,8 +298,8 @@ class TestUpdateFromXml(TestCase):
...
@@ -278,8 +298,8 @@ class TestUpdateFromXml(TestCase):
self
.
oa_block
.
rubric_criteria
=
dict
()
self
.
oa_block
.
rubric_criteria
=
dict
()
self
.
oa_block
.
rubric_assessments
=
list
()
self
.
oa_block
.
rubric_assessments
=
list
()
self
.
oa_block
.
start
=
"2000-01-01T00:00:00"
self
.
oa_block
.
start
=
dt
.
datetime
(
2000
,
1
,
1
)
.
replace
(
tzinfo
=
pytz
.
utc
)
self
.
oa_block
.
due
=
"3000-01-01T00:00:00"
self
.
oa_block
.
due
=
dt
.
datetime
(
3000
,
1
,
1
)
.
replace
(
tzinfo
=
pytz
.
utc
)
self
.
oa_block
.
submission_due
=
"2000-01-01T00:00:00"
self
.
oa_block
.
submission_due
=
"2000-01-01T00:00:00"
@file_data
(
'data/update_from_xml.json'
)
@file_data
(
'data/update_from_xml.json'
)
...
@@ -294,8 +314,8 @@ class TestUpdateFromXml(TestCase):
...
@@ -294,8 +314,8 @@ class TestUpdateFromXml(TestCase):
# Check that the contents of the modified XBlock are correct
# Check that the contents of the modified XBlock are correct
self
.
assertEqual
(
self
.
oa_block
.
title
,
data
[
'title'
])
self
.
assertEqual
(
self
.
oa_block
.
title
,
data
[
'title'
])
self
.
assertEqual
(
self
.
oa_block
.
prompt
,
data
[
'prompt'
])
self
.
assertEqual
(
self
.
oa_block
.
prompt
,
data
[
'prompt'
])
self
.
assertEqual
(
self
.
oa_block
.
start
,
data
[
'start'
]
)
self
.
assertEqual
(
self
.
oa_block
.
start
,
_parse_date
(
data
[
'start'
])
)
self
.
assertEqual
(
self
.
oa_block
.
due
,
data
[
'due'
]
)
self
.
assertEqual
(
self
.
oa_block
.
due
,
_parse_date
(
data
[
'due'
])
)
self
.
assertEqual
(
self
.
oa_block
.
submission_due
,
data
[
'submission_due'
])
self
.
assertEqual
(
self
.
oa_block
.
submission_due
,
data
[
'submission_due'
])
self
.
assertEqual
(
self
.
oa_block
.
rubric_criteria
,
data
[
'criteria'
])
self
.
assertEqual
(
self
.
oa_block
.
rubric_criteria
,
data
[
'criteria'
])
self
.
assertEqual
(
self
.
oa_block
.
rubric_assessments
,
data
[
'assessments'
])
self
.
assertEqual
(
self
.
oa_block
.
rubric_assessments
,
data
[
'assessments'
])
...
@@ -314,4 +334,4 @@ class TestUpdateFromXml(TestCase):
...
@@ -314,4 +334,4 @@ class TestUpdateFromXml(TestCase):
update_from_xml_str
(
update_from_xml_str
(
self
.
oa_block
,
""
.
join
(
data
[
'xml'
]),
self
.
oa_block
,
""
.
join
(
data
[
'xml'
]),
validator
=
lambda
*
args
:
(
False
,
''
)
validator
=
lambda
*
args
:
(
False
,
''
)
)
)
\ No newline at end of file
requirements/base.txt
View file @
4c473af4
# edX Internal Requirements
# edX Internal Requirements
git+https://github.com/edx/XBlock.git@c
4055bc1
#egg=XBlock
git+https://github.com/edx/XBlock.git@c
7ef611727d89887a258c5d4774a6efbda36cb13
#egg=XBlock
git+https://github.com/ormsbee/xblock-sdk.git@4f62e508#egg=xblock-sdk
git+https://github.com/ormsbee/xblock-sdk.git@4f62e508#egg=xblock-sdk
# Third Party Requirements
# Third Party Requirements
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment