def studio_view(self, context):
        """
        Render a form for editing this XBlock (override the StudioEditableXBlockMixin's method)
        """

        # if the XBlock has been submitted already then disable the studio_edit screen
        location = self.location.replace(
            branch=None,
            version=None)  # Standardize the key in case it isn't already
        item_id = unicode(location)
        if db_service.is_xblock_submitted(item_id):
            disabled_edit_fragment = Fragment()
            disabled_edit_fragment.content = loader.render_template(
                'static/html/formula_exercise_disabled_studio_edit.html', {})
            disabled_edit_fragment.add_javascript(
                loader.load_unicode(
                    'static/js/src/formula_exercise_disabled_studio_edit.js'))
            disabled_edit_fragment.initialize_js('StudioDisabledEditXBlock')
            return disabled_edit_fragment

        # Student not yet submit then we can edit the XBlock
        fragment = Fragment()
        context = {'fields': []}
        # Build a list of all the fields that can be edited:
        for field_name in self.editable_fields:
            field = self.fields[field_name]
            assert field.scope in (Scope.content, Scope.settings), (
                "Only Scope.content or Scope.settings fields can be used with "
                "StudioEditableXBlockMixin. Other scopes are for user-specific data and are "
                "not generally created/configured by content authors in Studio."
            )
            field_info = self._make_field_info(field_name, field)
            if field_info is not None:
                context["fields"].append(field_info)

        # (re-)fetch data from the database
        self.load_data_from_dbms()
        # self.serialize_data_to_context(context) ??? REMOVE not necessary, remove
        context['question_template'] = self.question_template
        context["variables"] = self.variables
        context["expressions"] = self.expressions

        fragment.content = loader.render_template(
            'static/html/formula_exercise_studio_edit.html', context)
        fragment.add_css(
            self.resource_string(
                "static/css/formula_exercise_block_studio_edit.css"))
        fragment.add_javascript(
            loader.load_unicode(
                'static/js/src/formula_exercise_studio_edit.js'))
        fragment.initialize_js('StudioEditableXBlockMixin')
        return fragment
Beispiel #2
0
 def fallback_view(self, view_name, context=None):
     result = Fragment()
     child_frags = self.runtime.render_children(self, context=context)
     result.add_frags_resources(child_frags)
     result.content = self.content
     result.add_content(self.runtime.render_template("vertical.html", children=child_frags))
     return result
    def studio_view(self, context):
        """
        Render a form for editing this XBlock
        """
        from .models import CorfoCodeMappingContent, CorfoCodeInstitution
        fragment = Fragment()

        context = {
            'xblock':
            self,
            'location':
            str(self.location).split('@')[-1],
            'list_content':
            CorfoCodeMappingContent.objects.all().values(
                'id_content', 'content'),
            'list_institution':
            CorfoCodeInstitution.objects.all().values('id_institution',
                                                      'institution')
        }
        context['len_list_institution'] = len(context['list_institution'])
        fragment.content = loader.render_django_template(
            'static/html/studio_view.html', context)
        fragment.add_css(
            self.resource_string("static/css/corfogeneratecode.css"))
        fragment.add_javascript(
            self.resource_string("static/js/src/corfogeneratecode_studio.js"))
        fragment.initialize_js('CorfoGenerateXBlock')
        return fragment
Beispiel #4
0
    def studio_view(self, context=None):  # pylint: disable=unused-argument
        """
        Return a fragment that contains the html for the Studio view.
        """
        frag = Fragment()

        settings_fields = self.get_editable_fields()
        settings_page = loader.render_django_template(
            'templates/studio_edit.html', {'fields': settings_fields})
        context = {
            'self': self,
            'settings_page': settings_page,
        }

        frag.content = xblock_loader.render_django_template(
            'static/html/studio.html', context)

        self.add_stylesheets(frag)
        self.add_scripts(frag)

        js_data = {
            'editor': self.editor,
            'skin_url': self.runtime.local_resource_url(self, 'public/skin'),
            'external_plugins': self.get_editor_plugins()
        }
        frag.initialize_js('HTML5XBlock', js_data)

        return frag
