示例#1
0
    def list_and_format_file_list(self,
                                  title,
                                  subfolder,
                                  links=False,
                                  upload=False,
                                  prefix=None,
                                  caption_if_empty='< none >',
                                  edit_url_template=None,
                                  sub_title=None):
        """Walks files in folders and renders their names in a section."""

        items = safe_dom.NodeList()
        count = 0
        for filename in self.list_files(subfolder):
            if prefix and not filename.startswith(prefix):
                continue
            li = safe_dom.Element('li')
            if links:
                li.add_child(
                    safe_dom.Element(
                        'a', href=urllib.quote(filename)).add_text(filename))
                if edit_url_template:
                    edit_url = edit_url_template % urllib.quote(filename)
                    li.add_child(safe_dom.Entity('&nbsp;')).add_child(
                        safe_dom.Element('a',
                                         href=edit_url).add_text('[Edit]'))
            else:
                li.add_text(filename)
            count += 1
            items.append(li)

        output = safe_dom.NodeList()

        if filer.is_editable_fs(self.app_context) and upload:
            output.append(
                safe_dom.Element(
                    'a',
                    className='btn btn-primary pull-right',
                    href='dashboard?%s' % urllib.urlencode({
                        'action': 'add_asset',
                        'base': subfolder
                    })).add_text('Upload')).append(
                        safe_dom.Element(
                            'div', style='clear: both; padding-top: 2px;'))
        if title:
            h3 = safe_dom.Element('h3')
            if count:
                h3.add_text('%s (%s)' % (title, count))
            else:
                h3.add_text(title)
            output.append(h3)
        if sub_title:
            output.append(safe_dom.Element('blockquote').add_text(sub_title))
        if items:
            output.append(safe_dom.Element('ol').add_children(items))
        else:
            if caption_if_empty:
                output.append(
                    safe_dom.Element('blockquote').add_text(caption_if_empty))
        return output
示例#2
0
    def list_question_groups(self):
        """Prepare a list of question groups."""
        if not filer.is_editable_fs(self.app_context):
            return safe_dom.NodeList()

        all_questions = QuestionDAO.get_all()
        output = safe_dom.NodeList()
        if all_questions:
            output.append(
                safe_dom.Element('a',
                                 className='gcb-button gcb-pull-right',
                                 href='dashboard?action=add_question_group').
                add_text('Add Question Group')).append(
                    safe_dom.Element('div',
                                     style='clear: both; padding-top: 2px;'))
        output.append(safe_dom.Element('h3').add_text('Question Groups'))

        # TODO(jorr): Hook this into the datastore
        all_question_groups = QuestionGroupDAO.get_all()
        if all_question_groups:
            ol = safe_dom.Element('ol')
            for question_group in all_question_groups:
                edit_url = 'dashboard?action=edit_question_group&key=%s' % (
                    question_group.id)
                li = safe_dom.Element('li')
                li.add_text(question_group.description).add_child(
                    safe_dom.Entity('&nbsp;')).add_child(
                        safe_dom.Element('a',
                                         href=edit_url).add_text('[Edit]'))
                ol.add_child(li)
            output.append(ol)
        else:
            output.append(safe_dom.Element('blockquote').add_text('< none >'))

        return output
示例#3
0
    def list_questions(self):
        """Prepare a list of the question bank contents."""
        if not filer.is_editable_fs(self.app_context):
            return safe_dom.NodeList()

        output = safe_dom.NodeList().append(
            safe_dom.Element('a',
                             className='gcb-button gcb-pull-right',
                             href='dashboard?action=add_mc_question').
            add_text('Add Multiple Choice')).append(
                safe_dom.Element('a',
                                 className='gcb-button gcb-pull-right',
                                 href='dashboard?action=add_sa_question').
                add_text('Add Short Answer')).append(
                    safe_dom.Element(
                        'div', style='clear: both; padding-top: 2px;')).append(
                            safe_dom.Element('h3').add_text('Question Bank'))

        all_questions = QuestionDAO.get_all()
        if all_questions:
            ol = safe_dom.Element('ol')
            for question in all_questions:
                edit_url = 'dashboard?action=edit_question&key=%s' % question.id
                li = safe_dom.Element('li')
                li.add_text(question.description).add_child(
                    safe_dom.Entity('&nbsp;')).add_child(
                        safe_dom.Element('a',
                                         href=edit_url).add_text('[Edit]'))
                ol.add_child(li)
            output.append(ol)
        else:
            output.append(safe_dom.Element('blockquote').add_text('< none >'))

        return output
示例#4
0
    def get_settings(self):
        """Renders course settings view."""

        yaml_actions = []

        # Basic course info.
        course_info = [('Course Title',
                        self.app_context.get_environ()['course']['title']),
                       ('Context Path', self.app_context.get_slug()),
                       ('Datastore Namespace',
                        self.app_context.get_namespace_name())]

        # Course file system.
        fs = self.app_context.fs.impl
        course_info.append(('File system', fs.__class__.__name__))
        if fs.__class__ == vfs.LocalReadOnlyFileSystem:
            course_info.append(
                ('Home folder',
                 sites.abspath(self.app_context.get_home_folder(), '/')))

        # Enable editing if supported.
        if filer.is_editable_fs(self.app_context):
            yaml_actions.append({
                'id':
                'edit_course_yaml',
                'caption':
                'Edit',
                'action':
                self.get_action_url('create_or_edit_settings'),
                'xsrf_token':
                self.create_xsrf_token('create_or_edit_settings')
            })

        # Yaml file content.
        yaml_info = []
        yaml_stream = self.app_context.fs.open(
            self.app_context.get_config_filename())
        if yaml_stream:
            yaml_lines = yaml_stream.read().decode('utf-8')
            for line in yaml_lines.split('\n'):
                yaml_info.append(line)
        else:
            yaml_info.append('< empty file >')

        # Prepare template values.
        template_values = {}
        template_values['page_title'] = self.format_title('Settings')
        template_values['page_description'] = messages.SETTINGS_DESCRIPTION
        template_values['sections'] = [{
            'title': 'About the Course',
            'description': messages.ABOUT_THE_COURSE_DESCRIPTION,
            'children': course_info
        }, {
            'title': 'Contents of course.yaml file',
            'description': messages.CONTENTS_OF_THE_COURSE_DESCRIPTION,
            'actions': yaml_actions,
            'children': yaml_info
        }]

        self.render_page(template_values)
