def format_title(self, text):
     """Formats standard title."""
     return safe_dom.NodeList().append(
         safe_dom.Text('Course Builder ')).append(
             safe_dom.Entity('>')).append(
                 safe_dom.Text(' Admin ')).append(
                     safe_dom.Entity('>')).append(
                         safe_dom.Text(' %s' % text))
Exemple #2
0
 def format_title(self, text):
     """Formats standard title."""
     title = self.app_context.get_environ()['course']['title']
     return safe_dom.NodeList().append(safe_dom.Text('U-MOOC ')).append(
         safe_dom.Entity('>')).append(safe_dom.Text(
             ' %s ' % title)).append(safe_dom.Entity('>')).append(
                 safe_dom.Text(' Dashboard ')).append(
                     safe_dom.Entity('>')).append(
                         safe_dom.Text(' %s' % text))
Exemple #3
0
 def format_title(self, text):
     """Formats standard title with or without course picker."""
     ret = safe_dom.NodeList()
     cb_text = 'Course Builder '
     ret.append(safe_dom.Text(cb_text))
     ret.append(safe_dom.Entity('>'))
     ret.append(safe_dom.Text(' %s ' % self.app_context.get_title()))
     ret.append(safe_dom.Entity('>'))
     dashboard_text = ' Dashboard '
     ret.append(safe_dom.Text(dashboard_text))
     ret.append(safe_dom.Entity('>'))
     ret.append(safe_dom.Text(' %s' % text))
     return ret
Exemple #4
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(' ')).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
Exemple #5
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
Exemple #6
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
 def test_should_reject_tampering(self):
     entity = safe_dom.Entity('&nbsp;')
     entity._entity = '<script/>'
     try:
         entity.__str__()
     except AssertionError:
         return
     self.fail('Expected an assert exception')
def assemble_sanitized_message(text, link):
    node_list = safe_dom.NodeList()
    if text:
        node_list.append(safe_dom.Text(text))
        node_list.append(safe_dom.Entity('&nbsp;'))
    if link:
        node_list.append(safe_dom.Element(
            'a', href=link, target='_blank').add_text('Learn more...'))
    return node_list
 def expect_fail(self, test_text):
     try:
         safe_dom.Entity(test_text)
     except AssertionError:
         return
     self.fail('Expected an assert exception')
 def expect_pass(self, test_text):
     entity = safe_dom.Entity(test_text)
     self.assertEqual(test_text, entity.__str__())