Beispiel #5
0
 def studio_view(self, context=None):
     """This is the view displaying xblock form in studio."""
     fragment = Fragment()
     fragment.content = self._render_template('static/html/studio_edit.html', **context)
     fragment.add_javascript(self.resource_string("static/js/src/studio_edit.js"))
     fragment.initialize_js('BotContainerStudio')
     return fragment
Beispiel #6
0
    def studio_view(self, context):
        """
        Render a form for editing this XBlock
        """
        frag = Fragment()
        context = {
            'fields': [],
            'test_id_list': self.test_id_list,
        }

        # Build a list of all the fields that can be edited:
        for field_name in self.editable_fields:
            field = self.fields[field_name]
            if field.scope not in (Scope.content, Scope.settings):
                logger.error(
                    "Only Scope.content or Scope.settings fields can be used with "
                    "StudioEditableXBlockMixin. Other scopes are for user-specific data and are "
                    "not generally created/configured by content authors in Studio."
                )
            field_info = self._make_field_info(field_name, field)
            if field_info is not None:
                context["fields"].append(field_info)
        frag.content = loader.render_django_template(
            "static/html/genesys_edit.html", context)
        frag.add_javascript(
            loader.load_unicode("static/js/src/genesys_edit.js"))
        frag.initialize_js('StudioEditableXBlockMixin')
        return frag
 def studio_view(self, context, override=None):
     """
     Render a form for editing this XBlock. Xblock using this utility
     method can add more functionality to the simple form generated by
     this studio_view method. In this case the overriding method is
     responsible of initializing the fragment javascript function (that's
     fragment.initialize_js part). It is also the overrriding method
     resposability to call 'StudioEditableXBlockMixin' from insdie the
     initialization function. Overriding methods should set override
     paramter to 'True'
     """
     fragment = Fragment()
     context = {'fields': []}
     # Build a list of all the fields that can be edited:
     for field_name in self.editable_fields:
         field = self.fields[field_name]
         assert field.scope in (Scope.content, Scope.settings), (
             "Only Scope.content or Scope.settings fields can be used with "
             "StudioEditableXBlockMixin. Other scopes are for "
             "user-specific data and are ot generally created/configured"
             " by content authors in Studio."
         )
         field_info = self._make_field_info(field_name, field)
         if field_info is not None:
             context["fields"].append(field_info)
     fragment.content = loader.render_template(
         'templates/studio_edit.html', context)
     fragment.add_javascript(loader.load_unicode('public/studio_edit.js'))
     # When ovveride is True that means the child class will call
     # function StudioEditableXBlockMixin his client side JavaScript
     if override is None:
         fragment.initialize_js('StudioEditableXBlockMixin')
     return fragment
 def studio_view(self, context, request=None):
     """
     Render a form for editing this XBlock
     """
     fragment = Fragment()
     context = {'fields': [], 'courseKey': self.location.course_key}
     # Build a list of all the fields that can be edited:
     for field_name in self.editable_fields:
         field = self.fields[field_name]
         assert field.scope in (Scope.content, Scope.settings), (
             "Only Scope.content or Scope.settings fields can be used with "
             "StudioEditableXBlockMixin. Other scopes are for user-specific data and are "
             "not generally created/configured by content authors in Studio."
         )
         field_info = self._make_field_info(field_name, field)
         if field_info is not None:
             context["fields"].append(field_info)
     fragment.content = self.render_template('static/html/studio_edit.html',
                                             context)
     fragment.add_css(
         self.resource_string("static/css/jupyternotebook_xblock.css"))
     fragment.add_javascript(
         self.resource_string("static/js/src/studio_edit.js"))
     fragment.initialize_js('JupyterNotebookStudioEditableXBlock')
     return fragment
    def studio_view(self, context):
        """
        Render a form for editing this XBlock
        """
        fragment = Fragment()
        context = {'fields': []}
        # Build a list of all the fields that can be edited:
        for field_name in self.editable_fields:
            field = self.fields[field_name]
            assert field.scope in (Scope.content, Scope.settings), (
                "Only Scope.content or Scope.settings fields can be used with "
                "StudioEditableXBlockMixin. Other scopes are for user-specific data and are "
                "not generally created/configured by content authors in Studio."
            )
            field_info = self._make_field_info(field_name, field)
            if field_info is not None:
                context["fields"].append(field_info)
        fragment.content = loader.render_template('static/html/infosecurexblock_studio.html', context)
        fragment.add_javascript(loader.load_unicode('static/js/src/infosecurexblock_studio.js'))

        css_urls = (
            "static/css/infosecurexblock_studio.css",
        )
        load_resources([], css_urls, fragment)

        fragment.initialize_js('StudioEditableXBlockMixin')

        return fragment
