def generate_rsd(app): """Generate the RSD definition for this application apis.""" from pyClanSphere.application import url_for document = __import__('xml.dom.minidom', None, None, ['']).Document() root = document.appendChild(document.createElement('rsd')) root.setAttribute('version', '1.0') root.setAttribute('xmlns', 'http://archipelago.phrasewise.com/rsd') service = root.appendChild(document.createElement('service')) attributes = [('engineName', 'pyClanSphere'), ('engineLink', 'http://www.pyclansphere.de/'), ('homePageLink', url_for('core/index', _external=True))] for attr, value in attributes: service.appendChild(document.createElement(attr)) \ .appendChild(document.createTextNode(value)) apis = service.appendChild(document.createElement('apis')) for name, (clan_id, preferred, endpoint) in app.apis.iteritems(): element = apis.appendChild(document.createElement('api')) element.setAttribute('name', name) element.setAttribute('clanID', str(clan_id)) element.setAttribute('preferred', preferred and 'true' or 'false') element.setAttribute('apiLink', url_for(endpoint, _external=True)) return document.toxml('utf-8')
def edit_group(request, group_id=None): """Edit a Group. This is used to create a group as well.""" group = None if group_id is not None: group = Group.query.get(group_id) if group is None: raise NotFound() form = EditGroupForm(group) if request.method == 'POST': if request.form.get('cancel'): return form.redirect('admin/manage_groups') elif request.form.get('delete') and group: return redirect_to('admin/delete_group', group_id=group.id) elif form.validate(request.form): if group is None: group = form.make_group() msg = _(u'Group %s created successfully.') icon = 'add' else: form.save_changes() msg = _(u'Group %s edited successfully.') icon = 'info' db.commit() html_group_detail = u'<a href="%s">%s</a>' % ( escape(url_for(group)), escape(group.name)) flash(msg % html_group_detail, icon) if request.form.get('save'): return form.redirect('admin/manage_groups') return redirect_to('admin/edit_group', group_id=group.id) return render_admin_response('admin/edit_group.html', 'users_groups.groups', form=form.as_widget())
def redirect_back(*args, **kwargs): """Redirect back to the page we are comming from or the URL rule given. """ target = get_redirect_target() if target is None: target = url_for(*args, **kwargs) # call werkzeug's redirect directly and not the redirect() function # from this module because it will strip leading slashes this function # returns and thus generate wrong redirects. return _redirect(target)
def list_documented_plugins(app): """Return a list of all documented plugins.""" plugins = [] for plugin in app.plugins.itervalues(): if plugin.is_documented: plugins.append('<li><a href="%s">%s</a></li>' % ( url_for('admin/help', page='plugins/%s/' % plugin.name), escape(plugin.display_name) )) if not plugins: return u'<ul><li>%s</li></ul>' % _('no documented plugins installed.') return '<ul>%s</ul>' % '\n'.join(plugins)
def edit_user(request, user_id=None): """Edit a user. This can also create a user. If a new user is created the dialog is simplified, some unimportant details are left out. """ user = None if user_id is not None: user = User.query.get(user_id) if user is None: raise NotFound() form = EditUserForm(user) if request.method == 'POST': if request.form.get('cancel'): return form.redirect('admin/manage_users') elif request.form.get('delete') and user: return redirect_to('admin/delete_user', user_id=user.id) elif form.validate(request.form): picfile = request.files.get('picfile') if user is None: user = form.make_user() if picfile and form['userpictype'] == 'Upload': picture.place_file(picfile) msg = _(u'User %s created successfully.') icon = 'add' else: picture = UserPicture(request.user) if picfile: form.save_changes() if form['userpictype'] == 'Upload': picture.place_file(picfile) else: pictype = user.userpictype if not form['userpictype']: form.data['userpictype'] = pictype if form['userpictype'] != pictype: picture.remove() form.save_changes() msg = _(u'User %s edited successfully.') icon = 'info' db.commit() html_user_detail = u'<a href="%s">%s</a>' % ( escape(url_for(user)), escape(user.username) ) flash(msg % html_user_detail, icon) if request.form.get('save'): return form.redirect('admin/manage_users') return redirect_to('admin/edit_user', user_id=user.id) return render_admin_response('admin/edit_user.html', 'users_groups.users', form=form.as_widget())
def render_query_table(queries): """Renders a nice table of all queries in the page.""" total = 0 stylesheet = url_for('core/shared', filename='debug.css') result = [u'<style type="text/css">@import url(%s)</style>' % stylesheet, u'<div class="_database_debug_table"><ul>'] for statement, parameters, start, end, calling_context in queries: total += (end - start) result.append(u'<li><pre>%s</pre><div class="detail"><em>%s</em> | ' u'<strong>took %.3f ms</strong></div></li>' % ( statement, escape(calling_context), (end - start) * 1000 )) result.append(u'<li><strong>%d queries in %.2f ms</strong></ul></div>' % ( len(queries), total * 1000 )) return u'\n'.join(result)
def generate(self, **options): """This method generates the pagination. It accepts some keyword arguments that override the theme pagination settings. These arguments have the same name as the theme setting variables without the `pagination.` prefix. """ from pyClanSphere.application import url_for, get_application, DEFAULT_THEME_SETTINGS if self._skip_theme_defaults: settings = DEFAULT_THEME_SETTINGS else: settings = get_application().theme.settings def _getopt(name): value = options.pop(name, None) if value is not None: return value return settings["pagination." + name] normal = _getopt("normal") active = _getopt("active") commata = _getopt("commata") ellipsis = _getopt("ellipsis") threshold = _getopt("threshold") left_threshold = _getopt("left_threshold") right_threshold = _getopt("right_threshold") prev_link = _getopt("prev_link") next_link = _getopt("next_link") gray_prev_link = _getopt("gray_prev_link") gray_next_link = _getopt("gray_next_link") simple = _getopt("simple") if options: raise TypeError("generate() got an unexpected keyword " "argument %r" % iter(options).next()) was_ellipsis = False result = [] prev = None next = None get_link = lambda x: url_for( self.endpoint, page=x, per_page=self.per_page, post_id=self.post_id, **self.url_args ) if simple: result.append(active % {"url": get_link(self.page), "page": self.page}) if self.page > 1: prev = self.page - 1 if self.page < self.pages: next = self.page + 1 else: for num in xrange(1, self.pages + 1): if num == self.page: was_ellipsis = False if num - 1 == self.page: next = num if num + 1 == self.page: prev = num if num <= left_threshold or num > self.pages - right_threshold or abs(self.page - num) < threshold: if result and result[-1] != ellipsis: result.append(commata) link = get_link(num) template = num == self.page and active or normal result.append(template % {"url": link, "page": num}) elif not was_ellipsis: was_ellipsis = True result.append(ellipsis) if next_link: if next is not None: result.append(u' <a href="%s" class="next">%s</a>' % (get_link(next), _(u"Next »"))) elif gray_next_link: result.append(u' <span class="disabled next">%s</span>' % _(u"Next »")) if prev_link: if prev is not None: result.insert(0, u'<a href="%s" class="prev">%s</a> ' % (get_link(prev), _(u"« Previous"))) elif gray_prev_link: result.insert(0, u'<span class="disabled prev">%s</span> ' % _(u"« Previous")) return Markup(u"".join(result))
def render_admin_response(template_name, _active_menu_item=None, **values): """Works pretty much like the normal `render_response` function but it emits some events to collect navigation items and injects that into the template context. This also gets the flashes messages from the user session and injects them into the template context after the plugins have provided theirs in the `before-admin-response-rendered` event. The second parameter can be the active menu item if wanted. For example ``'options.overview'`` would show the overview button in the options submenu. If the menu is a standalone menu like the dashboard (no child items) you can also just use ``'dashboard'`` to highlight that. """ request = get_request() # set up the core navigation bar navigation_bar = [ ('dashboard', url_for('admin/index'), _(u'Dashboard'), []) ] Access_items = [] # set up the administration menu bar if request.user.has_privilege(CLAN_ADMIN): navigation_bar.extend([ ('users_groups', url_for('admin/manage_users'), _(u'Users and Groups'), [ ('users', url_for('admin/manage_users'), _(u'Users')), ('groups', url_for('admin/manage_groups'), _(u'Groups')) ]) ]) navigation_bar.extend([ ('options', url_for('admin/options'), _(u'Options'), [ ('basic', url_for('admin/basic_options'), _(u'Basic')), ('urls', url_for('admin/urls'), _(u'URLs')), ('theme', url_for('admin/theme'), _(u'Theme')), ('recaptcha', url_for('admin/recaptcha'), _(u'reCAPTCHA')), ('cache', url_for('admin/cache'), _(u'Cache')), ('configuration', url_for('admin/configuration'), _(u'Configuration Editor')) ]) ]) # add the help item to the navigation bar system_items = [('help', url_for('admin/help'), _(u'Help'))] if request.user.has_privilege(CLAN_ADMIN): system_items[0:0] = [ ('information', url_for('admin/information'), _(u'Information')), ('maintenance', url_for('admin/maintenance'), _(u'Maintenance')), ('plugins', url_for('admin/plugins'), _(u'Plugins')), ('log', url_for('admin/log'), _('Log')) ] navigation_bar.append(('system', system_items[0][1], _(u'System'), system_items)) signals.modify_admin_navigation_bar.send(request=request, navbar=navigation_bar) # find out which is the correct menu and submenu bar active_menu = active_submenu = None if _active_menu_item is not None: p = _active_menu_item.split('.') if len(p) == 1: active_menu = p[0] else: active_menu, active_submenu = p for id, url, title, subnavigation_bar in navigation_bar: if id == active_menu: break else: subnavigation_bar = [] # if we are in maintenance_mode the user should know that, no matter # on which page he is. if request.app.cfg['maintenance_mode'] and \ request.user.has_privilege(CLAN_ADMIN): flash(_(u'pyClanSphere is in maintenance mode. Don\'t forget to ' u'<a href="%s">turn it off again</a> once you finish your ' u'changes.') % url_for('admin/maintenance')) # check for broken plugins if we have the plugin guard enabled if request.app.cfg['plugin_guard']: plugins_to_deactivate = [] for plugin in request.app.plugins.itervalues(): if plugin.active and plugin.setup_error is not None: flash(_(u'Could not activate plugin “%(name)s”: %(error)s') % { 'name': plugin.html_display_name, 'error': plugin.setup_error }) plugins_to_deactivate.append(plugin.name) if plugins_to_deactivate: #TODO: it's quite tricky – it needs at least two reloads to # deactivate the plugin (which is in fact a application reload) cfg = request.app.cfg.edit() cfg['plugins'] = u', '.join(sorted(set(request.app.cfg['plugins']) - \ set(plugins_to_deactivate))) cfg.commit() # we change the plugins inline so that the user get somewhat more # information request.app.cfg.touch() signals.before_admin_response_rendered.send(request=request, values=values) # the admin variables is pushed into the context after the event was # sent so that plugins can flash their messages. If we would emit the # event afterwards all flashes messages would appear in the request # after the current request. values['admin'] = { 'navbar': [{ 'id': id, 'url': url, 'title': title, 'active': active_menu == id } for id, url, title, children in navigation_bar], 'ctxnavbar': [{ 'id': id, 'url': url, 'title': title, 'active': active_submenu == id } for id, url, title in subnavigation_bar], 'messages': [{ 'type': type, 'msg': msg } for type, msg in request.session.pop('admin/flashed_messages', [])], 'active_pane': _active_menu_item } return render_response(template_name, **values)
def redirect_to(*args, **kwargs): """Temporarily redirect to an URL rule.""" # call werkzeug's redirect directly and not the redirect() function # from this module because it will strip leading slashes this function # returns and thus generate wrong redirects. return _redirect(url_for(*args, **kwargs))