def studio_view(self, context=None): html = self.resource_string("static/html/paellavideo_edit.html") options = "<option value='' >----</option>" for key in paellaservers.PAELLASERVERS: if self.server == key["url"]: options = ( options + "<option value='" + key["url"] + "' selected='selected' >" + key["name"] + "</option>" ) else: options = options + "<option value='" + key["url"] + "' >" + key["name"] + "</option>" selector = u""" <script type="text/template" id="xblock-equality-template"> </script> <select name='Server' id='edit_server'> {} </select>""".format( options ) frag = Fragment(html.format(self=self, selector=selector)) frag.add_javascript(self.resource_string("static/js/src/paellavideo_edit.js")) frag.initialize_js("paellaXBlock") return frag
def author_view(self, context): """ Renders the Studio preview view, which supports drag and drop. """ fragment = Fragment() contents = [] for child_key in self.children: # pylint: disable=E1101 context['reorderable_items'].add(child_key) child = self.runtime.get_block(child_key) rendered_child = self.runtime.render_child(child, StudioEditableModule.get_preview_view_name(child), context) fragment.add_frag_resources(rendered_child) contents.append({ 'id': unicode(child_key), 'content': rendered_child.content, }) fragment.add_content(self.runtime.render_template("studio_render_children_view.html", { 'items': contents, 'xblock_context': context, 'can_add': True, 'can_reorder': True, })) return fragment
def student_view(self, context): """ Renders the student view of the block in the LMS. """ fragment = Fragment() contents = [] child_context = {} if not context else copy(context) child_context['child_of_vertical'] = True # pylint: disable=no-member for child in self.get_display_items(): rendered_child = child.render(STUDENT_VIEW, child_context) fragment.add_frag_resources(rendered_child) contents.append({ 'id': child.location.to_deprecated_string(), 'content': rendered_child.content }) fragment.add_content(self.system.render_template('vert_module.html', { 'items': contents, 'xblock_context': context, })) return fragment
def studio_view(self, context=None): """Studio configuration view.""" html = self.resource_string("static/html/settings.html") frag = Fragment(html.format(query=self.query)) frag.add_javascript(self.resource_string("static/js/src/settings.js")) frag.initialize_js('MKWSRefSettings') return frag
def author_view(self, context): if self.question: return self.student_view(context) fragment = Fragment() fragment.add_content(messages.QUESTION_NOT_SELECTED) return fragment
def student_view(self, context=None): """ The primary view of the BadgerXBlock, shown to students when viewing courses. """ html = self.resource_string("static/html/badger.html") layout_html = "" for line in transform_layout(learning_map): new_item_html = layout_line(line) layout_html = layout_html + new_item_html html = html.replace("CSS", self.resource_string("static/css/badger.css")) html = html.replace("LAYOUT", layout_html) # circle = "" # for x in range(0,101,10): # circle = circle + html_line(x, 0, 100-x, 100) # circle = circle + html_line(50, -50, 50, 150) circle = "" #html_line(0,0,0,100) + html_line(0,100,100,200) + html_line(100,200,200,200) + html_line(200,200,300,100) + html_line(300,100,300,0) html = html.replace('CIRCLE', circle) frag = Fragment(html) #frag.add_css(self.resource_string("static/css/badger.css")) frag.add_javascript(self.resource_string("static/js/src/badger.js")) frag.initialize_js('BadgerXBlock') return frag
def student_view_aside(self, block, context): # pylint: disable=unused-argument """ Display the tag selector with specific categories and allowed values, depending on the context. """ if isinstance(block, CapaModule): tags = [] for tag in self.get_available_tags(): values = tag.get_values() current_value = self.saved_tags.get(tag.name, None) if current_value is not None and current_value not in values: values.insert(0, current_value) tags.append({ 'key': tag.name, 'title': tag.title, 'values': values, 'current_value': current_value }) fragment = Fragment(render_to_string('structured_tags_block.html', {'tags': tags, 'block_location': block.location})) fragment.add_javascript_url(self._get_studio_resource_url('/js/xblock_asides/structured_tags.js')) fragment.initialize_js('StructuredTagsInit') return fragment else: return Fragment(u'')
def studio_view(self, context=None): """ view function for studio edit """ html = self.resource_string("static/html/ubcpi_edit.html") frag = Fragment(html) frag.add_javascript(self.resource_string("static/js/src/ubcpi_edit.js")) frag.initialize_js('PIEdit', { 'display_name': self.ugettext(self.display_name), 'weight': self.weight, 'correct_answer': self.correct_answer, 'correct_rationale': self.correct_rationale, 'rationale_size': self.rationale_size, 'question_text': self.question_text, 'options': self.options, 'algo': self.algo, 'algos': { 'simple': self.ugettext('System will select one of each option to present to the students.'), 'random': self.ugettext('Completely random selection from the response pool.') }, 'image_position_locations': { 'above': self.ugettext('Appears above'), 'below': self.ugettext('Appears below') }, 'seeds': self.seeds, }) return frag
def student_view(self, context): """ Renders parameters to template. """ extension = self._get_extension(self.sourceurl) context = { 'course_key': self.runtime.course_id, 'display_name': self.display_name_with_default_escaped, 'instructions_html': self.instructions, 'sourceUrl': self.sourceurl, 'typeSource': extension, 'poster': self.poster_url, 'content_html': self.content, 'token': retrieve_token(self.user_email, self.annotation_token_secret), 'annotation_storage': self.annotation_storage_url, 'default_tab': self.default_tab, 'instructor_email': self.instructor_email, 'annotation_mode': self.annotation_mode, 'is_course_staff': self.is_course_staff, } fragment = Fragment(self.system.render_template('videoannotation.html', context)) # TinyMCE already exists in Studio so we should not load the files again # get_real_user always returns "None" in Studio since its runtimes contains no anonymous ids if self.runtime.get_real_user is not None: fragment.add_javascript_url(self.runtime.STATIC_URL + "js/vendor/tinymce/js/tinymce/tinymce.full.min.js") fragment.add_javascript_url(self.runtime.STATIC_URL + "js/vendor/tinymce/js/tinymce/jquery.tinymce.min.js") return fragment
def student_view(self, context=None): """ The primary view of the ContentXBlock, shown to students when viewing courses. """ if self.contnet_type == "content": result = Fragment() url = "public/html/"+self.short_name+".html" fragment = Fragment(self.resource_string(url)) html_template = Template(self.resource_string("templates/student_view.html")) html_context = Context({"fragment": fragment}) html_str = html_template.render(html_context) result.add_content(html_str) return result elif self.contnet_type == "topnav": html_context = Context({"source_link": self.source_link, "prev_link": self.prev_link, "prev_name": self.prev_name, "toc_link": self.toc_link, "next_link": self.next_link, "next_name": self.next_name, }) html_template = Template(self.resource_string("templates/student_view_topnav.html")) fragment = Fragment(html_template.render(html_context)) return fragment elif self.contnet_type == "header": return elif self.contnet_type == "footer": return
def _student_view(self, context, banner_text=None): """ Returns the rendered student view of the content of this sequential. If banner_text is given, it is added to the content. """ display_items = self.get_display_items() self._update_position(context, len(display_items)) fragment = Fragment() params = { 'items': self._render_student_view_for_items(context, display_items, fragment), 'element_id': self.location.html_id(), 'item_id': self.location.to_deprecated_string(), 'position': self.position, 'tag': self.location.category, 'ajax_url': self.system.ajax_url, 'next_url': context.get('next_url'), 'prev_url': context.get('prev_url'), 'banner_text': banner_text, } fragment.add_content(self.system.render_template("seq_module.html", params)) self._capture_full_seq_item_metrics(display_items) self._capture_current_unit_metrics(display_items) return fragment
def studio_view(self, context=None): template_context = {'lab_proxy_id': self.lab_proxy_id} if not self.lab_proxy_id: # fetch the proxies labs = requests.get(LAB_URL).json() template_context.update({ 'labs': labs, }) else: lab_proxy_url = "{}{}/".format(LAB_PROXY_URL, self.lab_proxy_id) lab_proxy = requests.get(lab_proxy_url).json() template_context.update({ 'lab_proxy': lab_proxy, }) html = render_template("templates/lab_studio.html", template_context) frag = Fragment(html) frag.add_javascript_url(self.runtime.local_resource_url(self, "public/js/labster_lab_studio.js")) frag.initialize_js('LabsterLabXBlock') return frag
def error_frag(msg): """ Build a fragment to display runtime errors. """ context = {'error_msg': msg} html = loader.render_template('static/html/error.html', context) frag = Fragment(html) frag.add_css_url(self.runtime.local_resource_url(self, 'public/css/main.css')) return frag
def dashboard_view(self, context): """ Renders stage content for dashboard view. :param dict context: :rtype: Fragment """ fragment = Fragment() target_workgroups = context.get(Constants.TARGET_WORKGROUPS) target_students = context.get(Constants.TARGET_STUDENTS) filtered_students = context.get(Constants.FILTERED_STUDENTS) students_to_display = [student for student in target_students if student.id not in filtered_students] state, stats = self.get_dashboard_stage_state(target_workgroups, students_to_display) human_stats = OrderedDict([ (StageState.get_human_name(StageState.NOT_STARTED), stats[StageState.NOT_STARTED]*100), (StageState.get_human_name(StageState.INCOMPLETE), stats[StageState.INCOMPLETE]*100), (StageState.get_human_name(StageState.COMPLETED), stats[StageState.COMPLETED]*100), ]) render_context = { 'stage': self, 'stats': human_stats, 'stage_state': state, 'ta_graded': self.activity.is_ta_graded } render_context.update(context) fragment.add_content(self.render_template('dashboard_view', render_context)) return fragment
def studio_view(self, context): """temporary for debug number of hosts=0""" html = self.resource_string("static/html/ssh_edit.html") frag = Fragment(html.format(self=self)) frag.add_javascript(self.resource_string("static/js/ssh_edit.js")) frag.initialize_js('SshEditXBlock') return frag
def studio_view(self, context=None): # pylint: disable=unused-argument """ Render the OpenAssessment XBlock for editing in Studio. Args: context: Not actively used for this view. Returns: (Fragment): An HTML fragment for editing the configuration of this XBlock. """ rendered_template = get_template( 'openassessmentblock/edit/oa_edit.html' ).render(self.editor_context()) fragment = Fragment(rendered_template) if settings.DEBUG: self.add_javascript_files(fragment, "static/js/src/oa_shared.js") self.add_javascript_files(fragment, "static/js/src/oa_server.js") self.add_javascript_files(fragment, "static/js/src/studio") else: # TODO: switch to add_javascript_url once XBlock resources are loaded from the CDN fragment.add_javascript(pkg_resources.resource_string(__name__, "static/js/openassessment-studio.min.js")) js_context_dict = { "FILE_EXT_BLACK_LIST": self.FILE_EXT_BLACK_LIST, } fragment.initialize_js('OpenAssessmentEditor', js_context_dict) return fragment
def studio_view(self, context=None): ''' The secondary view of the XBlock, shown to teachers when editing the XBlock. ''' context = { 'display_name': self.display_name, 'weight': self.weight, 'max_attempts': self.max_attempts, 'xml_data': self.question_string, 'your_answer_label': self.your_answer_label, 'our_answer_label': self.our_answer_label, 'submit_button_label': self.submit_button_label, } html = self.render_template( 'static/html/submit_and_compare_edit.html', context, ) frag = Fragment(html) frag.add_javascript( self.load_resource('static/js/submit_and_compare_edit.js'), ) frag.initialize_js('SubmitAndCompareXBlockInitEdit') return frag
def get_url_name_fragment(self, caption): fragment = Fragment() fragment.add_content(loader.render_template( "templates/html/url_name.html", {'url_name': self.url_name, 'caption': caption} )) return fragment
def _wrap_ele(self, block, frag, extra_data=None): """ Does the guts of the wrapping the same way for both xblocks and asides. Their wrappers provide other info in extra_data which gets put into the dom data- attrs. """ wrapped = Fragment() data = { 'usage': block.scope_ids.usage_id, 'block-type': block.scope_ids.block_type, } data.update(extra_data) if frag.js_init_fn: data['init'] = frag.js_init_fn data['runtime-version'] = frag.js_init_version json_init = "" # TODO/Note: We eventually want to remove: hasattr(frag, 'json_init_args') # However, I'd like to maintain backwards-compatibility with older XBlock # for at least a little while so as not to adversely effect developers. # pmitros/Jun 28, 2014. if hasattr(frag, 'json_init_args') and frag.json_init_args is not None: json_init = u'<script type="json/xblock-args" class="xblock_json_init_args">' + \ u'{data}</script>'.format(data=json.dumps(frag.json_init_args)) html = u"<div class='{}'{properties}>{body}{js}</div>".format( block.entry_point.replace('.', '-'), properties="".join(" data-%s='%s'" % item for item in data.items()), body=frag.body_html(), js=json_init) wrapped.add_content(html) wrapped.add_frag_resources(frag) return wrapped
def student_view(self, context): fragment = Fragment() contents = [] child_context = {} if not context else copy(context) child_context['child_of_vertical'] = True for child in self.get_display_items(): print print print "Type(child): ", type(child) print print rendered_child = child.render(STUDENT_VIEW, child_context) fragment.add_frag_resources(rendered_child) contents.append({ 'id': child.location.to_deprecated_string(), 'content': rendered_child.content }) fragment.add_content(self.system.render_template('vert_module.html', { 'items': contents, 'xblock_context': context, })) return fragment
def studio_view(self, context=None): """This is the view displaying xblock form in studio.""" logger.debug("On entre dans la partie prof") # logger.debug("self.max_id_question : %s", self.max_id_question) # logger.debug("self.dict_questions : %s", self.dict_questions) # logger.debug("self.max_id_studio_question : %s", self.max_id_studio_question) # logger.debug("self.dict_studio_questions : %s", self.dict_studio_questions) logger.debug(" self.var_test : %s", self.var_test) # q = "Que permet de faire le théorème de Bayes ? Donner un exemple ?" # r = "Il permet d'inverser des probabilités pourvu qu'on ait des connaissances préalables." # r_etu = "Si l'on connait P(A), P(B) et P(A|B),le théorème de Bayes nous permet de calculer P(B|A)." # for i in range(5): # self.add_studio_question(q, r) # logger.debug("self.max_id_question : %s", self.max_id_question) # logger.debug("self.dict_questions : %s", self.dict_questions) # logger.debug("self.max_id_studio_question : %s", self.max_id_studio_question) # logger.debug("self.dict_studio_questions : %s", self.dict_studio_questions) # logger.debug("self.var_test : %s", self.var_test) logger.debug("On sort de la partie prof") # self.t_prof_last_modif = time() frag = Fragment(self.resource_string("templates/studio.html")) frag.add_javascript(self.resource_string("static/js/src/p3exblock_studio.js")) frag.initialize_js('P3eXBlock') return frag
def student_view(self, context=None): """ The primary view of the XBlock, shown to students when viewing courses. """ context = { 'display_name': self.display_name, 'url': self.url, 'allow_download': self.allow_download, 'source_text': self.source_text, 'source_url': self.source_url } html = self.render_template('static/html/pdf_view.html', context) event_type = 'edx.pdf.loaded' event_data = { 'url': self.url, 'source_url': self.source_url, } self.runtime.publish(self, event_type, event_data) frag = Fragment(html) frag.add_javascript(self.load_resource("static/js/pdf_view.js")) frag.initialize_js('pdfXBlockInitView') return frag
def student_view(self, context=None): """ Create a fragment used to display the XBlock to a student `context` is a dictionary used to configure the display (unused). Returns a `Fragment` object specifying the HTML, CSS and JavaScript to display """ href = self.href or '' display_name = self.display_name or '' # Make the oEmbed call to get the embed code try: embed_code, width, height = self.get_embed_code(href) html_str = self.resource_string("static/html/officemix.html") except Exception as ex: html_str = self.resource_string("static/html/embed_error.html") frag = Fragment(html_str.format(self=self, exception=cgi.escape(str(ex)))) return frag # Grab and round the aspect ratio ratio = decimal.Decimal(float(height) / width * 100.0) # Construct the HTML frag = Fragment(html_str.format( self=self, embed_code=embed_code, display_name=cgi.escape(display_name))) # And construct the CSS css_str = self.resource_string("static/css/officemix.css") css_str = string.replace(unicode(css_str), "{aspect_ratio}", cgi.escape(unicode(round(ratio, 2)))) frag.add_css(css_str) return frag
def student_view(self, context=None): # pylint: disable=W0613 template = self.resource_string("static/html/acid.html") handler_url = self.runtime.handler_url(self, "handler1") frag = Fragment(template.format(handler_url=handler_url)) frag.add_javascript(self.resource_string("static/js/src/acid.js")) frag.initialize_js('AcidBlock') return frag
def student_view_aside(self, block, context): # pylint: disable=unused-argument """ Display the tag selector with specific categories and allowed values, depending on the context. """ if isinstance(block, CapaModule): tags = [] for tag in self.get_available_tags(): tag_available_values = tag.get_values() tag_current_values = self.saved_tags.get(tag.name, []) if isinstance(tag_current_values, basestring): tag_current_values = [tag_current_values] tag_values_not_exists = [cur_val for cur_val in tag_current_values if cur_val not in tag_available_values] tag_values_available_to_choose = tag_available_values + tag_values_not_exists tag_values_available_to_choose.sort() tags.append({ 'key': tag.name, 'title': tag.title, 'values': tag_values_available_to_choose, 'current_values': tag_current_values, }) fragment = Fragment(render_to_string('structured_tags_block.html', {'tags': tags, 'tags_count': len(tags), 'block_location': block.location})) fragment.add_javascript_url(self._get_studio_resource_url('/js/xblock_asides/structured_tags.js')) fragment.initialize_js('StructuredTagsInit') return fragment else: return Fragment(u'')
def studio_view(self, context=None): html_str = self.resource_string("static/html/studio.html") frag = Fragment(html_str.format(self=self)) frag.add_javascript(self.resource_string("static/js/src/replx-edit.js")) frag.initialize_js("ReplXBlockEdit") return frag
def mentoring_table_view(self, context=None): html = render_js_template('templates/html/answer_table.html', { 'self': self, }) fragment = Fragment(html) fragment.add_css_url(self.runtime.local_resource_url(self.xblock_container, 'public/css/answer_table.css')) return fragment
def dashboard_detail_view(self, context): fragment = Fragment() children_context = context.copy() target_workgroups = context.get(Constants.TARGET_WORKGROUPS) target_users = context.get(Constants.TARGET_STUDENTS) filtered_users = children_context[Constants.FILTERED_STUDENTS] stages = [] stage_stats = {} for stage in self.stages: if not stage.shown_on_detail_view: continue stage_fragment = stage.render('dashboard_detail_view', children_context) stage_fragment.add_frag_resources(fragment) stages.append({"id": stage.id, 'content': stage_fragment.content}) stage_stats[stage.id] = self._get_stage_completion_details(stage, target_workgroups, target_users) groups_data = self._build_groups_data(target_workgroups, stage_stats, filtered_users) visible_groups = [group for group in groups_data if group["group_visible"]] render_context = { 'activity': self, 'StageState': StageState, 'stages': stages, 'stages_count': len(stages), 'groups': visible_groups, 'filtered_out_workgroups': len(groups_data) - len(visible_groups), 'stage_cell_width_percent': (100 - 30) / float(len(stages)), # 30% is reserved for first column 'assigned_to_groups_label': messages.ASSIGNED_TO_GROUPS_LABEL.format(group_count=len(groups_data)) } fragment.add_content(self.render_template('dashboard_detail_view', render_context)) return fragment
def student_view(self, context=None): """ The primary view of the XBlock, shown to students when viewing courses. """ ''' #添加字段记录上回播放时间,应该是用户级别的 if self.start_time != "" and self.end_time != "": fullUrl += "#t=" + self.start_time + "," + self.end_time elif self.start_time != "": fullUrl += "#t=" + self.start_time elif self.end_time != "": fullUrl += "#t=0," + self.end_time ''' context = { 'display_name': self.display_name, 'app_id' : self.app_id, 'video_id': self.video_id, 'width': self.width, 'height': self.height } html = self.render_template('static/html/sewise_view.html', context) frag = Fragment(html) #frag.add_javascript(self.load_resource('static/js/h5connect.js')) #内有中文,使用插入外部url #frag.add_javascript(self.load_resource("static/js/sewise.player.min.js")) frag.add_javascript(self.load_resource("static/js/sewise_view.js")) frag.initialize_js('sewiseXBlockInitView') return frag
def wrap_fragment(fragment, new_content): """ Returns a new Fragment that has `new_content` and all as its content, and all of the resources from fragment """ wrapper_frag = Fragment(content=new_content) wrapper_frag.add_frag_resources(fragment) return wrapper_frag
def student_view(self, context=None): """Provide the default student view.""" if context is None: context = {} context = self.calc_context(context) result = Fragment() named_child_frags = [] # self.children is an attribute obtained from ChildrenModelMetaclass, so disable the # static pylint checking warning about this. for child_id in self.children: # pylint: disable=E1101 child = self.runtime.get_block(child_id) frag = self.runtime.render_child(child, "problem_view", context) result.add_frag_resources(frag) named_child_frags.append((child.name, frag)) result.add_css(u""" .problem { border: solid 1px #888; padding: 3px; } """) result.add_content(self.runtime.render_template( "problem.html", named_children=named_child_frags )) result.add_javascript(u""" function ProblemBlock(runtime, element) { function callIfExists(obj, fn) { if (typeof obj[fn] == 'function') { return obj[fn].apply(obj, Array.prototype.slice.call(arguments, 2)); } else { return undefined; } } function handleCheckResults(results) { $.each(results.submitResults || {}, function(input, result) { callIfExists(runtime.childMap(element, input), 'handleSubmit', result); }); $.each(results.checkResults || {}, function(checker, result) { callIfExists(runtime.childMap(element, checker), 'handleCheck', result); }); } // To submit a problem, call all the named children's submit() // function, collect their return values, and post that object // to the check handler. $(element).find('.check').bind('click', function() { var data = {}; var children = runtime.children(element); for (var i = 0; i < children.length; i++) { var child = children[i]; if (child.name !== undefined) { data[child.name] = callIfExists(child, 'submit'); } } var handlerUrl = runtime.handlerUrl(element, 'check') $.post(handlerUrl, JSON.stringify(data)).success(handleCheckResults); }); $(element).find('.rerandomize').bind('click', function() { var handlerUrl = runtime.handlerUrl(element, 'rerandomize'); $.post(handlerUrl, JSON.stringify({})); }); } """) result.initialize_js('ProblemBlock') return result
else: # TODO update git account student = self.runtime.get_real_user( self.runtime.anonymous_student_id) username = student.username print 'OK' context_dict = { "labs": self._get_available_labs(), "dockers": self.dockers, "password": self.git_password, "username": username, "message": "", "report": "" } fragment = Fragment() fragment.add_content( Util.render_template('static/html/uc_docker.html', context_dict)) fragment.add_css(Util.load_resource("static/css/uc_docker.css")) fragment.add_javascript( Util.load_resource("static/js/src/uc_docker.js")) fragment.initialize_js("UcDockerXBlock") return fragment def studio_view(self, context=None): # to add new lab context_dict = { "labs": self.labs, "docker_file": """FROM uclassroom/ucore-vnc-base MAINTAINER ggxx<*****@*****.**>
def wrap_child(self, block, view, frag, context): # pylint: disable=W0613 wrapped = Fragment() wrapped.add_javascript_url( self.resource_url("js/vendor/jquery.min.js")) wrapped.add_javascript_url( self.resource_url("js/vendor/jquery.cookie.js")) data = {} if frag.js_init_fn: wrapped.add_javascript_url( self.resource_url("js/runtime/%s.js" % frag.js_init_version)) data['init'] = frag.js_init_fn data['runtime-version'] = frag.js_init_version data['usage'] = block.scope_ids.usage_id data['block-type'] = block.scope_ids.block_type if block.name: data['name'] = block.name html = u"<div class='xblock'%s>%s</div>" % ( "".join(" data-%s='%s'" % item for item in data.items()), frag.body_html(), ) wrapped.add_content(html) wrapped.add_frag_resources(frag) return wrapped
def student_view(self, context=None): """ Player view, displayed to the student """ ### # VIDEO MODULE # #### => work and load dailymotion cloud player stream_url = "" stream_url_hd = "" download_url_ld = "" download_url_std = "" download_url_hd = "" thumbnail_url = "" subs_url = {} auth_key = "" auth_key_secure = "" msg = {} if self.id_video != "": try: assets = self.cloudkey.media.get_assets(id=self.id_video) if self.player == "Dailymotion": auth_key = self.get_dailymotion_auth_key(False) auth_key_secure = self.get_dailymotion_auth_key(True) else: #assets['jpeg_thumbnail_source']['stream_url'] #mp4_h264_aac #mp4_h264_aac_ld #mp4_h264_aac_hq -> 480 #mp4_h264_aac_hd -> 720 #jpeg_thumbnail_medium thumbnail_url = self.cloudkey.media.get_stream_url( id=self.id_video, asset_name='jpeg_thumbnail_source') stream_url = self.get_stream_url() if assets.get('mp4_h264_aac_hd'): stream_url_hd = self.get_stream_url('mp4_h264_aac_hd', download=False) elif assets.get('mp4_h264_aac_hq'): stream_url_hd = self.get_stream_url('mp4_h264_aac_hq', download=False) subs_url = self.get_subs_url() if self.allow_download_video: download_url_ld = self.get_stream_url('mp4_h264_aac_ld', download=True) download_url_std = self.get_stream_url(download=True) if assets.get('mp4_h264_aac_hd'): download_url_hd = self.get_stream_url( 'mp4_h264_aac_hd', download=True) elif assets.get('mp4_h264_aac_hq'): download_url_hd = self.get_stream_url( 'mp4_h264_aac_hq', download=True) except InvalidParameter: msg = { "level": "warning", "message": _("Your video ID is invalid") } except AuthenticationError: msg = { "level": "warning", "message": _("Your university ID is invalid") } except Exception as e: # we use Exception to catch everything because if one fails, all xblock on page fail # and become uneditable msg = { "level": "error", "message": u'Unexpected error : %r' % e } log.error(msg['message']) else: msg = { "level": "warning", "message": _("You must provide a video ID") } #create url for videojs to add it directly in the template dmjsurl = self.runtime.local_resource_url( self, "public/js/src/dmplayer-sdk.js") frag = Fragment() frag.add_content( self.render_template( "templates/html/dmcloud.html", { 'self': self, 'msg': msg, 'id': self.location.html_id(), #dmplayer 'auth_key': auth_key, 'auth_key_secure': auth_key_secure, 'video_id': self.id_video, 'user_id': self.univ.dm_user_id, 'dmjsurl': dmjsurl, #end dmplayer 'download_url_ld': download_url_ld, 'download_url_std': download_url_std, 'download_url_hd': download_url_hd, 'stream_url': stream_url, 'stream_url_hd': stream_url_hd, 'subs_url': subs_url, 'thumbnail_url': thumbnail_url, "transcript_url": self.runtime.handler_url(self, 'transcript', 'translation').rstrip('/?'), })) #load locally to work with more than one instance on page frag.add_css_url( self.runtime.local_resource_url(self, "public/css/dmcloud.css")) if self.player == "Dailymotion": frag.add_javascript( self.resource_string("public/js/src/dmcloud-dm.js")) frag.initialize_js('DmCloudPlayer') else: frag.add_css_url( self.runtime.local_resource_url( self, "public/video-js-4.10.2/video-js.min.css")) frag.add_javascript_url( self.runtime.local_resource_url( self, "public/video-js-4.10.2/video.dev.js")) frag.add_javascript( self.resource_string("public/js/src/dmcloud-video.js")) frag.initialize_js('DmCloudVideo') return frag
def studio_view(self, context): """ Editing view in Studio """ js_templates = load_resource('/templates/html/js_templates.html') context = { 'js_templates': js_templates, 'self': self, 'data': urllib.quote(json.dumps(self.data)), } fragment = Fragment() fragment.add_content(render_template('/templates/html/drag_and_drop_edit.html', context)) fragment.add_css_url(self.runtime.local_resource_url(self, 'public/css/vendor/jquery-ui-1.10.4.custom.min.css')) fragment.add_css_url(self.runtime.local_resource_url(self, 'public/css/drag_and_drop_edit.css')) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/vendor/jquery-ui-1.10.4.custom.min.js')) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/vendor/jquery.html5-placeholder-shim.js')) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/vendor/handlebars-v1.1.2.js')) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/drag_and_drop_edit.js')) fragment.initialize_js('DragAndDropEditBlock') return fragment
def student_view(self, context=None): """ The primary view of the HastexoXBlock, shown to students when viewing courses. """ def error_frag(msg): """ Build a fragment to display runtime errors. """ context = {'error_msg': msg} html = loader.render_template('static/html/error.html', context) frag = Fragment(html) frag.add_css_url( self.runtime.local_resource_url(self, 'public/css/main.css') ) return frag # Load configuration configuration = self.get_configuration() # Get the course id and anonymous user id, and derive the stack name # from them course_id, anonymous_student_id = self.get_block_ids() self.stack_run = "%s_%s" % (course_id.course, course_id.run) self.stack_name = "%s_%s" % (self.stack_run, anonymous_student_id) # Render the HTML template html = loader.render_template('static/html/main.html') frag = Fragment(html) # Add the public CSS and JS frag.add_css_url( self.runtime.local_resource_url(self, 'public/css/main.css') ) frag.add_javascript_url( self.runtime.local_resource_url(self, 'public/js/plugins.js') ) frag.add_javascript_url( self.runtime.local_resource_url(self, 'public/js/main.js') ) # Set the port port = None if len(self.stack_ports) > 0: port = self.stack_get("port") if not port or port not in self.stack_ports: port = self.stack_ports[0] # Update stack info self.stack_update({ "provider": self.provider, "protocol": self.stack_protocol, "port": port }) # Call the JS initialization function frag.initialize_js('HastexoXBlock', { "terminal_url": configuration.get("terminal_url"), "timeouts": configuration.get("js_timeouts"), "has_tests": len(self.tests) > 0, "protocol": self.stack_protocol, "ports": self.stack_ports, "port_names": self.stack_port_names, "port": port, "provider": self.provider }) return frag
def student_view(self, context): fragment = Fragment() # Check if the student view of a step child has been requested context_step_name = context.get('step', None) if context else None context_step_child_name = context.get('child', None) if context else None if (context_step_name and context_step_name == self.current_step_name and context_step_child_name): step = self._get_step_by_name(context_step_name) for child in step.get_children_objects(): if child.name == context_step_child_name: # 3play api key from setting if not child.api_key_3play: child.api_key_3play = self.api_key_3play_from_default_setting( ) return child.student_view(context) # First access, set the current_step to the beginning of the adventure if not self.current_step_name and self.has_steps: self.current_step_name = 'first' info_fragment = None if self.info: info_fragment = self.info.render(context={'as_template': False}) fragment.add_content( loader.render_template('templates/html/adventure.html', { 'self': self, 'info_fragment': info_fragment, })) for css_url in self.CSS_URLS: fragment.add_css_url(self.runtime.local_resource_url( self, css_url)) for js_url in self.JS_URLS: fragment.add_javascript_url( self.runtime.local_resource_url(self, js_url)) context = {} for template in self.JS_TEMPLATES: fragment.add_resource( loader.render_js_template(template[1], element_id=template[0], context=context), "text/html") fragment.initialize_js('AdventureBlock') return fragment
def student_view(self, context): """ Renders the output that a student will see. """ fragment = Fragment() fragment.add_content( self.system.render_template( 'word_cloud.html', { 'ajax_url': self.system.ajax_url, 'display_name': self.display_name, 'instructions': self.instructions, 'element_class': self.location.category, 'element_id': self.location.html_id(), 'num_inputs': self.num_inputs, 'submitted': self.submitted, })) fragment.add_javascript_url( self.runtime.local_resource_url(self, 'public/js/d3.min.js')) fragment.add_javascript_url( self.runtime.local_resource_url(self, 'public/js/d3.layout.cloud.js')) fragment.add_javascript_url( self.runtime.local_resource_url(self, 'public/js/word_cloud.js')) fragment.add_javascript_url( self.runtime.local_resource_url(self, 'public/js/word_cloud_main.js')) return fragment
def student_view(self, context=None): """ The primary view of the AnimationXBlock, shown to students when viewing courses. """ html = self.resource_string("static/html/animation.html") frag = Fragment(html.format(height = self.height, textheight = self.textheight, width=self.width, inner_width=self.width-20, animation = json.dumps(self.animation), position = self.position, max_position = self.max_position)) # frag.add_javascript_url("//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js") frag.add_css_url("//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css") frag.add_css(self.resource_string("static/css/jquery.ui.labeledslider.css")) frag.add_javascript_url("//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js") frag.add_javascript(self.resource_string("static/js/src/jquery.ui.labeledslider.js")) frag.add_css(self.resource_string("static/css/animation.css")) frag.add_javascript(self.resource_string("static/js/src/animation.js")) frag.initialize_js('AnimationXBlock') return frag
def student_view(self, context=None): """ Normal view of the review step. The parent Step Builder block should pass in appropriate context information: - score_summary """ context = context.copy() if context else {} fragment = Fragment() if "score_summary" not in context: fragment.add_content( u"Error: This block only works inside a Step Builder block.") elif not context["score_summary"]: # Note: The following text should never be seen (in theory) so does not need to be translated. fragment.add_content( u"Your score and review messages will appear here.") else: for child_id in self.children: child = self.runtime.get_block(child_id) if child is None: # child should not be None but it can happen due to bugs or permission issues fragment.add_content(u"<p>[{}]</p>".format( u"Error: Unable to load child component.")) else: if hasattr(child, 'is_applicable'): if not child.is_applicable(context): continue # Hide conditional messages that don't meet their criteria # Render children as "embedded_student_view" rather than "student_view" so # that Studio doesn't wrap with with unwanted controls and the XBlock SDK # workbench doesn't add the acid-aside to the fragment. child_fragment = self._render_child_fragment( child, context, view="embedded_student_view") fragment.add_frag_resources(child_fragment) fragment.add_content(child_fragment.content) return fragment
def student_view(self, context=None): """ The primary view of the MarkdownXBlock, shown to students when viewing courses. """ data = {} data['markdown_text'] = unicode(self.markdown_text) html = self.resource_string("static/html/markdowna_studentview.html") frag = Fragment( unicode(html.format(data=unicode(cgi.escape(json.dumps(data)))))) # markdown it frag.add_javascript( self.resource_string("static/js/lib/markdown-it_new.min.js")) frag.add_javascript( self.resource_string("static/js/lib/markdown-it-front-matter.js")) # github markdown css frag.add_css( self.resource_string("static/css/lib/github-markdown_new.css")) frag.add_javascript( self.resource_string("static/js/src/markdowna_studentview.js")) frag.initialize_js('MarkdownXBlock') return frag
def student_view(self, _context=None): """ Render this message. """ html = u'<div class="review-conditional-message">{content}</div>'.format( content=self.content) return Fragment(html)
def student_view(self, context): if self.child is None: # raise error instead? In fact, could complain on descriptor load... return Fragment(content=u"<div>Nothing to randomize between</div>") return self.child.render('student_view', context)
def student_view(self, context): """ Player view, displayed to the student """ try: workgroup = self.workgroup except OutsiderDisallowedError as ode: error_fragment = Fragment() error_fragment.add_content( render_template('/templates/html/loading_error.html', {'error_message': unicode(ode)})) error_fragment.add_javascript( load_resource('public/js/group_project_error.js')) error_fragment.initialize_js('GroupProjectError') return error_fragment user_id = self.user_id group_activity = GroupActivity.import_xml_string( self.data, self.is_admin_grader) try: group_activity.update_submission_data( self.project_api.get_latest_workgroup_submissions_by_id( workgroup["id"])) except: pass if self.is_group_member: try: team_members = [ self.project_api.get_user_details(tm["id"]) for tm in workgroup["users"] if user_id != int(tm["id"]) ] except: team_members = [] try: assess_groups = self.project_api.get_workgroups_to_review( user_id, self.course_id, self.content_id) except: assess_groups = [] else: team_members = [] assess_groups = [workgroup] context = { "group_activity": group_activity, "team_members": json.dumps(team_members), "assess_groups": json.dumps(assess_groups), "ta_graded": (self.group_reviews_required_count < 1), } fragment = Fragment() fragment.add_content( render_template('/templates/html/group_project.html', context)) fragment.add_css(load_resource('public/css/group_project.css')) fragment.add_javascript_url( self.runtime.local_resource_url( self, 'public/js/vendor/jquery.ui.widget.js')) fragment.add_javascript_url( self.runtime.local_resource_url( self, 'public/js/vendor/jquery.fileupload.js')) fragment.add_javascript_url( self.runtime.local_resource_url( self, 'public/js/vendor/jquery.iframe-transport.js')) fragment.add_javascript(load_resource('public/js/group_project.js')) fragment.initialize_js('GroupProjectBlock') return fragment
def xblock_view_handler(request, usage_key_string, view_name): """ The restful handler for requests for rendered xblock views. Returns a json object containing two keys: html: The rendered html of the view resources: A list of tuples where the first element is the resource hash, and the second is the resource description """ usage_key = UsageKey.from_string(usage_key_string) if not has_course_access(request.user, usage_key.course_key): raise PermissionDenied() accept_header = request.META.get('HTTP_ACCEPT', 'application/json') if 'application/json' in accept_header: store = get_modulestore(usage_key) xblock = store.get_item(usage_key) is_read_only = _is_xblock_read_only(xblock) container_views = ['container_preview', 'reorderable_container_child_preview'] unit_views = ['student_view'] # wrap the generated fragment in the xmodule_editor div so that the javascript # can bind to it correctly xblock.runtime.wrappers.append(partial(wrap_xblock, 'StudioRuntime', usage_id_serializer=unicode)) if view_name == 'studio_view': try: fragment = xblock.render('studio_view') # catch exceptions indiscriminately, since after this point they escape the # dungeon and surface as uneditable, unsaveable, and undeletable # component-goblins. except Exception as exc: # pylint: disable=w0703 log.debug("unable to render studio_view for %r", xblock, exc_info=True) fragment = Fragment(render_to_string('html_error.html', {'message': str(exc)})) # change not authored by requestor but by xblocks. store.update_item(xblock, None) elif view_name == 'student_view' and xblock_has_own_studio_page(xblock): context = { 'runtime_type': 'studio', 'container_view': False, 'read_only': is_read_only, 'root_xblock': xblock, } # For non-leaf xblocks on the unit page, show the special rendering # which links to the new container page. html = render_to_string('container_xblock_component.html', { 'xblock_context': context, 'xblock': xblock, 'locator': usage_key, }) return JsonResponse({ 'html': html, 'resources': [], }) elif view_name in (unit_views + container_views): is_container_view = (view_name in container_views) # Determine the items to be shown as reorderable. Note that the view # 'reorderable_container_child_preview' is only rendered for xblocks that # are being shown in a reorderable container, so the xblock is automatically # added to the list. reorderable_items = set() if view_name == 'reorderable_container_child_preview': reorderable_items.add(xblock.location) # Only show the new style HTML for the container view, i.e. for non-verticals # Note: this special case logic can be removed once the unit page is replaced # with the new container view. context = { 'runtime_type': 'studio', 'container_view': is_container_view, 'read_only': is_read_only, 'root_xblock': xblock if (view_name == 'container_preview') else None, 'reorderable_items': reorderable_items } fragment = get_preview_fragment(request, xblock, context) # For old-style pages (such as unit and static pages), wrap the preview with # the component div. Note that the container view recursively adds headers # into the preview fragment, so we don't want to add another header here. if not is_container_view: fragment.content = render_to_string('component.html', { 'xblock_context': context, 'preview': fragment.content, 'label': xblock.display_name or xblock.scope_ids.block_type, }) else: raise Http404 hashed_resources = OrderedDict() for resource in fragment.resources: hashed_resources[hash_resource(resource)] = resource return JsonResponse({ 'html': fragment.content, 'resources': hashed_resources.items() }) else: return HttpResponse(status=406)
def student_view(self, context=None): """ Student View """ context = context.copy() if context else {} context['hide_header'] = True context['self'] = self fragment = Fragment() fragment.add_content( loader.render_template('templates/html/plot.html', context)) fragment.add_css_url( self.runtime.local_resource_url(self, 'public/css/plot.css')) fragment.add_javascript_url( self.runtime.local_resource_url(self, 'public/js/vendor/d3.min.js')) fragment.add_javascript_url( self.runtime.local_resource_url(self, 'public/js/plot.js')) fragment.initialize_js('PlotBlock') return fragment
def student_view(self, context=None): """ The primary view of the LabProgXBlock, shown to students when viewing courses. """ html = self.resource_string("static/html/labprog.html") frag = Fragment(html.format(self=self)) frag.add_css(self.resource_string("static/css/labprog.css")) frag.add_javascript_url( "https://cdnjs.cloudflare.com/ajax/libs/ace/1.4.2/ace.js") frag.add_javascript(self.resource_string("static/js/src/labprog.js")) frag.add_javascript( self.resource_string("static/js/src/src-min-noconflict/ace.js")) frag.initialize_js('LabProgXBlock') return frag
def author_preview_view(self, context): context['self'] = self fragment = Fragment() fragment.add_content( loader.render_template('templates/html/plot_preview.html', context)) fragment.add_css_url( self.runtime.local_resource_url(self, 'public/css/plot-preview.css')) if self.overlay_ids: fragment.add_content(u"<p>{}</p>".format( _(u"In addition to the default and average overlays the plot includes the following overlays:" ))) for overlay in self.overlays: overlay_fragment = self._render_child_fragment( overlay, context, view='mentoring_view') fragment.add_frag_resources(overlay_fragment) fragment.add_content(overlay_fragment.content) return fragment
def author_view(self, context=None): """ Studio View """ msg = u"This XBlock only renders content when viewed via the LMS." return Fragment(u'<em>%s</em></p>' % msg)
def studio_view(self, _context): """ Render a form for XBlock editing. """ fragment = Fragment() player = self.get_player() languages = [{ 'label': label, 'code': lang } for lang, label in ALL_LANGUAGES] languages.sort(key=lambda l: l['label']) transcripts = self.get_enabled_transcripts() download_transcript_handler_url = self.runtime.handler_url( self, 'download_transcript') auth_error_message = '' # Authenticate to API of the player video platform and update metadata with auth information. # Note that there is no need to authenticate to Youtube API, # whilst for Wistia, a sample authorised request is to be made to ensure authentication succeeded, # since it is needed for the auth status message generation and the player's state update with auth status. if self.token: _auth_data, auth_error_message = self.authenticate_video_api( self.token.encode(encoding='utf-8')) initial_default_transcripts, transcripts_autoupload_message = self._update_default_transcripts( player, transcripts) log.debug("Fetched default transcripts: {}".format( initial_default_transcripts)) # Prepare basic_fields and advanced_fields for them to be rendered basic_fields = self.prepare_studio_editor_fields(player.basic_fields) advanced_fields = self.prepare_studio_editor_fields( player.advanced_fields) context = { 'advanced_fields': advanced_fields, 'auth_error_message': auth_error_message, 'basic_fields': basic_fields, 'courseKey': self.course_key, 'languages': languages, 'player_name': self.player_name, # for players identification 'players': PlayerName, 'sources': TranscriptSource.to_dict().items(), # transcripts context: 'transcripts': filter_transcripts_by_source( transcripts, sources=[TranscriptSource.THREE_PLAY_MEDIA], exclude=True), 'transcripts_fields': self.prepare_studio_editor_fields(player.trans_fields), 'three_pm_fields': self.prepare_studio_editor_fields(player.three_pm_fields), 'transcripts_type': '3PM' if self.threeplaymedia_streaming else 'manual', 'default_transcripts': self.default_transcripts, 'enabled_default_transcripts': filter_transcripts_by_source(transcripts), 'enabled_managed_transcripts': self.get_enabled_managed_transcripts(), 'initial_default_transcripts': initial_default_transcripts, 'transcripts_autoupload_message': transcripts_autoupload_message, 'download_transcript_handler_url': download_transcript_handler_url, } fragment.content = render_template('studio-edit.html', **context) fragment.add_css(resource_string("static/css/student-view.css")) fragment.add_css(resource_string("static/css/transcripts-upload.css")) fragment.add_css(resource_string("static/css/studio-edit.css")) fragment.add_css( resource_string("static/css/studio-edit-accordion.css")) fragment.add_javascript( resource_string("static/js/runtime-handlers.js")) fragment.add_javascript( resource_string("static/js/studio-edit/utils.js")) fragment.add_javascript( resource_string("static/js/studio-edit/studio-edit.js")) fragment.add_javascript( resource_string("static/js/studio-edit/transcripts-autoload.js")) fragment.add_javascript( resource_string( "static/js/studio-edit/transcripts-manual-upload.js")) fragment.initialize_js('StudioEditableXBlock') return fragment
def _create_fragment(self, template, context_dict, initialize_js_func, additional_css=None, additional_js=None): """ Creates a fragment for display. """ fragment = Fragment(template.render(context_dict)) if additional_css is None: additional_css = [] if additional_js is None: additional_js = [] i18n_service = self.runtime.service(self, 'i18n') if hasattr(i18n_service, 'get_language_bidi') and i18n_service.get_language_bidi(): css_url = "static/css/openassessment-rtl.css" else: css_url = "static/css/openassessment-ltr.css" if settings.DEBUG: for css in additional_css: fragment.add_css_url(self.runtime.local_resource_url( self, css)) fragment.add_css_url(self.runtime.local_resource_url( self, css_url)) for js in additional_js: # pylint: disable=invalid-name self.add_javascript_files(fragment, js) self.add_javascript_files(fragment, "static/js/src/oa_shared.js") self.add_javascript_files(fragment, "static/js/src/oa_server.js") self.add_javascript_files(fragment, "static/js/src/lms") else: # TODO: load CSS and JavaScript as URLs once they can be served by the CDN for css in additional_css: fragment.add_css(load(css)) fragment.add_css(load(css_url)) # minified additional_js should be already included in 'make javascript' fragment.add_javascript( load("static/js/openassessment-lms.min.js")) js_context_dict = { "ALLOWED_IMAGE_MIME_TYPES": self.ALLOWED_IMAGE_MIME_TYPES, "ALLOWED_FILE_MIME_TYPES": self.ALLOWED_FILE_MIME_TYPES, "FILE_EXT_BLACK_LIST": self.FILE_EXT_BLACK_LIST, "FILE_TYPE_WHITE_LIST": self.white_listed_file_types, "MAXIMUM_FILE_UPLOAD_COUNT": self.MAX_FILES_COUNT, "TEAM_ASSIGNMENT": self.teams_enabled and self.team_submissions_enabled() } fragment.initialize_js(initialize_js_func, js_context_dict) return fragment
def index(request, course_id, chapter=None, section=None, position=None): """ Displays courseware accordion and associated content. If course, chapter, and section are all specified, renders the page, or returns an error if they are invalid. If section is not specified, displays the accordion opened to the right chapter. If neither chapter or section are specified, redirects to user's most recent chapter, or the first chapter if this is the user's first visit. Arguments: - request : HTTP request - course_id : course id (str: ORG/course/URL_NAME) - chapter : chapter url_name (str) - section : section url_name (str) - position : position in module, eg of <sequential> module (str) Returns: - HTTPresponse """ user = User.objects.prefetch_related("groups").get(id=request.user.id) request.user = user # keep just one instance of User course = get_course_with_access(user, course_id, 'load', depth=2) staff_access = has_access(user, course, 'staff') registered = registered_for_course(course, user) if not registered: # TODO (vshnayder): do course instructors need to be registered to see course? log.debug('User %s tried to view course %s but is not enrolled' % (user, course.location.url())) return redirect(reverse('about_course', args=[course.id])) masq = setup_masquerade(request, staff_access) try: field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course.id, user, course, depth=2) course_module = get_module_for_descriptor(user, request, course, field_data_cache, course.id) if course_module is None: log.warning( 'If you see this, something went wrong: if we got this' ' far, should have gotten a course module for this user') return redirect(reverse('about_course', args=[course.id])) if chapter is None: return redirect_to_course_position(course_module) context = { 'csrf': csrf(request)['csrf_token'], 'accordion': render_accordion(request, course, chapter, section, field_data_cache), 'COURSE_TITLE': course.display_name_with_default, 'course': course, 'init': '', 'fragment': Fragment(), 'staff_access': staff_access, 'masquerade': masq, 'xqa_server': settings.FEATURES.get( 'USE_XQA_SERVER', 'http://*****:*****@content-qa.mitx.mit.edu/xqa') } # Only show the chat if it's enabled by the course and in the # settings. show_chat = course.show_chat and settings.FEATURES['ENABLE_CHAT'] if show_chat: context['chat'] = chat_settings(course, user) # If we couldn't load the chat settings, then don't show # the widget in the courseware. if context['chat'] is None: show_chat = False context['show_chat'] = show_chat chapter_descriptor = course.get_child_by( lambda m: m.url_name == chapter) if chapter_descriptor is not None: save_child_position(course_module, chapter) else: raise Http404( 'No chapter descriptor found with name {}'.format(chapter)) chapter_module = course_module.get_child_by( lambda m: m.url_name == chapter) if chapter_module is None: # User may be trying to access a chapter that isn't live yet if masq == 'student': # if staff is masquerading as student be kinder, don't 404 log.debug('staff masq as student: no chapter %s' % chapter) return redirect(reverse('courseware', args=[course.id])) raise Http404 if section is not None: section_descriptor = chapter_descriptor.get_child_by( lambda m: m.url_name == section) if section_descriptor is None: # Specifically asked-for section doesn't exist if masq == 'student': # if staff is masquerading as student be kinder, don't 404 log.debug('staff masq as student: no section %s' % section) return redirect(reverse('courseware', args=[course.id])) raise Http404 # cdodge: this looks silly, but let's refetch the section_descriptor with depth=None # which will prefetch the children more efficiently than doing a recursive load section_descriptor = modulestore().get_instance( course.id, section_descriptor.location, depth=None) # Load all descendants of the section, because we're going to display its # html, which in general will need all of its children section_field_data_cache = FieldDataCache.cache_for_descriptor_descendents( course_id, user, section_descriptor, depth=None) section_module = get_module_for_descriptor( request.user, request, section_descriptor, section_field_data_cache, course_id, position) if section_module is None: # User may be trying to be clever and access something # they don't have access to. raise Http404 # Save where we are in the chapter save_child_position(chapter_module, section) context['fragment'] = section_module.render('student_view') else: # section is none, so display a message prev_section = get_current_child(chapter_module) if prev_section is None: # Something went wrong -- perhaps this chapter has no sections visible to the user raise Http404 prev_section_url = reverse('courseware_section', kwargs={ 'course_id': course_id, 'chapter': chapter_descriptor.url_name, 'section': prev_section.url_name }) context['fragment'] = Fragment(content=render_to_string( 'courseware/welcome-back.html', { 'course': course, 'chapter_module': chapter_module, 'prev_section': prev_section, 'prev_section_url': prev_section_url })) result = render_to_response('courseware/courseware.html', context) except Exception as e: if isinstance(e, Http404): # let it propagate raise # In production, don't want to let a 500 out for any reason if settings.DEBUG: raise else: log.exception("Error in index view: user={user}, course={course}," " chapter={chapter} section={section}" "position={position}".format(user=user, course=course, chapter=chapter, section=section, position=position)) try: result = render_to_response('courseware/courseware-error.html', { 'staff_access': staff_access, 'course': course }) except: # Let the exception propagate, relying on global config to at # at least return a nice error message log.exception("Error while rendering courseware-error page") raise return result
def student_view(self, context): """ Player view, displayed to the student """ max_score_string = '({0} Point{1} Possible)'.format(int(self.weight), 's' if self.weight > 1 else '') if self.weight else '' js_templates = load_resource('/templates/html/js_templates.html') context = { 'js_templates': js_templates, 'title': self.display_name, 'question_text': self.question_text, 'max_score_string': max_score_string } fragment = Fragment() fragment.add_content(render_template('/templates/html/drag_and_drop.html', context)) fragment.add_css_url(self.runtime.local_resource_url(self, 'public/css/vendor/jquery-ui-1.10.4.custom.min.css')) fragment.add_css_url(self.runtime.local_resource_url(self, 'public/css/drag_and_drop.css')) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/vendor/jquery-ui-1.10.4.custom.min.js')) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/vendor/jquery.html5-placeholder-shim.js')) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/vendor/handlebars-v1.1.2.js')) fragment.add_javascript_url(self.runtime.local_resource_url(self, 'public/js/drag_and_drop.js')) fragment.initialize_js('DragAndDropBlock') return fragment
def _create_courseware_context(self): """ Returns and creates the rendering context for the courseware. Also returns the table of contents for the courseware. """ courseware_context = { 'csrf': csrf(self.request)['csrf_token'], 'COURSE_TITLE': self.course.display_name_with_default_escaped, 'course': self.course, 'init': '', 'fragment': Fragment(), 'staff_access': self.is_staff, 'studio_url': get_studio_url(self.course, 'course'), 'masquerade': self.masquerade, 'xqa_server': settings.FEATURES.get('XQA_SERVER', "http://your_xqa_server.com"), 'bookmarks_api_url': reverse('bookmarks'), 'language_preference': self._get_language_preference(), 'disable_optimizely': True, } table_of_contents = toc_for_course( self.effective_user, self.request, self.course, self.chapter_url_name, self.section_url_name, self.field_data_cache, ) courseware_context['accordion'] = render_accordion( self.request, self.course, table_of_contents['chapters']) # entrance exam data if course_has_entrance_exam(self.course): if getattr(self.chapter, 'is_entrance_exam', False): courseware_context[ 'entrance_exam_current_score'] = get_entrance_exam_score( self.request, self.course) courseware_context[ 'entrance_exam_passed'] = user_has_passed_entrance_exam( self.request, self.course) # staff masquerading data now = datetime.now(UTC()) effective_start = _adjust_start_date_for_beta_testers( self.effective_user, self.course, self.course_key) if not in_preview_mode() and self.is_staff and now < effective_start: # Disable student view button if user is staff and # course is not yet visible to students. courseware_context['disable_student_access'] = True if self.section: # chromeless data if self.section.chrome: chrome = [ s.strip() for s in self.section.chrome.lower().split(",") ] if 'accordion' not in chrome: courseware_context['disable_accordion'] = True if 'tabs' not in chrome: courseware_context['disable_tabs'] = True # default tab if self.section.default_tab: courseware_context['default_tab'] = self.section.default_tab # section data courseware_context[ 'section_title'] = self.section.display_name_with_default_escaped section_context = self._create_section_context( table_of_contents['previous_of_active_section'], table_of_contents['next_of_active_section'], ) courseware_context['fragment'] = self.section.render( STUDENT_VIEW, section_context) return courseware_context
def student_view(self, context=None): # runtime error if not hasattr(self.runtime, "anonymous_student_id"): return self.message_view( "Error in uc_docker (get anonymous student id)", "Cannot get anonymous_student_id in runtime", context) # preview in studio if self.runtime.anonymous_student_id == "student": result, message = GitLabUtil.get_user_projects( self.git_host, self.git_port, self.git_teacher_token) if not result: return self.message_view( "Error in uc_docker (get git projects)", "Cannot get user's projects in git", context) context_dict = {"labs": self.labs, "message": ""} fragment = Fragment() fragment.add_content( Util.render_template('static/html/uc_lab.html', context_dict)) fragment.add_css(Util.load_resource("static/css/uc_docker.css")) fragment.add_javascript( Util.load_resource("static/js/src/uc_lab.js")) fragment.initialize_js("UcDockerXBlock") return fragment # student view in open-edx if self.is_new: # create git account when first visiting student = self.runtime.get_real_user( self.runtime.anonymous_student_id) email = student.email name = student.first_name + " " + student.last_name username = student.username self.git_password = Util.create_random_password() self.save() # first_name, last_name are empty if name == " ": name = username self.logger.info("password is " + self.git_password) # create ldap account l = ldap.initialize(self.ldap_url) l.bind(self.principal_name, self.ldap_password) dn = "uid=" + username + "," + self.base_dn attrs = {} attrs['objectclass'] = ['top', 'inetOrgPerson', 'eduPerson'] attrs['cn'] = str(username) attrs['sn'] = str(username) attrs['givenName'] = str(username) attrs['uid'] = str(username) attrs['userPassword'] = str(self.git_password) attrs['description'] = 'ldap user for shibboleth' attrs['eduPersonPrincipalName'] = str(email) # Convert our dict to nice syntax for the add-function using modlist-module ldif = modlist.addModlist(attrs) l.add_s(dn, ldif) l.unbind_s() self.logger.info("create ldap account " + username + "," + dn) self.logger.info(self.git_host + "," + str(self.git_port) + "," + self.git_admin_token + "," + name + "," + username + "," + email + "," + self.git_password) result, message = GitLabUtil.create_account( self.git_host, self.git_port, self.git_admin_token, name, username, email, self.git_password) self.logger.info("create_account result:") self.logger.info(result) self.logger.info(message) if not result: return self.message_view( "Error in uc_docker (create git account)", message, context) result, message = GitLabUtil.login(self.git_host, self.git_port, username, self.git_password) self.logger.info("login result:") self.logger.info(result) self.logger.info(message) if not result: return self.message_view( "Error in uc_docker (login git account)", message, context) try: message = json.loads(message) self.git_id = message["id"] self.git_user_token = message["private_token"] self.save() except Exception, ex: return self.message_view( "Error in uc_docker (load json string)", message, context) try: self.private_key, self.public_key = Util.gen_ssh_keys(email) self.logger.info("private_key:" + self.private_key) self.save() conn = pymongo.Connection('localhost', 27017) db = conn.test token = db.token token.insert({ "username": username, "token": message["private_token"], "password": self.git_password, "private_key": self.private_key, "public_key": self.public_key }) conn.disconnect() except Exception, ex: return self.message_view("Error in uc_docker (gen ssh key)", ex, context)
def student_view(self, context=None): # pylint: disable=unused-argument """ Standard view of this XBlock. """ if not self.mentoring_ids: return Fragment(u"<h1>{}</h1><p>{}</p>".format( self.display_name, _("Not configured."))) blocks = [] for mentoring_block in self.get_mentoring_blocks(self.mentoring_ids): if mentoring_block is None: continue block = {'display_name': mentoring_block.display_name, 'mcqs': []} try: hide_questions = self.exclude_questions.get( mentoring_block.url_name, []) except Exception: # pylint: disable=broad-except-clause log.exception( "Cannot parse exclude_questions setting - probably malformed: %s", self.exclude_questions) hide_questions = [] for question_number, child_id in enumerate( self._get_problem_questions(mentoring_block), 1): try: if question_number in hide_questions: continue except TypeError: log.exception( "Cannot check question number - expected list of ints got: %s", hide_questions) # Get the student's submitted answer to this MCQ from the submissions API: mcq_block = self.runtime.get_block(child_id) mcq_submission_key = self._get_submission_key(child_id) try: value = sub_api.get_submissions(mcq_submission_key, limit=1)[0]["answer"] except IndexError: value = None block['mcqs'].append({ "display_name": mcq_block.display_name_with_default, "value": value, "accessible_value": _("Score: {score}").format( score=value) if value else _("No value yet"), "color": self.color_for_value(value) if value is not None else None, }) # If the values are numeric, display an average: numeric_values = [ float(mcq['value']) for mcq in block['mcqs'] if mcq['value'] is not None and mcq['value'].isnumeric() ] if numeric_values: average_value = sum(numeric_values) / len(numeric_values) block['average'] = average_value # average block is shown only if average value exists, so accessible text for no data is not required block['accessible_average'] = _("Score: {score}").format( score=floatformat(average_value)) block['average_label'] = self.average_labels.get( mentoring_block.url_name, _("Average")) block['has_average'] = True block['average_color'] = self.color_for_value(average_value) blocks.append(block) visual_repr = None if self.visual_rules: try: rules_parsed = json.loads(self.visual_rules) except ValueError: pass # JSON errors should be shown as part of validation else: visual_repr = DashboardVisualData(blocks, rules_parsed, self.color_for_value, self.visual_title, self.visual_desc) report_template = loader.render_template( 'templates/html/dashboard_report.html', { 'title': self.display_name, 'css': loader.load_unicode(self.css_path), 'student_name': self._get_user_full_name(), 'course_name': self._get_course_name(), }) html = loader.render_template( 'templates/html/dashboard.html', { 'blocks': blocks, 'display_name': self.display_name, 'visual_repr': visual_repr, 'show_numbers': self.show_numbers, 'header_html': self.header_html, 'footer_html': self.footer_html, }) fragment = Fragment(html) fragment.add_css_url( self.runtime.local_resource_url(self, self.css_path)) fragment.add_javascript_url( self.runtime.local_resource_url(self, self.js_path)) fragment.initialize_js( 'PBDashboardBlock', { 'reportTemplate': report_template, 'reportContentSelector': '.dashboard-report' }) return fragment
def studio_view(self, context): """ Editing view in Studio """ js_templates = loader.load_unicode('/templates/html/js_templates.html') # Get an 'id_suffix' string that is unique for this block. # We append it to HTML element ID attributes to ensure multiple instances of the DnDv2 block # on the same page don't share the same ID value. # We avoid using ID attributes in preference to classes, but sometimes we still need IDs to # connect 'for' and 'aria-describedby' attributes to the associated elements. id_suffix = self._get_block_id() js_templates = js_templates.replace('{{id_suffix}}', id_suffix) context = { 'js_templates': js_templates, 'id_suffix': id_suffix, 'fields': self.fields, 'self': self, 'data': six.moves.urllib.parse.quote(json.dumps(self.data)), } fragment = Fragment() fragment.add_content( loader.render_django_template( '/templates/html/drag_and_drop_edit.html', context=context, i18n_service=self.i18n_service)) css_urls = ('public/css/drag_and_drop_edit.css', ) js_urls = [ 'public/js/vendor/handlebars-v1.1.2.js', 'public/js/drag_and_drop_edit.js', ] statici18n_js_url = self._get_statici18n_js_url() if statici18n_js_url: js_urls.append(statici18n_js_url) for css_url in css_urls: fragment.add_css_url(self.runtime.local_resource_url( self, css_url)) for js_url in js_urls: fragment.add_javascript_url( self.runtime.local_resource_url(self, js_url)) # Do a bit of manipulation so we get the appearance of a list of zone options on # items that still have just a single zone stored items = self.data.get('items', []) for item in items: zones = self.get_item_zones(item['id']) # Note that we appear to be mutating the state of the XBlock here, but because # the change won't be committed, we're actually just affecting the data that # we're going to send to the client, not what's saved in the backing store. item['zones'] = zones item.pop('zone', None) fragment.initialize_js( 'DragAndDropEditBlock', { 'data': self.data, 'target_img_expanded_url': self.target_img_expanded_url, 'default_background_image_url': self.default_background_image_url, }) return fragment
def student_view(self, context=None): """ The primary view of the XBlock, shown to students when viewing courses. """ fullUrl = self.url if self.start_time != "" and self.end_time != "": fullUrl += "#t=" + self.start_time + "," + self.end_time elif self.start_time != "": fullUrl += "#t=" + self.start_time elif self.end_time != "": fullUrl += "#t=0," + self.end_time context = { 'display_name': self.display_name, 'url': fullUrl, 'allow_download': self.allow_download, 'source_text': self.source_text, 'source_url': self.source_url } html = self.render_template('static/html/videojs_view.html', context) frag = Fragment(html) frag.add_css(self.load_resource("static/css/video-js.min.css")) frag.add_css(self.load_resource("static/css/videojs.css")) frag.add_javascript(self.load_resource("static/js/video-js.js")) frag.add_javascript(self.load_resource("static/js/videojs_view.js")) frag.initialize_js('videojsXBlockInitView') return frag
def problem_view(self, context=None): """Renders the problem view. The view is specific to whether or not this problem was attempted, and, if so, if it was answered correctly. """ correct = self.left == self.right # TODO: I originally named this class="data", but that conflicted with # the CSS on the page! :( We might have to do something to namespace # things. # TODO: Should we have a way to spit out JSON islands full of data? # Note the horror of mixed Python-Javascript data below... content = string.Template(self.content).substitute(**context) result = Fragment( u""" <span class="mydata" data-attempted='{ecb.attempted}' data-correct='{correct}'> {content} <span class='indicator'></span> </span> """.format(ecb=self, content=content, correct=correct) ) # TODO: This is a runtime-specific URL. But if each XBlock ships their # own copy of underscore.js, we won't be able to uniquify them. # Perhaps runtimes can offer a palette of popular libraries so that # XBlocks can refer to them in XBlock-standard ways? result.add_javascript_url( self.runtime.resource_url("js/vendor/underscore-min.js") ) # TODO: The image tag here needs a magic URL, not a hard-coded one. format_data = { 'correct': self.runtime.local_resource_url( self, 'public/images/correct-icon.png'), 'incorrect': self.runtime.local_resource_url( self, 'public/images/incorrect-icon.png'), } result.add_resource( u""" <script type="text/template" id="xblock-equality-template"> <% if (attempted !== "True") {{ %> (Not attempted) <% }} else if (correct === "True") {{ %> <img src="{correct}"> <% }} else {{ %> <img src="{incorrect}"> <% }} %> </script> """.format(**format_data), "text/html" ) result.add_javascript( u""" function EqualityCheckerBlock(runtime, element) { var template = _.template($("#xblock-equality-template").html()); function render() { var data = $("span.mydata", element).data(); $("span.indicator", element).html(template(data)); } render(); return { handleCheck: function(result) { $("span.mydata", element) .data("correct", result ? "True" : "False") .data("attempted", "True"); render(); } } } """ ) result.initialize_js('EqualityCheckerBlock') return result
def student_view(self, context=None): # pylint: disable=W0613 """Returns default student view.""" return Fragment(u"<p>I can only appear inside problems.</p>")