Beispiel #10
0
    def studio_view(self, context):
        """
        Render a form for editing this XBlock
        """
        xblockId = self._get_xblock_id()
        frag = Fragment()
        context = {'fields': []}
        # Build a list of all the fields that can be edited:
        for field_name in self.editable_fields:
            field = self.fields[field_name]
            assert field.scope in (Scope.content, Scope.settings), (
                "Only Scope.content or Scope.settings fields can be used with "
                "StudioEditableXBlockMixin. Other scopes are for user-specific data and are "
                "not generally created/configured by content authors in Studio."
            )
            field_info = self._make_field_info(field_name, field)
            if field_info is not None:
                if field_name == 'block_id':
                    field_info['value'] = xblockId

                context["fields"].append(field_info)
        frag.content = loader.render_django_template("static/studio_edit.html",
                                                     context)
        frag.add_javascript(loader.load_unicode("static/studio_edit.js"))
        frag.initialize_js('StudioEditableXBlockMixin')
        return frag
Beispiel #11
0
 def fallback_view(self, view_name, context=None):
     result = Fragment()
     child_frags = self.runtime.render_children(self, context=context)
     result.add_frags_resources(child_frags)
     result.content = self.content
     result.add_content(
         self.runtime.render_template("vertical.html",
                                      children=child_frags))
     return result