示例#5
0
    def list_and_format_file_list(
        self, title, subfolder,
        links=False, upload=False, prefix=None, caption_if_empty='< none >',
        edit_url_template=None, merge_local_files=False, sub_title=None):
        """Walks files in folders and renders their names in a section."""

        items = safe_dom.NodeList()
        count = 0
        for filename in self.list_files(
                subfolder, merge_local_files=merge_local_files):
            if prefix and not filename.startswith(prefix):
                continue
            li = safe_dom.Element('li')
            if links:
                li.add_child(safe_dom.Element(
                    'a', href=urllib.quote(filename)).add_text(filename))
            else:
                li.add_text(filename)
            if (edit_url_template and
                self.app_context.fs.impl.is_read_write()):
                edit_url = edit_url_template % urllib.quote(filename)
                li.add_child(
                    safe_dom.Entity('&nbsp;')
                ).add_child(
                    safe_dom.Element('a', href=edit_url).add_text('[Edit]'))
            count += 1
            items.append(li)

        output = safe_dom.NodeList()

        if filer.is_editable_fs(self.app_context) and upload:
            output.append(
                safe_dom.Element(
                    'a', className='gcb-button gcb-pull-right',
                    href='dashboard?%s' % urllib.urlencode(
                        {'action': 'add_asset', 'base': subfolder})
                ).add_text(
                    'Upload to ' +
                    filer.strip_leading_and_trailing_slashes(subfolder))
            ).append(
                safe_dom.Element('div', style='clear: both; padding-top: 2px;'))
        if title:
            h3 = safe_dom.Element('h3')
            if count:
                h3.add_text('%s (%s)' % (title, count))
            else:
                h3.add_text(title)
            output.append(h3)
        if sub_title:
            output.append(safe_dom.Element('blockquote').add_text(sub_title))
        if items:
            output.append(safe_dom.Element('ol').add_children(items))
        else:
            if caption_if_empty:
                output.append(
                    safe_dom.Element('blockquote').add_text(caption_if_empty))
        return output
示例#6
0
    def get_settings(self):
        """Renders course settings view."""

        yaml_actions = []

        # Basic course info.
        course_info = [
            ('Course Title', self.app_context.get_environ()['course']['title']),
            ('Context Path', self.app_context.get_slug()),
            ('Datastore Namespace', self.app_context.get_namespace_name())]

        # Course file system.
        fs = self.app_context.fs.impl
        course_info.append(('File system', fs.__class__.__name__))
        if fs.__class__ == vfs.LocalReadOnlyFileSystem:
            course_info.append(('Home folder', sites.abspath(
                self.app_context.get_home_folder(), '/')))

        # Enable editing if supported.
        if filer.is_editable_fs(self.app_context):
            yaml_actions.append({
                'id': 'edit_course_yaml',
                'caption': 'Edit',
                'action': self.get_action_url('create_or_edit_settings'),
                'xsrf_token': self.create_xsrf_token(
                    'create_or_edit_settings')})

        # Yaml file content.
        yaml_info = []
        yaml_stream = self.app_context.fs.open(
            self.app_context.get_config_filename())
        if yaml_stream:
            yaml_lines = yaml_stream.read().decode('utf-8')
            for line in yaml_lines.split('\n'):
                yaml_info.append(line)
        else:
            yaml_info.append('< empty file >')

        # Prepare template values.
        template_values = {}
        template_values['page_title'] = self.format_title('Settings')
        template_values['page_description'] = messages.SETTINGS_DESCRIPTION
        template_values['sections'] = [
            {
                'title': 'About the Course',
                'description': messages.ABOUT_THE_COURSE_DESCRIPTION,
                'children': course_info},
            {
                'title': 'Contents of course.yaml file',
                'description': messages.CONTENTS_OF_THE_COURSE_DESCRIPTION,
                'actions': yaml_actions,
                'children': yaml_info}]

        self.render_page(template_values)
示例#7
0
    def list_and_format_file_list(self,
                                  title,
                                  subfolder,
                                  links=False,
                                  upload=False,
                                  prefix=None,
                                  caption_if_empty='< none >',
                                  edit_url_template=None,
                                  sub_title=None):
        """Walks files in folders and renders their names in a section."""

        lines = []
        count = 0
        for filename in self.list_files(subfolder):
            if prefix and not filename.startswith(prefix):
                continue
            if links:
                lines.append('<li><a href="%s">%s</a>' %
                             (urllib.quote(filename), cgi.escape(filename)))
                if edit_url_template:
                    edit_url = edit_url_template % urllib.quote(filename)
                    lines.append('&nbsp;<a href="%s">[Edit]</a>' % edit_url)
                lines.append('</li>\n')
            else:
                lines.append('<li>%s</li>\n' % cgi.escape(filename))
            count += 1

        output = []

        if filer.is_editable_fs(self.app_context) and upload:
            output.append(
                '<a class="gcb-button pull-right" href="dashboard?%s">'
                'Upload</a>' % urllib.urlencode({
                    'action': 'add_asset',
                    'base': subfolder
                }))
            output.append('<div style=\"clear: both; padding-top: 2px;\" />')
        if title:
            output.append('<h3>%s' % cgi.escape(title))
            if count:
                output.append(' (%s)' % count)
            output.append('</h3>')
        if sub_title:
            output.append('<blockquote>%s</blockquote>' %
                          cgi.escape(sub_title))
        if lines:
            output.append('<ol>')
            output += lines
            output.append('</ol>')
        else:
            if caption_if_empty:
                output.append('<blockquote>%s</blockquote>' %
                              cgi.escape(caption_if_empty))
        return output
