Merge remote-tracking branch 'origin/master' into 700x-sandbox
This commit is contained in:
@@ -9,6 +9,7 @@ gfortran
|
||||
liblapack-dev
|
||||
libfreetype6-dev
|
||||
libpng12-dev
|
||||
libjpeg-dev
|
||||
libxml2-dev
|
||||
libxslt-dev
|
||||
yui-compressor
|
||||
|
||||
@@ -107,6 +107,8 @@
|
||||
<script type="text/javascript" src="${static.url('js/models/course_relative.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/views/grader-select-view.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/models/settings/course_grading_policy.js')}"></script>
|
||||
<script type="text/javascript" src="${static.url('js/views/overview.js')}"></script>
|
||||
|
||||
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
|
||||
@@ -77,9 +77,13 @@ def replace_static_urls(text, data_directory, course_namespace=None):
|
||||
# course_namespace is not None, then use studio style urls
|
||||
if course_namespace is not None and not isinstance(modulestore(), XMLModuleStore):
|
||||
url = StaticContent.convert_legacy_static_url(rest, course_namespace)
|
||||
# In debug mode, if we can find the url as is,
|
||||
elif settings.DEBUG and finders.find(rest, True):
|
||||
return original
|
||||
# Otherwise, look the file up in staticfiles_storage, and append the data directory if needed
|
||||
else:
|
||||
course_path = "/".join((data_directory, rest))
|
||||
|
||||
try:
|
||||
if staticfiles_storage.exists(rest):
|
||||
url = staticfiles_storage.url(rest)
|
||||
|
||||
@@ -128,6 +128,17 @@ class VideoModule(XModule):
|
||||
else:
|
||||
caption_asset_path = StaticContent.get_base_url_path_for_course_assets(self.location) + '/subs_'
|
||||
|
||||
# We normally let JS parse this, but in the case that we need a hacked
|
||||
# out <object> player because YouTube has broken their <iframe> API for
|
||||
# the third time in a year, we need to extract it server side.
|
||||
normal_speed_video_id = None # The 1.0 speed video
|
||||
|
||||
# video_list() example:
|
||||
# "0.75:nugHYNiD3fI,1.0:7m8pab1MfYY,1.25:3CxdPGXShq8,1.50:F-D7bOFCnXA"
|
||||
for video_id_str in self.video_list().split(","):
|
||||
if video_id_str.startswith("1.0:"):
|
||||
normal_speed_video_id = video_id_str.split(":")[1]
|
||||
|
||||
return self.system.render_template('video.html', {
|
||||
'streams': self.video_list(),
|
||||
'id': self.location.html_id(),
|
||||
@@ -140,7 +151,8 @@ class VideoModule(XModule):
|
||||
'caption_asset_path': caption_asset_path,
|
||||
'show_captions': self.show_captions,
|
||||
'start': self.start_time,
|
||||
'end': self.end_time
|
||||
'end': self.end_time,
|
||||
'normal_speed_video_id': normal_speed_video_id
|
||||
})
|
||||
|
||||
|
||||
|
||||
@@ -385,6 +385,46 @@ def instructor_dashboard(request, course_id):
|
||||
user.groups.remove(group)
|
||||
track.views.server_track(request, 'remove-instructor {0}'.format(user), {}, page='idashboard')
|
||||
|
||||
#----------------------------------------
|
||||
# DataDump
|
||||
|
||||
elif 'Download CSV of all student profile data' in action:
|
||||
enrolled_students = User.objects.filter(courseenrollment__course_id=course_id).order_by('username').select_related("profile")
|
||||
profkeys = ['name', 'language', 'location', 'year_of_birth', 'gender', 'level_of_education',
|
||||
'mailing_address', 'goals']
|
||||
datatable = {'header': ['username', 'email'] + profkeys}
|
||||
def getdat(u):
|
||||
p = u.profile
|
||||
return [u.username, u.email] + [getattr(p,x,'') for x in profkeys]
|
||||
|
||||
datatable['data'] = [getdat(u) for u in enrolled_students]
|
||||
datatable['title'] = 'Student profile data for course %s' % course_id
|
||||
return return_csv('profiledata_%s.csv' % course_id, datatable)
|
||||
|
||||
|
||||
elif 'Download CSV of all responses to problem' in action:
|
||||
problem_to_dump = request.POST.get('problem_to_dump','')
|
||||
|
||||
if problem_to_dump[-4:]==".xml":
|
||||
problem_to_dump=problem_to_dump[:-4]
|
||||
try:
|
||||
(org, course_name, run)=course_id.split("/")
|
||||
module_state_key="i4x://"+org+"/"+course_name+"/problem/"+problem_to_dump
|
||||
smdat = StudentModule.objects.filter(course_id=course_id,
|
||||
module_state_key=module_state_key)
|
||||
smdat = smdat.order_by('student')
|
||||
msg+="Found module to reset. "
|
||||
except Exception as err:
|
||||
msg+="<font color='red'>Couldn't find module with that urlname. </font>"
|
||||
msg += "<pre>%s</pre>" % escape(err)
|
||||
smdat = []
|
||||
|
||||
if smdat:
|
||||
datatable = {'header': ['username', 'state']}
|
||||
datatable['data'] = [ [x.student.username, x.state] for x in smdat ]
|
||||
datatable['title'] = 'Student state for problem %s' % problem_to_dump
|
||||
return return_csv('student_state_from_%s.csv' % problem_to_dump, datatable)
|
||||
|
||||
#----------------------------------------
|
||||
# Group management
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ with open(ENV_ROOT / CONFIG_PREFIX + "env.json") as env_file:
|
||||
|
||||
SITE_NAME = ENV_TOKENS['SITE_NAME']
|
||||
SESSION_COOKIE_DOMAIN = ENV_TOKENS.get('SESSION_COOKIE_DOMAIN')
|
||||
CSRF_COOKIE_DOMAIN = ENV_TOKENS.get('SESSION_COOKIE_DOMAIN')
|
||||
|
||||
BOOK_URL = ENV_TOKENS['BOOK_URL']
|
||||
MEDIA_URL = ENV_TOKENS['MEDIA_URL']
|
||||
|
||||
@@ -81,6 +81,9 @@ MITX_FEATURES = {
|
||||
'AUTH_USE_OPENID': False,
|
||||
'AUTH_USE_MIT_CERTIFICATES': False,
|
||||
'AUTH_USE_OPENID_PROVIDER': False,
|
||||
|
||||
# Flip to True when the YouTube iframe API breaks (again)
|
||||
'USE_YOUTUBE_OBJECT_API': False,
|
||||
}
|
||||
|
||||
# Used for A/B testing
|
||||
|
||||
@@ -64,6 +64,7 @@ function goto( mode)
|
||||
<a href="#" onclick="goto('Admin');" class="${modeflag.get('Admin')}">Admin</a> |
|
||||
<a href="#" onclick="goto('Forum Admin');" class="${modeflag.get('Forum Admin')}">Forum Admin</a> |
|
||||
<a href="#" onclick="goto('Enrollment');" class="${modeflag.get('Enrollment')}">Enrollment</a> |
|
||||
<a href="#" onclick="goto('Data');" class="${modeflag.get('Data')}">DataDump</a> |
|
||||
<a href="#" onclick="goto('Manage Groups');" class="${modeflag.get('Manage Groups')}">Manage Groups</a> ]
|
||||
</h2>
|
||||
|
||||
@@ -269,6 +270,20 @@ function goto( mode)
|
||||
|
||||
##-----------------------------------------------------------------------------
|
||||
|
||||
%if modeflag.get('Data'):
|
||||
<hr width="40%" style="align:left">
|
||||
<p>
|
||||
<input type="submit" name="action" value="Download CSV of all student profile data">
|
||||
</p>
|
||||
<p> Problem urlname:
|
||||
<input type="text" name="problem_to_dump" size="40">
|
||||
<input type="submit" name="action" value="Download CSV of all responses to problem">
|
||||
</p>
|
||||
<hr width="40%" style="align:left">
|
||||
%endif
|
||||
|
||||
##-----------------------------------------------------------------------------
|
||||
|
||||
%if modeflag.get('Manage Groups'):
|
||||
%if instructor_access:
|
||||
<hr width="40%" style="align:left">
|
||||
|
||||
@@ -2,9 +2,19 @@
|
||||
<h2> ${display_name} </h2>
|
||||
% endif
|
||||
|
||||
|
||||
%if settings.MITX_FEATURES['STUB_VIDEO_FOR_TESTING']:
|
||||
<div id="stub_out_video_for_testing"></div>
|
||||
|
||||
%elif settings.MITX_FEATURES.get('USE_YOUTUBE_OBJECT_API') and normal_speed_video_id:
|
||||
<object width="640" height="390">
|
||||
<param name="movie"
|
||||
value="https://www.youtube.com/v/${normal_speed_video_id}?version=3&autoplay=1&rel=0"></param>
|
||||
<param name="allowScriptAccess" value="always"></param>
|
||||
<embed src="https://www.youtube.com/v/${normal_speed_video_id}?version=3&autoplay=1&rel=0"
|
||||
type="application/x-shockwave-flash"
|
||||
allowscriptaccess="always"
|
||||
width="640" height="390"></embed>
|
||||
</object>
|
||||
%else:
|
||||
<div id="video_${id}" class="video" data-streams="${streams}" data-caption-data-dir="${data_dir}" data-show-captions="${show_captions}" data-start="${start}" data-end="${end}" data-caption-asset-path="${caption_asset_path}">
|
||||
<div class="tc-wrapper">
|
||||
|
||||
Reference in New Issue
Block a user