Beispiel #12
0
def xblock_view_handler(request, package_id, view_name, tag=None, branch=None, version_guid=None, block=None):
    """
    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
    """
    locator = BlockUsageLocator(package_id=package_id, branch=branch, version_guid=version_guid, block_id=block)
    if not has_course_access(request.user, locator):
        raise PermissionDenied()
    old_location = loc_mapper().translate_locator_to_location(locator)

    accept_header = request.META.get('HTTP_ACCEPT', 'application/json')

    if 'application/x-fragment+json' in accept_header:
        store = get_modulestore(old_location)
        component = store.get_item(old_location)

        # wrap the generated fragment in the xmodule_editor div so that the javascript
        # can bind to it correctly
        component.runtime.wrappers.append(partial(wrap_xblock, 'StudioRuntime'))

        if view_name == 'studio_view':
            try:
                fragment = component.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", component, exc_info=True)
                fragment = Fragment(render_to_string('html_error.html', {'message': str(exc)}))

            store.save_xmodule(component)

        elif view_name == 'student_view':
            fragment = get_preview_fragment(request, component)
            fragment.content = render_to_string('component.html', {
                'preview': fragment.content,
                'label': component.display_name or component.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)
Beispiel #13
0
    def student_view(self, context=None):  # pylint: disable=unused-argument
        """
        Return a fragment that contains the html for the student view.
        """
        frag = Fragment()
        frag.content = xblock_loader.render_django_template('static/html/lms.html', {'self': self})

        frag.add_css(self.resource_string('public/plugins/codesample/css/prism.css'))
        frag.add_javascript(self.resource_string('public/plugins/codesample/js/prism.js'))

        frag.add_css(self.resource_string('static/css/pygments.css'))

        return frag
 def studio_view(self, context=None):
     """This is the view displaying xblock form in studio."""
     fragment = Fragment()
     initial = {
         'passing_grade': self.passing_grade,
     }
     form = BotXBlockForm(initial=initial)
     context = {}
     context['form'] = form
     fragment.content = self._render_template('static/html/studio_edit.html', **context)
     fragment.add_javascript(self.resource_string("static/js/src/studio_edit.js"))
     fragment.initialize_js('BotContainerStudio')
     return fragment
 def studio_view(self, context=None):
     """This is the view displaying xblock form in studio."""
     fragment = Fragment()
     initial = {
         'passing_grade': self.passing_grade,
     }
     form = BotXBlockForm(initial=initial)
     context = {}
     context['form'] = form
     fragment.content = self._render_template(
         'static/html/studio_edit.html', **context)
     fragment.add_javascript(
         self.resource_string("static/js/src/studio_edit.js"))
     fragment.initialize_js('BotContainerStudio')
     return fragment
 def studio_view(self, context=None):
     """This is the view displaying xblock form in studio."""
     fragment = Fragment()
     initial = {
             'group_id': self.group_id,
             'start_date': self.configuration.start_date,
             'end_date': self.configuration.end_date,
             'password': self.configuration.password,
             'duration': self.configuration.duration,
             }
     form = PasswordContainerXBlockForm(initial=initial)
     context = {}
     context['form'] = form
     fragment.content = self._render_template('static/html/studio_edit.html', **context)
     fragment.add_javascript(self.resource_string("static/js/src/studio_edit.js"))
     fragment.initialize_js('PasswordContainerStudio')
     return fragment
 def studio_view(self, context):
     """
     Render a form for editing this XBlock
     """
     fragment = Fragment()
     context = {'fields': []}
     # Build a list of all the fields that can be edited:
     for field_name in self.editable_fields:
         field = self.fields[field_name]
         assert field.scope in (Scope.content, Scope.settings)
         field_info = self._make_field_info(field_name, field)
         if field_info is not None:
             context["fields"].append(field_info)
     fragment.content = loader.render_template('templates/studio_edit.html', context)
     fragment.add_javascript(loader.load_unicode('public/js/src/studio_edit.js'))
     # Function StudioEditableXBlockMixin will be called from subclass client side JavaScript
     # fragment.initialize_js('StudioEditableXBlockMixin')
     return fragment
    def studio_view(self, context):
        """
        Render a form for editing this XBlock
        """
        fragment = Fragment()

        context = {
            'xblock': self,
            'field_autoclose': self.fields['autoclose'],
            'location': str(self.location).split('@')[-1]
        }
        context['idform'] = self._make_field_info2('idform',
                                                   self.fields['idform'])

        fragment.content = loader.render_django_template(
            'static/html/studio_view.html', context)
        fragment.add_css(self.resource_string("static/css/eoltimify.css"))
        fragment.add_javascript(
            self.resource_string("static/js/src/eoltimify_studio.js"))
        fragment.initialize_js('EolTimifyXBlock')
        return fragment
 def studio_view(self, context):
     """
     Render a form for editing this XBlock
     """
     fragment = Fragment()
     context = {'fields': []}
     # Build a list of all the fields that can be edited:
     for field_name in self.editable_fields:
         field = self.fields[field_name]
         assert field.scope in (Scope.content, Scope.settings), (
             "Only Scope.content or Scope.settings fields can be used with "
             "StudioEditableXBlockMixin. Other scopes are for user-specific data and are "
             "not generally created/configured by content authors in Studio."
         )
         field_info = self._make_field_info(field_name, field)
         if field_info is not None:
             context["fields"].append(field_info)
     fragment.content = loader.render_template('templates/studio_edit.html', context)
     fragment.add_javascript(loader.load_unicode('public/studio_edit.js'))
     fragment.initialize_js('StudioEditableXBlockMixin')
     return fragment
 def studio_view(self, context):
     """
     Render a form for editing this XBlock
     """
     fragment = Fragment()
     context = {'fields': [],
                'courseKey': self.location.course_key}
     # Build a list of all the fields that can be edited:
     for field_name in self.editable_fields:
         field = self.fields[field_name]
         assert field.scope in (Scope.content, Scope.settings), (
             "Only Scope.content or Scope.settings fields can be used with "
             "StudioEditableXBlockMixin. Other scopes are for user-specific data and are "
             "not generally created/configured by content authors in Studio."
         )
         field_info = self._make_field_info(field_name, field)
         if field_info is not None:
             context["fields"].append(field_info)
     fragment.content = self.render_template('static/html/studio_edit.html', context)
     fragment.add_css(self.resource_string("static/css/jupyterhub_xblock.css"))
     fragment.add_javascript(self.resource_string("static/js/src/studio_edit.js"))
     fragment.initialize_js('JupyterhubStudioEditableXBlock')
     return fragment
Beispiel #21
0
    def student_view(self, context=None):
        """
        The primary view of the CodePlayground XBlock, shown to students when viewing courses.
        """

        if not (self.showanswer):
            self.answer_button_text = self.SHOW_ANSWER_BUTTON_TEXT

        context = {
            'point_string':
            self.point_string,
            'question_content':
            self.question_content,
            'showanswer':
            self.showanswer,
            'code_skeleton':
            self.code_skeleton,
            'expected_output':
            self.expected_output,
            'answer':
            '' if (self.answer_button_text == self.SHOW_ANSWER_BUTTON_TEXT)
            else self.answer,
            'answer_button_text':
            self.answer_button_text
        }

        frag = Fragment()

        frag.content = loader.render_template(
            'static/html/codeplayground.html', context)
        frag.add_css(self.resource_string("static/css/codeplayground.css"))
        frag.add_javascript(
            self.resource_string("static/js/codeplayground.js"))
        frag.initialize_js('CodePlayground')

        return frag
Beispiel #22
0
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 = usage_key_with_run(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 = modulestore()
        xblock = store.get_item(usage_key)
        container_views = ['container_preview', 'reorderable_container_child_preview']

        # 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,
            request_token=request_token(request),
        ))

        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)}))

            store.update_item(xblock, request.user.id)
        elif view_name in (PREVIEW_VIEWS + container_views):
            is_pages_view = view_name == STUDENT_VIEW   # Only the "Pages" view uses student view in Studio

            # 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)

            # Set up the context to be passed to each XBlock's render method.
            context = {
                'is_pages_view': is_pages_view,     # This setting disables the recursive wrapping of xblocks
                'is_unit_page': is_unit(xblock),
                'root_xblock': xblock if (view_name == 'container_preview') else None,
                'reorderable_items': reorderable_items
            }

            fragment = get_preview_fragment(request, xblock, context)

            # Note that the container view recursively adds headers into the preview fragment,
            # so only the "Pages" view requires that this extra wrapper be included.
            if is_pages_view:
                fragment.content = render_to_string('component.html', {
                    'xblock_context': context,
                    'xblock': xblock,
                    'locator': usage_key,
                    '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)
Beispiel #23
0
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 = usage_key_with_run(usage_key_string)
    if not has_course_author_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 = modulestore()
        xblock = store.get_item(usage_key)
        container_views = [
            'container_preview', 'reorderable_container_child_preview'
        ]

        # 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,
                request_token=request_token(request),
            ))

        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=broad-except
                log.debug("unable to render studio_view for %r",
                          xblock,
                          exc_info=True)
                fragment = Fragment(
                    render_to_string('html_error.html', {'message': str(exc)}))

        elif view_name in (PREVIEW_VIEWS + container_views):
            is_pages_view = view_name == STUDENT_VIEW  # Only the "Pages" view uses student view in Studio

            # 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)

            # Set up the context to be passed to each XBlock's render method.
            context = {
                'is_pages_view':
                is_pages_view,  # This setting disables the recursive wrapping of xblocks
                'is_unit_page': is_unit(xblock),
                'root_xblock': xblock if
                (view_name == 'container_preview') else None,
                'reorderable_items': reorderable_items
            }

            fragment = get_preview_fragment(request, xblock, context)

            # Note that the container view recursively adds headers into the preview fragment,
            # so only the "Pages" view requires that this extra wrapper be included.
            if is_pages_view:
                fragment.content = render_to_string(
                    'component.html', {
                        'xblock_context':
                        context,
                        'xblock':
                        xblock,
                        'locator':
                        usage_key,
                        '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)
Beispiel #24
0
def xblock_view_handler(request,
                        package_id,
                        view_name,
                        tag=None,
                        branch=None,
                        version_guid=None,
                        block=None):
    """
    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
    """
    locator = BlockUsageLocator(package_id=package_id,
                                branch=branch,
                                version_guid=version_guid,
                                block_id=block)
    if not has_course_access(request.user, locator):
        raise PermissionDenied()
    old_location = loc_mapper().translate_locator_to_location(locator)

    accept_header = request.META.get('HTTP_ACCEPT', 'application/json')

    if 'application/json' in accept_header:
        store = get_modulestore(old_location)
        component = store.get_item(old_location)

        # wrap the generated fragment in the xmodule_editor div so that the javascript
        # can bind to it correctly
        component.runtime.wrappers.append(partial(wrap_xblock,
                                                  'StudioRuntime'))

        if view_name == 'studio_view':
            try:
                fragment = component.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",
                          component,
                          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(component, None)

        elif view_name == 'student_view' and component.has_children:
            # 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': component,
                    'locator': locator,
                    'reordering_enabled': True,
                })
            return JsonResponse({
                'html': html,
                'resources': [],
            })
        elif view_name in ('student_view', 'container_preview'):
            is_container_view = (view_name == 'container_preview')
            component_publish_state = compute_publish_state(component)
            is_read_only_view = component_publish_state == PublishState.public

            # 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_view,
                'root_xblock': component,
            }

            fragment = get_preview_fragment(request, component, 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', {
                        'preview':
                        fragment.content,
                        'label':
                        component.display_name
                        or component.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)