示例#8
0
    def list_and_format_file_list(
        self, title, subfolder,
        links=False, upload=False, prefix=None, caption_if_empty='< none >',
        edit_url_template=None, sub_title=None):
        """Walks files in folders and renders their names in a section."""

        lines = []
        count = 0
        for filename in self.list_files(subfolder):
            if prefix and not filename.startswith(prefix):
                continue
            if links:
                lines.append(
                    '<li><a href="%s">%s</a>' % (
                        urllib.quote(filename), cgi.escape(filename)))
                if edit_url_template:
                    edit_url = edit_url_template % urllib.quote(filename)
                    lines.append('&nbsp;<a href="%s">[Edit]</a>' % edit_url)
                lines.append('</li>\n')
            else:
                lines.append('<li>%s</li>\n' % cgi.escape(filename))
            count += 1

        output = []

        if filer.is_editable_fs(self.app_context) and upload:
            output.append(
                '<a class="gcb-button pull-right" href="dashboard?%s">'
                'Upload</a>' % urllib.urlencode(
                    {'action': 'add_asset', 'base': subfolder}))
            output.append('<div style=\"clear: both; padding-top: 2px;\" />')
        if title:
            output.append('<h3>%s' % cgi.escape(title))
            if count:
                output.append(' (%s)' % count)
            output.append('</h3>')
        if sub_title:
            output.append('<blockquote>%s</blockquote>' % cgi.escape(sub_title))
        if lines:
            output.append('<ol>')
            output += lines
            output.append('</ol>')
        else:
            if caption_if_empty:
                output.append(
                    '<blockquote>%s</blockquote>' % cgi.escape(
                        caption_if_empty))
        return output
示例#9
0
    def _render_edit_form_for(self,
                              rest_handler_cls,
                              title,
                              annotations_dict=None,
                              delete_xsrf_token='delete-unit',
                              page_description=None):
        """Renders an editor form for a given REST handler class."""
        if not annotations_dict:
            annotations_dict = rest_handler_cls.SCHEMA_ANNOTATIONS_DICT

        key = self.request.get('key')

        extra_args = {}
        if self.request.get('is_newly_created'):
            extra_args['is_newly_created'] = 1

        exit_url = self.canonicalize_url('/dashboard')
        rest_url = self.canonicalize_url(rest_handler_cls.URI)
        delete_url = '%s?%s' % (
            self.canonicalize_url(rest_handler_cls.URI),
            urllib.urlencode({
                'key':
                key,
                'xsrf_token':
                cgi.escape(self.create_xsrf_token(delete_xsrf_token))
            }))

        form_html = oeditor.ObjectEditor.get_html_for(
            self,
            rest_handler_cls.SCHEMA_JSON,
            annotations_dict,
            key,
            rest_url,
            exit_url,
            extra_args=extra_args,
            delete_url=delete_url,
            delete_method='delete',
            read_only=not filer.is_editable_fs(self.app_context),
            required_modules=rest_handler_cls.REQUIRED_MODULES)

        template_values = {}
        template_values['page_title'] = self.format_title('Edit %s' % title)
        if page_description:
            template_values['page_description'] = page_description
        template_values['main_content'] = form_html
        self.render_page(template_values)
示例#10
0
    def list_question_groups(self):
        """Prepare a list of question groups."""
        if not filer.is_editable_fs(self.app_context):
            return safe_dom.NodeList()

        all_questions = QuestionDAO.get_all()
        output = safe_dom.NodeList()
        if all_questions:
            output.append(
                safe_dom.Element(
                    'a', className='gcb-button gcb-pull-right',
                    href='dashboard?action=add_question_group'
                ).add_text('Add Question Group')
            ).append(
                safe_dom.Element(
                    'div', style='clear: both; padding-top: 2px;'
                )
            )
        output.append(
            safe_dom.Element('h3').add_text('Question Groups')
        )

        # TODO(jorr): Hook this into the datastore
        all_question_groups = QuestionGroupDAO.get_all()
        if all_question_groups:
            ol = safe_dom.Element('ol')
            for question_group in all_question_groups:
                edit_url = 'dashboard?action=edit_question_group&key=%s' % (
                    question_group.id)
                li = safe_dom.Element('li')
                li.add_text(
                    question_group.description
                ).add_child(
                    safe_dom.Entity('&nbsp;')
                ).add_child(
                    safe_dom.Element('a', href=edit_url).add_text('[Edit]'))
                ol.add_child(li)
            output.append(ol)
        else:
            output.append(safe_dom.Element('blockquote').add_text('< none >'))

        return output
