Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
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-platform
Commits
1abeec78
Commit
1abeec78
authored
Jan 27, 2012
by
Bridger Maxwell
Browse files
Options
Browse Files
Download
Plain Diff
Merge
parents
ca44cf07
cbd8a964
Show whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
181 additions
and
26 deletions
+181
-26
auth/views.py
+2
-0
courseware/capa/capa_problem.py
+1
-1
courseware/capa/responsetypes.py
+5
-1
courseware/capa/unit.py
+130
-0
courseware/modules/video_module.py
+22
-18
settings_new_askbot.py
+2
-1
staticbook/views.py
+1
-1
track/middleware.py
+4
-3
urls.py
+1
-1
util/middleware.py
+13
-0
No files found.
auth/views.py
View file @
1abeec78
...
@@ -74,8 +74,10 @@ def login_user(request, error=""):
...
@@ -74,8 +74,10 @@ def login_user(request, error=""):
log
.
critical
(
"Login failed - Could not create session. Is memcached running?"
)
log
.
critical
(
"Login failed - Could not create session. Is memcached running?"
)
log
.
exception
(
e
)
log
.
exception
(
e
)
log
.
info
(
"Login success - {0} ({1})"
.
format
(
username
,
email
))
return
HttpResponse
(
json
.
dumps
({
'success'
:
True
}))
return
HttpResponse
(
json
.
dumps
({
'success'
:
True
}))
log
.
warning
(
"Login failed - Account not active for user {0}"
.
format
(
username
))
return
HttpResponse
(
json
.
dumps
({
'success'
:
False
,
return
HttpResponse
(
json
.
dumps
({
'success'
:
False
,
'error'
:
'Account not active. Check your e-mail.'
}))
'error'
:
'Account not active. Check your e-mail.'
}))
...
...
courseware/capa/capa_problem.py
View file @
1abeec78
...
@@ -133,7 +133,7 @@ class LoncapaProblem(object):
...
@@ -133,7 +133,7 @@ class LoncapaProblem(object):
for
entry
in
problems_simple
.
xpath
(
"//"
+
"|//"
.
join
(
response_properties
+
entry_types
)):
for
entry
in
problems_simple
.
xpath
(
"//"
+
"|//"
.
join
(
response_properties
+
entry_types
)):
answer
=
entry
.
get
(
'correct_answer'
)
answer
=
entry
.
get
(
'correct_answer'
)
if
answer
!=
None
:
if
answer
!=
None
:
answer_map
[
entry
.
get
(
'id'
)]
=
contextualize_text
(
answer
,
self
.
context
()
)
answer_map
[
entry
.
get
(
'id'
)]
=
contextualize_text
(
answer
,
self
.
context
)
return
answer_map
return
answer_map
...
...
courseware/capa/responsetypes.py
View file @
1abeec78
...
@@ -3,12 +3,16 @@ from util import contextualize_text
...
@@ -3,12 +3,16 @@ from util import contextualize_text
from
calc
import
evaluator
from
calc
import
evaluator
import
random
,
math
import
random
,
math
from
django.conf
import
settings
from
django.conf
import
settings
import
eia
import
calc
# TODO: Should be the same object as in capa_problem
# TODO: Should be the same object as in capa_problem
global_context
=
{
'random'
:
random
,
global_context
=
{
'random'
:
random
,
'numpy'
:
numpy
,
'numpy'
:
numpy
,
'math'
:
math
,
'math'
:
math
,
'scipy'
:
scipy
}
'scipy'
:
scipy
,
'calc'
:
calc
,
'eia'
:
eia
}
class
numericalresponse
(
object
):
class
numericalresponse
(
object
):
def
__init__
(
self
,
xml
,
context
):
def
__init__
(
self
,
xml
,
context
):
...
...
courseware/capa/unit.py
0 → 100644
View file @
1abeec78
import
math
from
numpy
import
eye
,
array
import
operator
from
pyparsing
import
Word
,
alphas
,
nums
,
oneOf
,
Literal
from
pyparsing
import
ZeroOrMore
,
OneOrMore
,
StringStart
from
pyparsing
import
StringEnd
,
Optional
,
Forward
from
pyparsing
import
CaselessLiteral
,
Group
,
StringEnd
from
pyparsing
import
NoMatch
,
stringEnd
base_units
=
[
'meter'
,
'gram'
,
'second'
,
'ampere'
,
'kelvin'
,
'mole'
,
'cd'
]
unit_vectors
=
dict
([(
base_units
[
i
],
eye
(
len
(
base_units
))[:,
i
])
for
i
in
range
(
len
(
base_units
))])
def
unit_evaluator
(
unit_string
,
units
=
unit_map
):
''' Evaluate an expression. Variables are passed as a dictionary
from string to value. Unary functions are passed as a dictionary
from string to function '''
if
string
.
strip
()
==
""
:
return
float
(
'nan'
)
ops
=
{
"^"
:
operator
.
pow
,
"*"
:
operator
.
mul
,
"/"
:
operator
.
truediv
,
}
prefixes
=
{
'
%
'
:
0.01
,
'k'
:
1e3
,
'M'
:
1e6
,
'G'
:
1e9
,
'T'
:
1e12
,
#'P':1e15,'E':1e18,'Z':1e21,'Y':1e24,
'c'
:
1e-2
,
'm'
:
1e-3
,
'u'
:
1e-6
,
'n'
:
1e-9
,
'p'
:
1e-12
}
#,'f':1e-15,'a':1e-18,'z':1e-21,'y':1e-24}
def
super_float
(
text
):
''' Like float, but with si extensions. 1k goes to 1000'''
if
text
[
-
1
]
in
suffixes
:
return
float
(
text
[:
-
1
])
*
suffixes
[
text
[
-
1
]]
else
:
return
float
(
text
)
def
number_parse_action
(
x
):
# [ '7' ] -> [ 7 ]
return
[
super_float
(
""
.
join
(
x
))]
def
exp_parse_action
(
x
):
# [ 2 ^ 3 ^ 2 ] -> 512
x
=
[
e
for
e
in
x
if
type
(
e
)
==
float
]
# Ignore ^
x
.
reverse
()
x
=
reduce
(
lambda
a
,
b
:
b
**
a
,
x
)
return
x
def
parallel
(
x
):
# Parallel resistors [ 1 2 ] => 2/3
if
len
(
x
)
==
1
:
return
x
[
0
]
if
0
in
x
:
return
float
(
'nan'
)
x
=
[
1.
/
e
for
e
in
x
if
type
(
e
)
==
float
]
# Ignore ^
return
1.
/
sum
(
x
)
def
sum_parse_action
(
x
):
# [ 1 + 2 - 3 ] -> 0
total
=
0.0
op
=
ops
[
'+'
]
for
e
in
x
:
if
e
in
set
(
'+-'
):
op
=
ops
[
e
]
else
:
total
=
op
(
total
,
e
)
return
total
def
prod_parse_action
(
x
):
# [ 1 * 2 / 3 ] => 0.66
prod
=
1.0
op
=
ops
[
'*'
]
for
e
in
x
:
if
e
in
set
(
'*/'
):
op
=
ops
[
e
]
else
:
prod
=
op
(
prod
,
e
)
return
prod
def
func_parse_action
(
x
):
return
[
functions
[
x
[
0
]](
x
[
1
])]
number_suffix
=
reduce
(
lambda
a
,
b
:
a
|
b
,
map
(
Literal
,
suffixes
.
keys
()),
NoMatch
())
# SI suffixes and percent
(
dot
,
minus
,
plus
,
times
,
div
,
lpar
,
rpar
,
exp
)
=
map
(
Literal
,
".-+*/()^"
)
number_part
=
Word
(
nums
)
inner_number
=
(
number_part
+
Optional
(
"."
+
number_part
)
)
|
(
"."
+
number_part
)
# 0.33 or 7 or .34
number
=
Optional
(
minus
|
plus
)
+
inner_number
+
\
Optional
(
CaselessLiteral
(
"E"
)
+
Optional
(
"-"
)
+
number_part
)
+
\
Optional
(
number_suffix
)
# 0.33k or -17
number
=
number
.
setParseAction
(
number_parse_action
)
# Convert to number
# Predefine recursive variables
expr
=
Forward
()
factor
=
Forward
()
def
sreduce
(
f
,
l
):
''' Same as reduce, but handle len 1 and len 0 lists sensibly '''
if
len
(
l
)
==
0
:
return
NoMatch
()
if
len
(
l
)
==
1
:
return
l
[
0
]
return
reduce
(
f
,
l
)
# Handle variables passed in. E.g. if we have {'R':0.5}, we make the substitution.
# Special case for no variables because of how we understand PyParsing is put together
if
len
(
variables
)
>
0
:
varnames
=
sreduce
(
lambda
x
,
y
:
x
|
y
,
map
(
lambda
x
:
CaselessLiteral
(
x
),
variables
.
keys
()))
varnames
.
setParseAction
(
lambda
x
:
map
(
lambda
y
:
variables
[
y
],
x
))
else
:
varnames
=
NoMatch
()
# Same thing for functions.
if
len
(
functions
)
>
0
:
funcnames
=
sreduce
(
lambda
x
,
y
:
x
|
y
,
map
(
lambda
x
:
CaselessLiteral
(
x
),
functions
.
keys
()))
function
=
funcnames
+
lpar
.
suppress
()
+
expr
+
rpar
.
suppress
()
function
.
setParseAction
(
func_parse_action
)
else
:
function
=
NoMatch
()
atom
=
number
|
varnames
|
lpar
+
expr
+
rpar
|
function
factor
<<
(
atom
+
ZeroOrMore
(
exp
+
atom
))
.
setParseAction
(
exp_parse_action
)
# 7^6
paritem
=
factor
+
ZeroOrMore
(
Literal
(
'||'
)
+
factor
)
# 5k || 4k
paritem
=
paritem
.
setParseAction
(
parallel
)
term
=
paritem
+
ZeroOrMore
((
times
|
div
)
+
paritem
)
# 7 * 5 / 4 - 3
term
=
term
.
setParseAction
(
prod_parse_action
)
expr
<<
Optional
((
plus
|
minus
))
+
term
+
ZeroOrMore
((
plus
|
minus
)
+
term
)
# -5 + 4 - 3
expr
=
expr
.
setParseAction
(
sum_parse_action
)
return
(
expr
+
stringEnd
)
.
parseString
(
string
)[
0
]
if
__name__
==
'__main__'
:
variables
=
{
'R1'
:
2.0
,
'R3'
:
4.0
}
functions
=
{
'sin'
:
math
.
sin
,
'cos'
:
math
.
cos
}
print
"X"
,
evaluator
(
variables
,
functions
,
"10000||sin(7+5)-6k"
)
print
"X"
,
evaluator
(
variables
,
functions
,
"13"
)
print
evaluator
({
'R1'
:
2.0
,
'R3'
:
4.0
},
{},
"13"
)
#
print
evaluator
({
'a'
:
2.2997471478310274
,
'k'
:
9
,
'm'
:
8
,
'x'
:
0.66009498411213041
},
{},
"5"
)
print
evaluator
({},{},
"-1"
)
print
evaluator
({},{},
"-(7+5)"
)
print
evaluator
({},{},
"-0.33"
)
print
evaluator
({},{},
"-.33"
)
print
evaluator
({},{},
"5+7 QWSEKO"
)
courseware/modules/video_module.py
View file @
1abeec78
from
x_module
import
XModule
import
logging
from
lxml
import
etree
import
json
import
json
## TODO: Abstract out from Django
## TODO: Abstract out from Django
from
django.conf
import
settings
from
django.conf
import
settings
from
djangomako.shortcuts
import
render_to_response
,
render_to_string
from
djangomako.shortcuts
import
render_to_response
,
render_to_string
from
lxml
import
etree
from
x_module
import
XModule
log
=
logging
.
getLogger
(
"mitx.courseware.modules"
)
class
VideoModule
(
XModule
):
class
VideoModule
(
XModule
):
#id_attribute = 'youtube'
#id_attribute = 'youtube'
video_time
=
0
video_time
=
0
def
handle_ajax
(
self
,
dispatch
,
get
):
def
handle_ajax
(
self
,
dispatch
,
get
):
print
"GET"
,
get
log
.
debug
(
u"GET {0}"
.
format
(
get
))
print
"DISPATCH"
,
dispatch
log
.
debug
(
u"DISPATCH {0}"
.
format
(
dispatch
))
if
dispatch
==
'goto_position'
:
if
dispatch
==
'goto_position'
:
self
.
position
=
int
(
float
(
get
[
'position'
]))
self
.
position
=
int
(
float
(
get
[
'position'
]))
print
"NEW POSITION"
,
self
.
position
log
.
debug
(
u"NEW POSITION {0}"
.
format
(
self
.
position
))
return
json
.
dumps
({
'success'
:
True
})
return
json
.
dumps
({
'success'
:
True
})
raise
Http404
()
raise
Http404
()
def
get_state
(
self
):
def
get_state
(
self
):
print
"STATE POSITION"
,
self
.
position
log
.
debug
(
u"STATE POSITION {0}"
.
format
(
self
.
position
))
return
json
.
dumps
({
'position'
:
self
.
position
})
return
json
.
dumps
({
'position'
:
self
.
position
})
def
get_xml_tags
():
def
get_xml_tags
():
'''
Tags in the courseware file guaranteed to correspond to the module
'''
'''
Tags in the courseware file guaranteed to correspond to the module
'''
return
"video"
return
"video"
def
video_list
(
self
):
def
video_list
(
self
):
l
=
self
.
youtube
.
split
(
','
)
l
=
self
.
youtube
.
split
(
','
)
l
=
[
i
.
split
(
":"
)
for
i
in
l
]
l
=
[
i
.
split
(
":"
)
for
i
in
l
]
return
json
.
dumps
(
dict
(
l
))
return
json
.
dumps
(
dict
(
l
))
def
get_html
(
self
):
def
get_html
(
self
):
...
@@ -39,24 +42,25 @@ class VideoModule(XModule):
...
@@ -39,24 +42,25 @@ class VideoModule(XModule):
'position'
:
self
.
position
})
'position'
:
self
.
position
})
def
get_init_js
(
self
):
def
get_init_js
(
self
):
'''
JavaScript code to be run when problem is shown. Be aware
'''JavaScript code to be run when problem is shown. Be aware
that this may happen several times on the same page
that this may happen several times on the same page
(e.g. student switching tabs). Common functions should be put
(e.g. student switching tabs). Common functions should be put
in the main course .js files for now. '''
in the main course .js files for now. '''
print
"INIT POSITION"
,
self
.
position
log
.
debug
(
u"INIT POSITION {0}"
.
format
(
self
.
position
))
return
render_to_string
(
'video_init.js'
,{
'streams'
:
self
.
video_list
(),
return
render_to_string
(
'video_init.js'
,{
'streams'
:
self
.
video_list
(),
'id'
:
self
.
item_id
,
'id'
:
self
.
item_id
,
'position'
:
self
.
position
})
'position'
:
self
.
position
})
def
get_destroy_js
(
self
):
def
get_destroy_js
(
self
):
return
"videoDestroy(
\"
"
+
self
.
item_id
+
"
\"
);"
return
"videoDestroy(
\"
{0}
\"
);"
.
format
(
self
.
item_id
)
def
__init__
(
self
,
xml
,
item_id
,
ajax_url
=
None
,
track_url
=
None
,
state
=
None
,
track_function
=
None
,
render_function
=
None
):
def
__init__
(
self
,
xml
,
item_id
,
ajax_url
=
None
,
track_url
=
None
,
state
=
None
,
track_function
=
None
,
render_function
=
None
):
XModule
.
__init__
(
self
,
xml
,
item_id
,
ajax_url
,
track_url
,
state
,
track_function
,
render_function
)
XModule
.
__init__
(
self
,
xml
,
item_id
,
ajax_url
,
track_url
,
state
,
track_function
,
render_function
)
self
.
youtube
=
etree
.
XML
(
xml
)
.
get
(
'youtube'
)
self
.
youtube
=
etree
.
XML
(
xml
)
.
get
(
'youtube'
)
self
.
position
=
0
self
.
position
=
0
if
state
!=
None
:
if
state
!=
None
:
state
=
json
.
loads
(
state
)
state
=
json
.
loads
(
state
)
if
'position'
in
state
:
self
.
position
=
int
(
float
(
state
[
'position'
]))
if
'position'
in
state
:
print
"POOSITION IN STATE"
self
.
position
=
int
(
float
(
state
[
'position'
]))
print
"LOAD POSITION"
,
self
.
position
log
.
debug
(
"POSITION IN STATE"
)
log
.
debug
(
u"LOAD POSITION {0}"
.
format
(
self
.
position
))
settings_new_askbot.py
View file @
1abeec78
...
@@ -155,7 +155,7 @@ LOGGING = {
...
@@ -155,7 +155,7 @@ LOGGING = {
'stream'
:
sys
.
stderr
,
'stream'
:
sys
.
stderr
,
},
},
'app'
:
{
'app'
:
{
'level'
:
'INFO'
,
'level'
:
'
DEBUG'
if
DEBUG
else
'
INFO'
,
'class'
:
'logging.handlers.TimedRotatingFileHandler'
,
'class'
:
'logging.handlers.TimedRotatingFileHandler'
,
'formatter'
:
'standard'
,
'formatter'
:
'standard'
,
'filename'
:
LOG_DIR
+
'/mitx.log'
,
# temporary location for proof of concept
'filename'
:
LOG_DIR
+
'/mitx.log'
,
# temporary location for proof of concept
...
@@ -262,6 +262,7 @@ site.addsitedir(os.path.join(os.path.dirname(askbot.__file__), 'deps'))
...
@@ -262,6 +262,7 @@ site.addsitedir(os.path.join(os.path.dirname(askbot.__file__), 'deps'))
TEMPLATE_LOADERS
=
TEMPLATE_LOADERS
+
(
'askbot.skins.loaders.filesystem_load_template_source'
,)
TEMPLATE_LOADERS
=
TEMPLATE_LOADERS
+
(
'askbot.skins.loaders.filesystem_load_template_source'
,)
MIDDLEWARE_CLASSES
=
MIDDLEWARE_CLASSES
+
(
MIDDLEWARE_CLASSES
=
MIDDLEWARE_CLASSES
+
(
'util.middleware.ExceptionLoggingMiddleware'
,
'askbot.middleware.anon_user.ConnectToSessionMessagesMiddleware'
,
'askbot.middleware.anon_user.ConnectToSessionMessagesMiddleware'
,
'askbot.middleware.forum_mode.ForumModeMiddleware'
,
'askbot.middleware.forum_mode.ForumModeMiddleware'
,
'askbot.middleware.cancel.CancelActionMiddleware'
,
'askbot.middleware.cancel.CancelActionMiddleware'
,
...
...
staticbook/views.py
View file @
1abeec78
...
@@ -5,7 +5,7 @@ import os
...
@@ -5,7 +5,7 @@ import os
from
django.conf
import
settings
from
django.conf
import
settings
from
django.http
import
Http404
from
django.http
import
Http404
def
index
(
request
,
page
=
1
):
def
index
(
request
,
page
=
0
):
if
not
request
.
user
.
is_authenticated
():
if
not
request
.
user
.
is_authenticated
():
return
redirect
(
'/'
)
return
redirect
(
'/'
)
return
render_to_response
(
'staticbook.html'
,{
'page'
:
int
(
page
)})
return
render_to_response
(
'staticbook.html'
,{
'page'
:
int
(
page
)})
track/middleware.py
View file @
1abeec78
...
@@ -5,10 +5,11 @@ from django.conf import settings
...
@@ -5,10 +5,11 @@ from django.conf import settings
import
views
import
views
class
TrackMiddleware
:
class
TrackMiddleware
:
def
process_request
(
self
,
request
):
def
process_request
(
self
,
request
):
try
:
try
:
# We're already logging events
# We're already logging events, and we don't want to capture user
if
request
.
META
[
'PATH_INFO'
]
==
'/event'
:
# names/passwords.
if
request
.
META
[
'PATH_INFO'
]
in
[
'/event'
,
'/login'
]:
return
return
event
=
{
'GET'
:
dict
(
request
.
GET
),
event
=
{
'GET'
:
dict
(
request
.
GET
),
...
...
urls.py
View file @
1abeec78
...
@@ -19,7 +19,7 @@ urlpatterns = ('',
...
@@ -19,7 +19,7 @@ urlpatterns = ('',
url
(
r'^activate/(?P<key>[^/]*)$'
,
'auth.views.activate_account'
),
url
(
r'^activate/(?P<key>[^/]*)$'
,
'auth.views.activate_account'
),
url
(
r'^$'
,
'auth.views.index'
),
url
(
r'^$'
,
'auth.views.index'
),
url
(
r'^password_reset/$'
,
'django.contrib.auth.views.password_reset'
,
url
(
r'^password_reset/$'
,
'django.contrib.auth.views.password_reset'
,
dict
(
from_email
=
'
6002-admin@
mit.edu'
),
name
=
'auth_password_reset'
),
dict
(
from_email
=
'
registration@mitx.
mit.edu'
),
name
=
'auth_password_reset'
),
url
(
r'^password_change/$'
,
django
.
contrib
.
auth
.
views
.
password_change
,
name
=
'auth_password_change'
),
url
(
r'^password_change/$'
,
django
.
contrib
.
auth
.
views
.
password_change
,
name
=
'auth_password_change'
),
url
(
r'^password_change_done/$'
,
django
.
contrib
.
auth
.
views
.
password_change_done
,
name
=
'auth_password_change_done'
),
url
(
r'^password_change_done/$'
,
django
.
contrib
.
auth
.
views
.
password_change_done
,
name
=
'auth_password_change_done'
),
url
(
r'^password_reset_confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$'
,
django
.
contrib
.
auth
.
views
.
password_reset_confirm
,
url
(
r'^password_reset_confirm/(?P<uidb36>[0-9A-Za-z]+)-(?P<token>.+)/$'
,
django
.
contrib
.
auth
.
views
.
password_reset_confirm
,
...
...
util/middleware.py
0 → 100644
View file @
1abeec78
import
logging
from
django.http
import
HttpResponse
log
=
logging
.
getLogger
(
"mitx"
)
class
ExceptionLoggingMiddleware
(
object
):
"""Just here to log unchecked exceptions that go all the way up the Django
stack"""
def
process_exception
(
self
,
request
,
exception
):
log
.
exception
(
exception
)
return
HttpResponse
(
"Server Error - Please try again later."
)
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