Beispiel #25
0
def xblock_view_handler(request, package_id, view_name, tag=None, branch=None, version_guid=None, block=None):
    """
    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
    """
    locator = BlockUsageLocator(package_id=package_id, branch=branch, version_guid=version_guid, block_id=block)
    if not has_course_access(request.user, locator):
        raise PermissionDenied()
    old_location = loc_mapper().translate_locator_to_location(locator)

    accept_header = request.META.get('HTTP_ACCEPT', 'application/json')

    if 'application/json' in accept_header:
        store = get_modulestore(old_location)
        component = store.get_item(old_location)

        # wrap the generated fragment in the xmodule_editor div so that the javascript
        # can bind to it correctly
        component.runtime.wrappers.append(partial(wrap_xblock, 'StudioRuntime'))

        if view_name == 'studio_view':
            try:
                fragment = component.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", component, 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(component, None)

        elif view_name == 'student_view' and component.has_children:
            # 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': component,
                'locator': locator,
                'reordering_enabled': True,
            })
            return JsonResponse({
                'html': html,
                'resources': [],
            })
        elif view_name in ('student_view', 'container_preview'):
            is_container_view = (view_name == 'container_preview')

            # 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.
            is_read_only_view = is_container_view
            context = {
                'container_view': is_container_view,
                'read_only': is_read_only_view,
                'root_xblock': component
            }

            fragment = get_preview_fragment(request, component, 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', {
                    'preview': fragment.content,
                    'label': component.display_name or component.scope_ids.block_type,

                    # Native XBlocks are responsible for persisting their own data,
                    # so they are also responsible for providing save/cancel buttons.
                    'show_save_cancel': isinstance(component, xmodule.x_module.XModuleDescriptor),
                })
        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)