示例#11
0
    def _render_edit_form_for(
        self, rest_handler_cls, title, annotations_dict=None, delete_xsrf_token="delete-unit", page_description=None
    ):
        """Renders an editor form for a given REST handler class."""
        if not annotations_dict:
            annotations_dict = rest_handler_cls.SCHEMA_ANNOTATIONS_DICT

        key = self.request.get("key")

        extra_args = {}
        if self.request.get("is_newly_created"):
            extra_args["is_newly_created"] = 1

        exit_url = self.canonicalize_url("/dashboard")
        rest_url = self.canonicalize_url(rest_handler_cls.URI)
        delete_url = "%s?%s" % (
            self.canonicalize_url(rest_handler_cls.URI),
            urllib.urlencode({"key": key, "xsrf_token": cgi.escape(self.create_xsrf_token(delete_xsrf_token))}),
        )

        form_html = oeditor.ObjectEditor.get_html_for(
            self,
            rest_handler_cls.SCHEMA_JSON,
            annotations_dict,
            key,
            rest_url,
            exit_url,
            extra_args=extra_args,
            delete_url=delete_url,
            delete_method="delete",
            read_only=not filer.is_editable_fs(self.app_context),
            required_modules=rest_handler_cls.REQUIRED_MODULES,
        )

        template_values = {}
        template_values["page_title"] = self.format_title("Edit %s" % title)
        if page_description:
            template_values["page_description"] = page_description
        template_values["main_content"] = form_html
        self.render_page(template_values)
示例#12
0
    def list_questions(self):
        """Prepare a list of the question bank contents."""
        if not filer.is_editable_fs(self.app_context):
            return safe_dom.NodeList()

        output = safe_dom.NodeList().append(
            safe_dom.Element(
                'a', className='gcb-button gcb-pull-right',
                href='dashboard?action=add_mc_question'
            ).add_text('Add Multiple Choice')
        ).append(
            safe_dom.Element(
                'a', className='gcb-button gcb-pull-right',
                href='dashboard?action=add_sa_question'
            ).add_text('Add Short Answer')
        ).append(
            safe_dom.Element('div', style='clear: both; padding-top: 2px;')
        ).append(
            safe_dom.Element('h3').add_text('Question Bank')
        )

        all_questions = QuestionDAO.get_all()
        if all_questions:
            ol = safe_dom.Element('ol')
            for question in all_questions:
                edit_url = 'dashboard?action=edit_question&key=%s' % question.id
                li = safe_dom.Element('li')
                li.add_text(
                    question.description
                ).add_child(
                    safe_dom.Entity('&nbsp;')
                ).add_child(
                    safe_dom.Element('a', href=edit_url).add_text('[Edit]'))
                ol.add_child(li)
            output.append(ol)
        else:
            output.append(safe_dom.Element('blockquote').add_text('< none >'))

        return output
    def _render_edit_form_for(
        self, rest_handler_cls, title, annotations_dict=None,
        delete_xsrf_token='delete-unit', page_description=None):
        """Renders an editor form for a given REST handler class."""
        if not annotations_dict:
            annotations_dict = rest_handler_cls.SCHEMA_ANNOTATIONS_DICT

        key = self.request.get('key')

        extra_args = {}
        if self.request.get('is_newly_created'):
            extra_args['is_newly_created'] = 1

        exit_url = self.canonicalize_url('/dashboard')
        rest_url = self.canonicalize_url(rest_handler_cls.URI)
        delete_url = '%s?%s' % (
            self.canonicalize_url(rest_handler_cls.URI),
            urllib.urlencode({
                'key': key,
                'xsrf_token': cgi.escape(
                    self.create_xsrf_token(delete_xsrf_token))
                }))

        form_html = oeditor.ObjectEditor.get_html_for(
            self,
            rest_handler_cls.SCHEMA_JSON,
            annotations_dict,
            key, rest_url, exit_url,
            extra_args=extra_args,
            delete_url=delete_url, delete_method='delete',
            read_only=not filer.is_editable_fs(self.app_context),
            required_modules=rest_handler_cls.REQUIRED_MODULES)

        template_values = {}
        template_values['page_title'] = self.format_title('Edit %s' % title)
        if page_description:
            template_values['page_description'] = page_description
        template_values['main_content'] = form_html
        self.render_page(template_values)
示例#14
0
    def render_course_outline_to_html(self):
        """CGL-MOOC-Builder: The original function was modified to cooperate
        with Section -> Units -> Lessons course structure.
        Renders course outline to HTML."""
        course = courses.Course(self)
        if not course.get_units():
            return []

        is_editable = filer.is_editable_fs(self.app_context)

        # CGL-MOOC-Builder: Sort and group all units by section_id
        unitObj = course.get_units()
        sortedUnits = sorted(unitObj, key = lambda x: int(x.section_id or 0))
        groups = []
        keys = []
        for k, g in groupby(sortedUnits, key = lambda x: int(x.section_id or 0)):
            groups.append(list(g))
            keys.append(k)
        # CGL-MOOC-Builder: Loop through Section, Units and Lessons
        outline = safe_dom.Element('ul', style='list-style: none;')
        for s in groups:
            lines = safe_dom.Element('ul', style='list-style: none;')
            for unit in s:
                if unit.type == verify.UNIT_TYPE_ASSESSMENT:
                    li = safe_dom.Element('li').add_child(
                        safe_dom.Element(
                            'a', href='assessment?name=%s' % unit.unit_id,
                            className='strong'
                        ).add_text(unit.title)
                    ).add_child(self._get_availability(unit))
                    if is_editable:
                        url = self.canonicalize_url(
                            '/dashboard?%s') % urllib.urlencode({
                                'action': 'edit_assessment',
                                'key': unit.unit_id})
                        li.add_child(self._get_edit_link(url))
                    lines.add_child(li)
                    continue

                if unit.type == verify.UNIT_TYPE_LINK:
                    li = safe_dom.Element('li').add_child(
                        safe_dom.Element(
                            'a', href=unit.href, className='strong'
                        ).add_text(unit.title)
                    ).add_child(self._get_availability(unit))
                    if is_editable:
                        url = self.canonicalize_url(
                            '/dashboard?%s') % urllib.urlencode({
                                'action': 'edit_link',
                                'key': unit.unit_id})
                        li.add_child(self._get_edit_link(url))
                    lines.add_child(li)
                    continue

                if unit.type == verify.UNIT_TYPE_UNIT:
                    li = safe_dom.Element('li').add_child(
                        safe_dom.Element(
                            'a', href='unit?unit=%s' % unit.unit_id,
                            className='strong').add_text(
                                'Unit %s - %s' % (unit.index, unit.title))
                    ).add_child(self._get_availability(unit))
                    if is_editable:
                        url = self.canonicalize_url(
                            '/dashboard?%s') % urllib.urlencode({
                                'action': 'edit_unit',
                                'key': unit.unit_id})
                        li.add_child(self._get_edit_link(url))

                    ol = safe_dom.Element('ol')
                    for lesson in course.get_lessons(unit.unit_id):
                        li2 = safe_dom.Element('li').add_child(
                            safe_dom.Element(
                                'a',
                                href='unit?unit=%s&lesson=%s' % (
                                    unit.unit_id, lesson.lesson_id),
                            ).add_text(lesson.title)
                        ).add_child(self._get_availability(lesson))
                        if is_editable:
                            url = self.get_action_url(
                                'edit_lesson', key=lesson.lesson_id)
                            li2.add_child(self._get_edit_link(url))
                        ol.add_child(li2)

                    li.add_child(ol)
                    lines.add_child(li)
                    continue

                raise Exception('Unknown unit type: %s.' % unit.type)

            liSection = safe_dom.Element('li')
            liSection.add_child(safe_dom.Element(
                'span')).add_text(
                        'Section %s - %s' % (
                            unit.section_id, unit.section_title))

            # CGL-MOOC-Builder: adds a link for edit section content
            if is_editable:
                section_edit_url = self.canonicalize_url(
                    '/dashboard?%s') % urllib.urlencode({
                        'action': 'edit_section',
                        'key': unit.unit_id})
                liSection.add_child(self._get_edit_link(section_edit_url))

            liSection.add_child(lines)
            outline.add_child(liSection)

        return outline