Exemple #11
0
    def get_settings(self):
        """Shows configuration properties information page."""
        template_values = {}
        template_values['page_title'] = self.format_title('Settings')
        template_values['page_description'] = messages.SETTINGS_DESCRIPTION

        content = safe_dom.NodeList()
        content.append(
            safe_dom.Element('link',
                             rel='stylesheet',
                             href='/modules/admin/resources/css/admin.css'))
        table = safe_dom.Element('table', className='gcb-config').add_child(
            safe_dom.Element('tr').
            add_child(safe_dom.Element('th').add_text('Name')).add_child(
                safe_dom.Element('th').add_text('Current Value')).add_child(
                    safe_dom.Element('th').add_text('Actions')).add_child(
                        safe_dom.Element('th').add_text('Description')))
        content.append(
            safe_dom.Element('h3').add_text('All Settings')).append(table)

        def get_style_for(value, value_type):
            """Formats CSS style for given value."""
            style = ''
            if not value or value_type in [int, long, bool]:
                style = 'text-align: center;'
            return style

        def get_action_html(caption, args, onclick=None, idName=None):
            """Formats actions <a> link."""
            a = safe_dom.Element('a',
                                 href='%s?%s' %
                                 (self.LINK_URL, urllib.urlencode(args)),
                                 className='gcb-button').add_text(caption)
            if onclick:
                a.add_attribute(onclick=onclick)
            if idName:
                a.add_attribute(id=idName)
            return a

        def get_actions(name, override):
            """Creates actions appropriate to an item."""
            if override:
                return get_action_html('Edit', {
                    'action': 'config_edit',
                    'name': name
                },
                                       idName=name)
            else:
                return safe_dom.Element(
                    'form',
                    action='%s?%s' % (self.LINK_URL,
                                      urllib.urlencode({
                                          'action': 'config_override',
                                          'name': name
                                      })),
                    method='POST').add_child(
                        safe_dom.Element(
                            'input',
                            type='hidden',
                            name='xsrf_token',
                            value=self.create_xsrf_token(
                                'config_override'))).add_child(
                                    safe_dom.Element(
                                        'button',
                                        className='gcb-button',
                                        type='submit',
                                        id=name).add_text('Override'))

        def get_doc_string(item, default_value):
            """Formats an item documentation string for display."""
            doc_string = item.doc_string
            if not doc_string:
                doc_string = 'No documentation available.'
            if isinstance(doc_string, safe_dom.NodeList) or isinstance(
                    doc_string, safe_dom.Node):
                return safe_dom.NodeList().append(doc_string).append(
                    safe_dom.Text(' Default: \'%s\'.' % default_value))
            doc_string = ' %s Default: \'%s\'.' % (doc_string, default_value)
            return safe_dom.Text(doc_string)

        def get_lines(value):
            """Convert \\n line breaks into <br> and escape the lines."""
            escaped_value = safe_dom.NodeList()
            for line in str(value).split('\n'):
                escaped_value.append(safe_dom.Text(line)).append(
                    safe_dom.Element('br'))
            return escaped_value

        # get fresh properties and their overrides
        unused_overrides = config.Registry.get_overrides(force_update=True)
        registered = config.Registry.registered.copy()
        db_overrides = config.Registry.db_overrides.copy()
        names_with_draft = config.Registry.names_with_draft.copy()

        count = 0
        for name in sorted(registered.keys()):
            count += 1
            item = registered[name]
            has_environ_value, unused_environ_value = item.get_environ_value()

            # figure out what kind of override this is
            class_current = ''
            if has_environ_value:
                class_current = 'gcb-env-diff'
            if item.name in db_overrides:
                class_current = 'gcb-db-diff'
            if item.name in names_with_draft:
                class_current = 'gcb-db-draft'

            # figure out default and current value
            default_value = item.default_value
            value = item.value
            if default_value:
                default_value = str(default_value)
            if value:
                value = str(value)

            style_current = get_style_for(value, item.value_type)

            tr = safe_dom.Element('tr')
            table.add_child(tr)

            tr.add_child(
                safe_dom.Element('td', style='white-space: nowrap;').add_text(
                    item.name))

            td_value = safe_dom.Element('td').add_child(get_lines(value))
            if style_current:
                td_value.add_attribute(style=style_current)
            if class_current:
                td_value.add_attribute(className=class_current)
            tr.add_child(td_value)

            tr.add_child(
                safe_dom.Element('td',
                                 style='white-space: nowrap;',
                                 align='center').add_child(
                                     get_actions(
                                         name, name in db_overrides
                                         or name in names_with_draft)))

            tr.add_child(
                safe_dom.Element('td').add_child(
                    get_doc_string(item, default_value)))

        table.add_child(
            safe_dom.Element('tr').add_child(
                safe_dom.Element('td', colspan='4', align='right').add_text(
                    'Total: %s item(s)' % count)))

        content.append(
            safe_dom.Element('p').add_child(
                safe_dom.Element('strong').add_text('Legend')).add_text(':').
            add_text("""
                For each property, the value shown corresponds to, in
                descending order of priority:
            """).add_child(
                safe_dom.Element('span', className='gcb-db-diff').add_child(
                    safe_dom.Entity('&nbsp;')).
                add_text('[ the value override set via this page ]').add_child(
                    safe_dom.Entity('&nbsp;'))).add_text(', ').add_child(
                        safe_dom.Element('span', className='gcb-db-draft').
                        add_child(safe_dom.Entity('&nbsp;')).add_text(
                            '[ the default value with pending value override ]'
                        ).add_child(safe_dom.Entity('&nbsp;'))).add_text(', ').
            add_child(
                safe_dom.Element('span',
                                 className='gcb-env-diff').add_child(
                                     safe_dom.Entity('&nbsp;')).
                add_text('[ the environment value in app.yaml ]').add_child(
                    safe_dom.Entity('&nbsp;'))).add_text(', ').add_text("""
                and the [ default value ] in the Course Builder codebase.
            """))

        template_values['main_content'] = content
        self.render_page(template_values)
Exemple #12
0
def _list_and_format_file_list(
    handler, title, subfolder, tab_name,
    links=False, upload=False, prefix=None, caption_if_empty='< none >',
    edit_url_template=None, merge_local_files=False, sub_title=None,
    all_paths=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 = dashboard_utils.list_files(
            handler, subfolder, merge_local_files=False, all_paths=all_paths)

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

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

        # add actions if available
        if (edit_url_template and
            handler.app_context.fs.impl.is_read_write()):

            li.add_child(safe_dom.Entity('&nbsp;'))
            edit_url = edit_url_template % (
                tab_name, urllib.quote(filename))
            # show [overridden] + edit button if override exists
            if (filename in unmerged_files) or (not merge_local_files):
                li.add_text('[Overridden]').add_child(
                    dashboard_utils.create_edit_button(edit_url))
            # show an [override] link otherwise
            else:
                li.add_child(safe_dom.A(edit_url).add_text('[Override]'))

        count += 1
        items.append(li)

    output = safe_dom.NodeList()

    if handler.app_context.is_editable_fs() and upload:
        output.append(
            safe_dom.Element(
                'a', className='gcb-button gcb-pull-right',
                href='dashboard?%s' % urllib.urlencode(
                    {'action': 'manage_asset',
                     'tab': tab_name,
                     'key': subfolder})
            ).add_text(
                'Upload to ' + subfolder.lstrip('/').rstrip('/'))
        ).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
Exemple #13
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