Beispiel #26
0
    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': list(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 student_view(self, context=None):
        """
        The primary view of the FormulaExerciseXBlock, shown to students when viewing courses.
        """

        context = {}
        self.submitted_expressions = {}

        if self.xblock_id is None:
            self.xblock_id = unicode(
                self.location.replace(branch=None, version=None))

        if self.newly_created_block:
            self.newly_created_block = (db_service.is_block_in_db(
                self.xblock_id) is False)

        if (self.newly_created_block is
                True):  # generate question template for newly created XBlock
            self.question_template, self.variables, self.expressions = question_service.generate_question_template(
            )
            db_service.create_question_template(self.xblock_id,
                                                self.question_template,
                                                self.variables,
                                                self.expressions)
            self.newly_created_block = False
        else:  # existing question template in dbms
            self.load_data_from_dbms()

        # generate question from template if necessary
        if (self.generated_question == ""):
            self.generated_question, self.generated_variables = question_service.generate_question(
                self.question_template, self.variables)

        for expression_name, expression_value in self.expressions.iteritems():
            self.submitted_expressions[expression_name] = ''

        # load submission data to display the previously submitted result
        submissions = sub_api.get_submissions(self.student_item_key, 1)
        if submissions:
            latest_submission = submissions[0]

            # parse the answer
            answer = latest_submission['answer']
            self.generated_question = answer['generated_question']

            if ('variable_values' in answer):  # backward compatibility
                saved_generated_variables = json.loads(
                    answer['variable_values'])
                for var_name, var_value in saved_generated_variables.iteritems(
                ):
                    self.generated_variables[var_name] = var_value

            saved_submitted_expressions = json.loads(
                answer['expression_values'])
            for submitted_expr_name, submitted_expr_val in saved_submitted_expressions.iteritems(
            ):
                self.submitted_expressions[
                    submitted_expr_name] = submitted_expr_val

            self.attempt_number = latest_submission['attempt_number']
            if (self.attempt_number >= self.max_attempts):
                context['disabled'] = 'disabled'
            else:
                context['disabled'] = ''

        self.serialize_data_to_context(context)

        context['attempt_number'] = self.attempt_number_string
        context['point_string'] = self.point_string
        context['question'] = self.generated_question
        context['xblock_id'] = self.xblock_id
        context['submitted_expressions'] = self.submitted_expressions
        context['show_answer'] = self.show_answer

        frag = Fragment()
        frag.content = loader.render_template(
            'static/html/formula_exercise_block.html', context)
        frag.add_css(
            self.resource_string("static/css/formula_exercise_block.css"))
        frag.add_javascript(
            self.resource_string("static/js/src/formula_exercise_block.js"))
        frag.initialize_js('FormulaExerciseXBlock')
        return frag