示例#15
0
    def get_outline(self):
        """Renders course outline view."""

        pages_info = [
            safe_dom.Element(
                'a', href=self.canonicalize_url('/announcements')
            ).add_text('Announcements'),
            safe_dom.Element(
                'a', href=self.canonicalize_url('/course')
            ).add_text('Course')]

        outline_actions = []
        if filer.is_editable_fs(self.app_context):
            outline_actions.append({
                'id': 'edit_unit_lesson',
                'caption': 'Organize',
                'href': self.get_action_url('edit_unit_lesson')})
            all_units = courses.Course(self).get_units()
            if any([unit.type == verify.UNIT_TYPE_UNIT for unit in all_units]):
                outline_actions.append({
                    'id': 'add_lesson',
                    'caption': 'Add Lesson',
                    'action': self.get_action_url('add_lesson'),
                    'xsrf_token': self.create_xsrf_token('add_lesson')})
            outline_actions.append({
                'id': 'add_unit',
                'caption': 'Add Unit',
                'action': self.get_action_url('add_unit'),
                'xsrf_token': self.create_xsrf_token('add_unit')})
            outline_actions.append({
                'id': 'add_link',
                'caption': 'Add Link',
                'action': self.get_action_url('add_link'),
                'xsrf_token': self.create_xsrf_token('add_link')})
            outline_actions.append({
                'id': 'add_assessment',
                'caption': 'Add Assessment',
                'action': self.get_action_url('add_assessment'),
                'xsrf_token': self.create_xsrf_token('add_assessment')})
            if not courses.Course(self).get_units():
                outline_actions.append({
                    'id': 'import_course',
                    'caption': 'Import',
                    'href': self.get_action_url('import_course')
                    })

        data_info = self.list_files('/data/')

        sections = [
            {
                'title': 'Pages',
                'description': messages.PAGES_DESCRIPTION,
                'children': pages_info},
            {
                'title': 'Course Outline',
                'description': messages.COURSE_OUTLINE_DESCRIPTION,
                'actions': outline_actions,
                'pre': self.render_course_outline_to_html()},
            {
                'title': 'Data Files',
                'description': messages.DATA_FILES_DESCRIPTION,
                'children': data_info}]

        template_values = {}
        template_values['page_title'] = self.format_title('Outline')
        template_values['alerts'] = self._get_alerts()
        template_values['sections'] = sections
        self.render_page(template_values)
示例#16
0
    def render_course_outline_to_html(self):
        """Renders course outline to HTML."""
        course = courses.Course(self)
        if not course.get_units():
            return []

        is_editable = filer.is_editable_fs(self.app_context)

        lines = safe_dom.Element('ul', style='list-style: none;')
        for unit in course.get_units():
            if unit.type == verify.UNIT_TYPE_ASSESSMENT:
                li = safe_dom.Element('li').add_child(
                    safe_dom.Element(
                        'a', href='assessment?name=%s' % unit.unit_id,
                        className='strong'
                    ).add_text(unit.title)
                ).add_child(self._get_availability(unit))
                if is_editable:
                    url = self.canonicalize_url(
                        '/dashboard?%s') % urllib.urlencode({
                            'action': 'edit_assessment',
                            'key': unit.unit_id})
                    li.add_child(self._get_edit_link(url))
                lines.add_child(li)
                continue

            if unit.type == verify.UNIT_TYPE_LINK:
                li = safe_dom.Element('li').add_child(
                    safe_dom.Element(
                        'a', href=unit.href, className='strong'
                    ).add_text(unit.title)
                ).add_child(self._get_availability(unit))
                if is_editable:
                    url = self.canonicalize_url(
                        '/dashboard?%s') % urllib.urlencode({
                            'action': 'edit_link',
                            'key': unit.unit_id})
                    li.add_child(self._get_edit_link(url))
                lines.add_child(li)
                continue

            if unit.type == verify.UNIT_TYPE_UNIT:
                li = safe_dom.Element('li').add_child(
                    safe_dom.Element(
                        'a', href='unit?unit=%s' % unit.unit_id,
                        className='strong').add_text(
                            'Unit %s - %s' % (unit.index, unit.title))
                ).add_child(self._get_availability(unit))
                if is_editable:
                    url = self.canonicalize_url(
                        '/dashboard?%s') % urllib.urlencode({
                            'action': 'edit_unit',
                            'key': unit.unit_id})
                    li.add_child(self._get_edit_link(url))

                ol = safe_dom.Element('ol')
                for lesson in course.get_lessons(unit.unit_id):
                    li2 = safe_dom.Element('li').add_child(
                        safe_dom.Element(
                            'a',
                            href='unit?unit=%s&lesson=%s' % (
                                unit.unit_id, lesson.lesson_id),
                        ).add_text(lesson.title)
                    ).add_child(self._get_availability(lesson))
                    if is_editable:
                        url = self.get_action_url(
                            'edit_lesson', key=lesson.lesson_id)
                        li2.add_child(self._get_edit_link(url))
                    ol.add_child(li2)
                li.add_child(ol)
                lines.add_child(li)
                continue

            raise Exception('Unknown unit type: %s.' % unit.type)

        return lines
