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))
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))
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
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
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(' ')).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 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(' ')).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(' ') 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(' ')) 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__())
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(' ')). add_text('[ the value override set via this page ]').add_child( safe_dom.Entity(' '))).add_text(', ').add_child( safe_dom.Element('span', className='gcb-db-draft'). add_child(safe_dom.Entity(' ')).add_text( '[ the default value with pending value override ]' ).add_child(safe_dom.Entity(' '))).add_text(', '). add_child( safe_dom.Element('span', className='gcb-env-diff').add_child( safe_dom.Entity(' ')). add_text('[ the environment value in app.yaml ]').add_child( safe_dom.Entity(' '))).add_text(', ').add_text(""" and the [ default value ] in the Course Builder codebase. """)) template_values['main_content'] = content self.render_page(template_values)
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(' ')) 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
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(' ') ).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