Beispiel #28
0
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 = modulestore()
        xblock = store.get_item(usage_key)
        is_read_only = _is_xblock_read_only(xblock)
        container_views = ['container_preview', 'reorderable_container_child_preview']
        unit_views = PREVIEW_VIEWS

        # 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)}))

            store.update_item(xblock, request.user.id)
        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 = {
                '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:
                # For non-leaf xblocks, show the special rendering which links to the new container page.
                if xblock_has_own_studio_page(xblock):
                    template = 'container_xblock_component.html'
                else:
                    template = 'component.html'
                fragment.content = render_to_string(template, {
                    'xblock_context': context,
                    'xblock': xblock,
                    'locator': usage_key,
                    '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)
Beispiel #29
0
    def recap_blocks_listing_view(self, context=None):
        """This view is used in the Racap tab in the LMS Instructor Dashboard
        to display all available course Recap xblocks.

        Args:
            context: contains two items:
                "recap_items" - all course items with names and parents, example:
                    [{"parent_name": "Vertical name",
                      "name": "Recap Display Name",
                     }, ...]
        Returns:
            (Fragment): The HTML Fragment for this XBlock.
        """
        course_id = self.location.course_key
        recap_blocks = self.get_recap_course_blocks(course_id)
        recap_name_list = []

        for block in recap_blocks:
            recap_name_list.append((block.display_name, block.xblock_list))

        make_pdf_json = reverse('xblock_handler', args=[course_id, block.location, 'make_pdf_json'])
        refresh_table = reverse('xblock_handler', args=[course_id, block.location, 'refresh_table'])

        user = self.runtime.get_real_user(self.runtime.anonymous_student_id)
        lang_prefs = get_user_preference(user, LANGUAGE_KEY)

        context_dict = {
            "make_pdf_json": make_pdf_json,
            "refresh_table": refresh_table,
            "recap_name_list": recap_name_list,
            "lang_prefs": lang_prefs
        }

        instructor_dashboard_fragment = Fragment()
        instructor_dashboard_fragment.content = loader.render_django_template(
            'static/html/recap_dashboard.html',
            context_dict
        )
        instructor_dashboard_fragment.add_css(
            self.resource_string("static/css/recap.css")
        )
        instructor_dashboard_fragment.add_css(
            self.resource_string("public/DataTables/css/jquery.dataTables.css")
        )
        instructor_dashboard_fragment.add_javascript_url(
            self.runtime.local_resource_url(
                self,
                'public/FileSaver.js/FileSaver.min.js'
            )
        )
        instructor_dashboard_fragment.add_javascript_url(
            self.runtime.local_resource_url(
                self,
                'public/jsPDF-1.3.2/jspdf.min.js'
            )
        )
        instructor_dashboard_fragment.add_javascript_url(
            self.runtime.local_resource_url(
                self,
                'public/jsPDF-1.3.2/html2canvas.min.js'
            )
        )
        instructor_dashboard_fragment.add_javascript_url(
            self.runtime.local_resource_url(
                self,
                'public/jsPDF-1.3.2/html2pdf.js'
            )
        )
        instructor_dashboard_fragment.add_javascript_url(
            self.runtime.local_resource_url(
                self,
                'public/DataTables/js/jquery.dataTables.js'
            )
        )

        instructor_dashboard_fragment.add_javascript_url(
            self.runtime.local_resource_url(
                self,
                "public/recap_dashboard.js"
            )
        )
        instructor_dashboard_fragment.initialize_js('RecapDashboard')

        return instructor_dashboard_fragment
Beispiel #30
0
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 = usage_key_with_run(usage_key_string)
    if not has_studio_read_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 = modulestore()
        xblock = store.get_item(usage_key)
        container_views = ["container_preview", "reorderable_container_child_preview", "container_child_preview"]

        # 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, request_token=request_token(request))
        )

        if view_name in (STUDIO_VIEW, VISIBILITY_VIEW):
            try:
                fragment = xblock.render(view_name)
            # 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=broad-except
                log.debug("Unable to render %s for %r", view_name, xblock, exc_info=True)
                fragment = Fragment(render_to_string("html_error.html", {"message": str(exc)}))

        elif view_name in PREVIEW_VIEWS + container_views:
            is_pages_view = view_name == STUDENT_VIEW  # Only the "Pages" view uses student view in Studio
            can_edit = has_studio_write_access(request.user, usage_key.course_key)

            # 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)

            paging = None
            try:
                if request.REQUEST.get("enable_paging", "false") == "true":
                    paging = {
                        "page_number": int(request.REQUEST.get("page_number", 0)),
                        "page_size": int(request.REQUEST.get("page_size", 0)),
                    }
            except ValueError:
                # pylint: disable=too-many-format-args
                return HttpResponse(
                    content="Couldn't parse paging parameters: enable_paging: "
                    "{0}, page_number: {1}, page_size: {2}".format(
                        request.REQUEST.get("enable_paging", "false"),
                        request.REQUEST.get("page_number", 0),
                        request.REQUEST.get("page_size", 0),
                    ),
                    status=400,
                    content_type="text/plain",
                )

            force_render = request.REQUEST.get("force_render", None)

            # Set up the context to be passed to each XBlock's render method.
            context = {
                "is_pages_view": is_pages_view,  # This setting disables the recursive wrapping of xblocks
                "is_unit_page": is_unit(xblock),
                "can_edit": can_edit,
                "root_xblock": xblock if (view_name == "container_preview") else None,
                "reorderable_items": reorderable_items,
                "paging": paging,
                "force_render": force_render,
            }

            fragment = get_preview_fragment(request, xblock, context)

            # Note that the container view recursively adds headers into the preview fragment,
            # so only the "Pages" view requires that this extra wrapper be included.
            if is_pages_view:
                fragment.content = render_to_string(
                    "component.html",
                    {
                        "xblock_context": context,
                        "xblock": xblock,
                        "locator": usage_key,
                        "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)
Beispiel #31
0
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 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:
                # For non-leaf xblocks, show the special rendering which links to the new container page.
                if xblock_has_own_studio_page(xblock):
                    template = 'container_xblock_component.html'
                else:
                    template = 'component.html'
                fragment.content = render_to_string(
                    template, {
                        'xblock_context':
                        context,
                        'xblock':
                        xblock,
                        'locator':
                        usage_key,
                        '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)