示例#17
0
    def list_and_format_file_list(
        self, title, subfolder,
        links=False, upload=False, prefix=None, caption_if_empty='< none >',
        edit_url_template=None, merge_local_files=False, sub_title=None):
        """Walks files in folders and renders their names in a section."""

        # keep a list of files without merging
        unmerged_files = {}
        if merge_local_files:
            unmerged_files = self.list_files(subfolder, merge_local_files=False)

        items = safe_dom.NodeList()
        count = 0
        for filename in self.list_files(
                subfolder, merge_local_files=merge_local_files):
            if prefix and not filename.startswith(prefix):
                continue

            # show different captions depending if the override exists or not
            has_override = filename in unmerged_files
            link_caption = '[Override]'
            if has_override or not merge_local_files:
                link_caption = '[Edit]'

            # make a <li> item
            li = safe_dom.Element('li')
            if links:
                li.add_child(safe_dom.Element(
                    'a', href=urllib.quote(filename)).add_text(filename))
            else:
                li.add_text(filename)

            # add actions if available
            if (edit_url_template and
                self.app_context.fs.impl.is_read_write()):
                edit_url = edit_url_template % urllib.quote(filename)
                li.add_child(
                    safe_dom.Entity('&nbsp;')
                ).add_child(
                    safe_dom.Element('a', href=edit_url).add_text(link_caption))

            count += 1
            items.append(li)

        output = safe_dom.NodeList()

        if filer.is_editable_fs(self.app_context) and upload:
            output.append(
                safe_dom.Element(
                    'a', className='gcb-button gcb-pull-right',
                    href='dashboard?%s' % urllib.urlencode(
                        {'action': 'add_asset', 'base': subfolder})
                ).add_text(
                    'Upload to ' +
                    filer.strip_leading_and_trailing_slashes(subfolder))
            ).append(
                safe_dom.Element(
                    'div', style='clear: both; padding-top: 2px;'
                )
            )
        if title:
            h3 = safe_dom.Element('h3')
            if count:
                h3.add_text('%s (%s)' % (title, count))
            else:
                h3.add_text(title)
            output.append(h3)
        if sub_title:
            output.append(safe_dom.Element('blockquote').add_text(sub_title))
        if items:
            output.append(safe_dom.Element('ol').add_children(items))
        else:
            if caption_if_empty:
                output.append(
                    safe_dom.Element('blockquote').add_text(caption_if_empty))
        return output
示例#18
0
    def get_outline(self):
        """Renders course outline view."""

        pages_info = [
            safe_dom.Element('a', href=self.canonicalize_url(
                '/announcements')).add_text('Announcements'),
            safe_dom.Element(
                'a', href=self.canonicalize_url('/course')).add_text('Course')
        ]

        outline_actions = []
        if filer.is_editable_fs(self.app_context):
            outline_actions.append({
                'id':
                'edit_unit_lesson',
                'caption':
                'Organize',
                'href':
                self.get_action_url('edit_unit_lesson')
            })
            all_units = courses.Course(self).get_units()
            if any([unit.type == verify.UNIT_TYPE_UNIT for unit in all_units]):
                outline_actions.append({
                    'id':
                    'add_lesson',
                    'caption':
                    'Add Lesson',
                    'action':
                    self.get_action_url('add_lesson'),
                    'xsrf_token':
                    self.create_xsrf_token('add_lesson')
                })
            outline_actions.append({
                'id':
                'add_unit',
                'caption':
                'Add Unit',
                'action':
                self.get_action_url('add_unit'),
                'xsrf_token':
                self.create_xsrf_token('add_unit')
            })
            outline_actions.append({
                'id':
                'add_link',
                'caption':
                'Add Link',
                'action':
                self.get_action_url('add_link'),
                'xsrf_token':
                self.create_xsrf_token('add_link')
            })
            outline_actions.append({
                'id':
                'add_assessment',
                'caption':
                'Add Assessment',
                'action':
                self.get_action_url('add_assessment'),
                'xsrf_token':
                self.create_xsrf_token('add_assessment')
            })
            if not courses.Course(self).get_units():
                outline_actions.append({
                    'id':
                    'import_course',
                    'caption':
                    'Import',
                    'href':
                    self.get_action_url('import_course')
                })

        data_info = self.list_files('/data/')

        sections = [{
            'title': 'Pages',
            'description': messages.PAGES_DESCRIPTION,
            'children': pages_info
        }, {
            'title': 'Course Outline',
            'description': messages.COURSE_OUTLINE_DESCRIPTION,
            'actions': outline_actions,
            'pre': self.render_course_outline_to_html()
        }, {
            'title': 'Data Files',
            'description': messages.DATA_FILES_DESCRIPTION,
            'children': data_info
        }]

        template_values = {}
        template_values['page_title'] = self.format_title('Outline')
        template_values['alerts'] = self._get_alerts()
        template_values['sections'] = sections
        self.render_page(template_values)
