Esempio n. 1
0
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')
Esempio n. 2
0
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())
Esempio n. 3
0
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)
Esempio n. 4
0
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)
Esempio n. 5
0
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())
Esempio n. 6
0
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)
Esempio n. 7
0
    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))
Esempio n. 8
0
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)
Esempio n. 9
0
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))