示例#19
0
    def render_course_outline_to_html(self):
        """Renders course outline to HTML."""
        course = courses.Course(self)
        if not course.get_units():
            return []

        is_editable = filer.is_editable_fs(self.app_context)

        lines = safe_dom.Element('ul', style='list-style: none;')
        for unit in course.get_units():
            if unit.type == verify.UNIT_TYPE_ASSESSMENT:
                li = safe_dom.Element('li').add_child(
                    safe_dom.Element('a',
                                     href='assessment?name=%s' % unit.unit_id,
                                     className='strong').add_text(
                                         unit.title)).add_child(
                                             self._get_availability(unit))
                if is_editable:
                    url = self.canonicalize_url(
                        '/dashboard?%s') % urllib.urlencode({
                            'action': 'edit_assessment',
                            'key': unit.unit_id
                        })
                    li.add_child(self._get_edit_link(url))
                lines.add_child(li)
                continue

            if unit.type == verify.UNIT_TYPE_LINK:
                li = safe_dom.Element('li').add_child(
                    safe_dom.Element('a', href=unit.href,
                                     className='strong').add_text(
                                         unit.title)).add_child(
                                             self._get_availability(unit))
                if is_editable:
                    url = self.canonicalize_url(
                        '/dashboard?%s') % urllib.urlencode({
                            'action': 'edit_link',
                            'key': unit.unit_id
                        })
                    li.add_child(self._get_edit_link(url))
                lines.add_child(li)
                continue

            if unit.type == verify.UNIT_TYPE_UNIT:
                li = safe_dom.Element('li').add_child(
                    safe_dom.Element('a',
                                     href='unit?unit=%s' % unit.unit_id,
                                     className='strong').add_text(
                                         'Unit %s - %s' %
                                         (unit.index, unit.title))).add_child(
                                             self._get_availability(unit))
                if is_editable:
                    url = self.canonicalize_url(
                        '/dashboard?%s') % urllib.urlencode({
                            'action': 'edit_unit',
                            'key': unit.unit_id
                        })
                    li.add_child(self._get_edit_link(url))

                ol = safe_dom.Element('ol')
                for lesson in course.get_lessons(unit.unit_id):
                    li2 = safe_dom.Element('li').add_child(
                        safe_dom.Element(
                            'a',
                            href='unit?unit=%s&lesson=%s' %
                            (unit.unit_id, lesson.lesson_id),
                        ).add_text(lesson.title)).add_child(
                            self._get_availability(lesson))
                    if is_editable:
                        url = self.get_action_url('edit_lesson',
                                                  key=lesson.lesson_id)
                        li2.add_child(self._get_edit_link(url))
                    ol.add_child(li2)
                li.add_child(ol)
                lines.add_child(li)
                continue

            raise Exception('Unknown unit type: %s.' % unit.type)

        return lines
示例#20
0
    def render_course_outline_to_html(self):
        """Renders course outline to HTML."""
        course = courses.Course(self)
        if not course.get_units():
            return []

        is_editable = filer.is_editable_fs(self.app_context)

        lines = []
        lines.append('<ul style="list-style: none;">')
        for unit in course.get_units():
            if unit.type == 'A':
                lines.append('<li>')
                lines.append(
                    '<strong><a href="assessment?name=%s">%s</a></strong>' % (
                        unit.unit_id, cgi.escape(unit.title)))
                lines.append(self._get_availability(unit))
                if is_editable:
                    url = self.canonicalize_url(
                        '/dashboard?%s') % urllib.urlencode({
                            'action': 'edit_assessment',
                            'key': unit.unit_id})
                    lines.append(self._get_edit_link(url))
                lines.append('</li>\n')
                continue

            if unit.type == 'O':
                lines.append('<li>')
                lines.append(
                    '<strong><a href="%s">%s</a></strong>' % (
                        unit.href, cgi.escape(unit.title)))
                lines.append(self._get_availability(unit))
                if is_editable:
                    url = self.canonicalize_url(
                        '/dashboard?%s') % urllib.urlencode({
                            'action': 'edit_link',
                            'key': unit.unit_id})
                    lines.append(self._get_edit_link(url))
                lines.append('</li>\n')
                continue

            if unit.type == 'U':
                lines.append('<li>')
                lines.append(
                    ('<strong><a href="unit?unit=%s">Unit %s - %s</a>'
                     '</strong>') % (
                         unit.unit_id, unit.index, cgi.escape(unit.title)))
                lines.append(self._get_availability(unit))
                if is_editable:
                    url = self.canonicalize_url(
                        '/dashboard?%s') % urllib.urlencode({
                            'action': 'edit_unit',
                            'key': unit.unit_id})
                    lines.append(self._get_edit_link(url))

                lines.append('<ol>')
                for lesson in course.get_lessons(unit.unit_id):
                    lines.append(
                        '<li><a href="unit?unit=%s&lesson=%s">%s</a>\n' % (
                            unit.unit_id, lesson.lesson_id,
                            cgi.escape(lesson.title)))
                    lines.append(self._get_availability(lesson))
                    if is_editable:
                        url = self.get_action_url(
                            'edit_lesson', key=lesson.lesson_id)
                        lines.append(self._get_edit_link(url))
                    lines.append('</li>')
                lines.append('</ol>')
                lines.append('</li>\n')
                continue

            raise Exception('Unknown unit type: %s.' % unit.type)

        lines.append('</ul>')
        return ''.join(lines)
示例#21
0
    def render_course_outline_to_html(self):
        """Renders course outline to HTML."""
        course = courses.Course(self)
        if not course.get_units():
            return []

        is_editable = filer.is_editable_fs(self.app_context)

        lines = []
        lines.append('<ul style="list-style: none;">')
        for unit in course.get_units():
            if unit.type == 'A':
                lines.append('<li>')
                lines.append(
                    '<strong><a href="assessment?name=%s">%s</a></strong>' %
                    (unit.unit_id, cgi.escape(unit.title)))
                lines.append(self._get_availability(unit))
                if is_editable:
                    url = self.canonicalize_url(
                        '/dashboard?%s') % urllib.urlencode({
                            'action': 'edit_assessment',
                            'key': unit.unit_id
                        })
                    lines.append(self._get_edit_link(url))
                lines.append('</li>\n')
                continue

            if unit.type == 'O':
                lines.append('<li>')
                lines.append('<strong><a href="%s">%s</a></strong>' %
                             (unit.href, cgi.escape(unit.title)))
                lines.append(self._get_availability(unit))
                if is_editable:
                    url = self.canonicalize_url(
                        '/dashboard?%s') % urllib.urlencode({
                            'action': 'edit_link',
                            'key': unit.unit_id
                        })
                    lines.append(self._get_edit_link(url))
                lines.append('</li>\n')
                continue

            if unit.type == 'U':
                lines.append('<li>')
                lines.append(
                    ('<strong><a href="unit?unit=%s">Unit %s - %s</a>'
                     '</strong>') %
                    (unit.unit_id, unit.index, cgi.escape(unit.title)))
                lines.append(self._get_availability(unit))
                if is_editable:
                    url = self.canonicalize_url(
                        '/dashboard?%s') % urllib.urlencode({
                            'action': 'edit_unit',
                            'key': unit.unit_id
                        })
                    lines.append(self._get_edit_link(url))

                lines.append('<ol>')
                for lesson in course.get_lessons(unit.unit_id):
                    lines.append(
                        '<li><a href="unit?unit=%s&lesson=%s">%s</a>\n' %
                        (unit.unit_id, lesson.lesson_id,
                         cgi.escape(lesson.title)))
                    lines.append(self._get_availability(lesson))
                    if is_editable:
                        url = self.get_action_url('edit_lesson',
                                                  key=lesson.lesson_id)
                        lines.append(self._get_edit_link(url))
                    lines.append('</li>')
                lines.append('</ol>')
                lines.append('</li>\n')
                continue

            raise Exception('Unknown unit type: %s.' % unit.type)

        lines.append('</ul>')
        return ''.join(lines)
    def get_settings(self):
        """Renders course settings view."""

        yaml_actions = []
        basic_setting_actions = []

        # Basic course info.
        course_info = [
            'Course Title: %s' % self.app_context.get_environ()['course'][
                'title'],
            'Context Path: %s' % self.app_context.get_slug(),
            'Datastore Namespace: %s' % self.app_context.get_namespace_name()]

        # Course file system.
        fs = self.app_context.fs.impl
        course_info.append(('File System: %s' % fs.__class__.__name__))
        if fs.__class__ == vfs.LocalReadOnlyFileSystem:
            course_info.append(('Home Folder: %s' % sites.abspath(
                self.app_context.get_home_folder(), '/')))

        # Enable editing if supported.
        if filer.is_editable_fs(self.app_context):
            yaml_actions.append({
                'id': 'edit_course_yaml',
                'caption': 'Advanced Edit',
                'action': self.get_action_url('create_or_edit_settings'),
                'xsrf_token': self.create_xsrf_token(
                    'create_or_edit_settings')})
            yaml_actions.append({
                'id': 'edit_basic_course_settings',
                'caption': 'Edit',
                'action': self.get_action_url('edit_basic_course_settings'),
                'xsrf_token': self.create_xsrf_token(
                    'edit_basic_course_settings')})

        # course.yaml file content.
        yaml_info = []
        yaml_stream = self.app_context.fs.open(
            self.app_context.get_config_filename())
        if yaml_stream:
            yaml_lines = yaml_stream.read().decode('utf-8')
            for line in yaml_lines.split('\n'):
                yaml_info.append(line)
        else:
            yaml_info.append('< empty file >')

        # course_template.yaml file contents
        course_template_info = []
        course_template_stream = open(os.path.join(os.path.dirname(
            __file__), '../../course_template.yaml'), 'r')
        if course_template_stream:
            course_template_lines = course_template_stream.read().decode(
                'utf-8')
            for line in course_template_lines.split('\n'):
                course_template_info.append(line)
        else:
            course_template_info.append('< empty file >')

        # Prepare template values.
        template_values = {
            'page_title': self.format_title('Settings'),
            'page_title_linked': self.format_title('Settings', as_link=True),
            'page_description': messages.SETTINGS_DESCRIPTION,
        }
        template_values['sections'] = [
            {
                'title': 'About the Course',
                'description': messages.ABOUT_THE_COURSE_DESCRIPTION,
                'actions': basic_setting_actions,
                'children': course_info},
            {
                'title': 'Contents of course.yaml file',
                'description': messages.CONTENTS_OF_THE_COURSE_DESCRIPTION,
                'actions': yaml_actions,
                'children': yaml_info},
            {
                'title': 'Contents of course_template.yaml file',
                'description': messages.COURSE_TEMPLATE_DESCRIPTION,
                'children': course_template_info}]

        self.render_page(template_values)