示例#1
0
 def __init__(self, user, initial=None):
     if user is not None:
         initial = forms.fill_dict(
             initial,
             username=user.username,
             real_name=user.real_name,
             display_name=user._display_name,
             gender_male=user.gender_male,
             birthday=user.birthday,
             height=user.height,
             address=user.address,
             zip=user.zip,
             city=user.city,
             country=user.country,
             email=user.email,
             www=user.www,
             notes=user.notes,
             userpictype=user.userpictype,
         )
     _UserBoundForm.__init__(self, user, initial)
     self.user = user
     self.display_name.choices = [
         (u"$username", user and user.username or _("Username")),
         (u"$real_name", user and user.real_name or _("Realname")),
     ]
     self.gender_male.choices = [(1, _("Male")), (0, _("Female"))]
     self.country.choices = sorted(get_application().locale.territories.iteritems(), key=itemgetter(1))
     self.country.choices.insert(0, ("", ""))
     self.userpictype.choices = [(u"", _("No change")), (u"None", _("No Picture")), (u"Gravatar", _("Gravatar.com"))]
示例#2
0
 def __getitem__(self, name):
     locale = str(get_application().locale)
     if name in self._i18n_values.get(locale, ()):
         return self._i18n_values[locale][name]
     if name in self._values:
         return self._values[name]
     raise KeyError(name)
示例#3
0
def make_config_form():
    """Returns the form for the configuration editor."""
    app = get_application()
    fields = {}
    values = {}
    use_default_label = lazy_gettext(u"Use default value")

    for category in app.cfg.get_detail_list():
        items = {}
        values[category["name"]] = category_values = {}
        for item in category["items"]:
            items[item["name"]] = forms.Mapping(value=item["field"], use_default=forms.BooleanField(use_default_label))
            category_values[item["name"]] = {"value": item["value"], "use_default": False}
        fields[category["name"]] = forms.Mapping(**items)

    class _ConfigForm(forms.Form):
        values = forms.Mapping(**fields)
        cfg = app.cfg

        def apply(self):
            t = self.cfg.edit()
            for category, items in self.data["values"].iteritems():
                for key, d in items.iteritems():
                    if category != "pyClanSphere":
                        key = "%s/%s" % (category, key)
                    if d["use_default"]:
                        t.revert_to_default(key)
                    else:
                        t[key] = d["value"]
            t.commit()

    return _ConfigForm({"values": values})
示例#4
0
 def __init__(self, initial=None):
     self.app = get_application()
     if initial is None:
         initial = {}
         for name in self.fields:
             initial[name] = self.app.cfg[name]
     forms.Form.__init__(self, initial)
示例#5
0
 def __init__(self, initial=None):
     self.app = app = get_application()
     self.active_plugins.choices = sorted(
         [(x.name, x.display_name) for x in app.plugins.values()], key=lambda x: x[1].lower()
     )
     if initial is None:
         initial = dict(active_plugins=[x.name for x in app.plugins.itervalues() if x.active])
     forms.Form.__init__(self, initial)
示例#6
0
def get_engine():
    """Return the active database engine (the database engine of the active
    application).  If no application is enabled this has an undefined behavior.
    If you are not sure if the application is bound to the active thread, use
    :func:`~pyClanSphere.application.get_application` and check it for `None`.
    The database engine is stored on the application object as `database_engine`.
    """
    from pyClanSphere.application import get_application
    return get_application().database_engine
示例#7
0
def gen_slug(text, delim=u'-'):
    """Generates a proper slug for the given text.  It calls either
    `gen_ascii_slug` or `gen_unicode_slug` depending on the application
    configuration.
    """
    from pyClanSphere.application import get_application
    if get_application().cfg['ascii_slugs']:
        return gen_ascii_slug(text, delim)
    return gen_unicode_slug(text, delim)
示例#8
0
 def log(message, module=None):
     try:
         logger = get_application().log
     except AttributeError:
         warn(UnboundLogging('Tried to log %r but no application '
                             'was bound to the calling thread'
                             % message), stacklevel=2)
         return
     if level >= logger.level:
         logger.log(name, message, module, currentframe(1))
示例#9
0
def exception(message=None, module=None, exc_info=None):
    """Logs an error plus the current or given exc info."""
    if exc_info is None:
        exc_info = sys.exc_info()
    try:
        logger = get_application().log
    except AttributeError:
        # no application, write the exception to stderr
        return print_exception(*exc_info)

    if LEVELS['error'] >= logger.level:
        message = (message and message + '\n' or '') + \
                  ''.join(format_exception(*exc_info)) \
                    .decode('utf-8', 'ignore')
        logger.log('error', message, module, currentframe(1))
示例#10
0
def open_url(url, data=None, timeout=None, allow_internal_requests=True, **kwargs):
    """This function parses the URL and opens the connection.  The
    following protocols are supported:

    -   `http`
    -   `https`

    Per default requests to pyClanSphere itself trigger an internal request.  This
    can be disabled by setting `allow_internal_requests` to False.
    """
    app = get_application()
    if timeout is None:
        timeout = app.cfg["default_network_timeout"]
    parts = urlparse.urlsplit(url)
    if app is not None:
        site_url = urlparse.urlsplit(app.cfg["site_url"])
        if (
            allow_internal_requests
            and parts.scheme in ("http", "https")
            and site_url.netloc == parts.netloc
            and parts.path.startswith(site_url.path)
        ):
            path = parts.path[len(site_url.path) :].lstrip("/")
            method = kwargs.pop("method", None)
            if method is None:
                method = data is not None and "POST" or "GET"
            make_response = lambda *a: URLResponse(url, *a)
            return app.perform_subrequest(
                path.decode("utf-8"),
                url_decode(parts.query),
                method,
                data,
                timeout=timeout,
                response_wrapper=make_response,
                **kwargs
            )
    handler = _url_handlers.get(parts.scheme)
    if handler is None:
        raise URLError("unsupported URL schema %r" % parts.scheme)
    if isinstance(data, basestring):
        data = StringIO(data)
    try:
        obj = handler(parts, timeout, **kwargs)
        return obj.open(data)
    except Exception, e:
        if not isinstance(e, NetException):
            e = NetException("%s: %s" % (e.__class__.__name__, str(e)))
        raise e
示例#11
0
def bind_privileges(container, privileges, user=None):
    """Binds the privileges to the container.  The privileges can be a list
    of privilege names, the container must be a set.  This is called for
    the HTTP round-trip in the form validation.
    """
    if not user:
        user = get_request().user
    app = get_application()
    notification_types = app.notification_manager.notification_types
    current_map = dict((x.name, x) for x in container)
    currently_attached = set(x.name for x in container)
    new_privileges = set(privileges)

    # remove out-dated privileges
    for name in currently_attached.difference(new_privileges):
        container.remove(current_map[name])
        # remove any privilege dependencies that are not attached to other
        # privileges
        if current_map[name].dependencies:
            for privilege in current_map[name].dependencies.iter_privileges():
                try:
                    container.remove(privilege)
                except KeyError:
                    # privilege probably already removed
                    pass

        # remove notification subscriptions that required the privilege
        # being deleted.
        for notification in user.notification_subscriptions:
            privs = notification_types[notification.notification_id].privileges
            if current_map[name] in privs.iter_privileges():
                db.session.delete(notification)
                break
            for privilege in current_map[name].dependencies:
                if privilege in privs.iter_privileges():
                    db.session.delete(notification)

    # add new privileges
    for name in new_privileges.difference(currently_attached):
        privilege = app.privileges[name]
        container.add(privilege)
        # add dependable privileges
        if privilege.dependencies:
            for privilege in privilege.dependencies.iter_privileges():
                container.add(privilege)
示例#12
0
 def __init__(self, subject=None, text='', to_addrs=None):
     self.app = app = get_application()
     self.subject = u' '.join(subject.splitlines())
     self.text = text
     from_addr = app.cfg['clan_email']
     if not from_addr:
         from_addr = 'noreply@' + urlparse(app.cfg['site_url']) \
                 [1].split(':')[0]
     self.from_addr = u'%s <%s>' % (
         app.cfg['clan_title'],
         from_addr
     )
     self.to_addrs = []
     if isinstance(to_addrs, basestring):
         self.add_addr(to_addrs)
     else:
         for addr in to_addrs:
             self.add_addr(addr)
示例#13
0
def make_notification_form(user):
    """Creates a notification form."""
    app = get_application()
    fields = {}
    subscriptions = {}

    systems = [(s.key, s.name) for s in sorted(app.notification_manager.systems.values(), key=lambda x: x.name.lower())]

    for obj in app.notification_manager.types(user):
        fields[obj.name] = forms.MultiChoiceField(choices=systems, label=obj.description, widget=forms.CheckboxGroup)

    for ns in user.notification_subscriptions:
        subscriptions.setdefault(ns.notification_id, []).append(ns.notification_system)

    class _NotificationForm(forms.Form):
        subscriptions = forms.Mapping(**fields)
        system_choices = systems

        def apply(self):
            user_subscriptions = {}
            for subscription in user.notification_subscriptions:
                user_subscriptions.setdefault(subscription.notification_id, set()).add(subscription.notification_system)

            for key, active in self["subscriptions"].iteritems():
                currently_set = user_subscriptions.get(key, set())
                active = set(active)

                # remove outdated
                for system in currently_set.difference(active):
                    for subscription in user.notification_subscriptions.filter_by(
                        notification_id=key, notification_system=system
                    ):
                        db.session.delete(subscription)

                # add new
                for system in active.difference(currently_set):
                    user.notification_subscriptions.append(
                        NotificationSubscription(user=user, notification_id=key, notification_system=system)
                    )

    return _NotificationForm({"subscriptions": subscriptions})
示例#14
0
def redirect(url, code=302, allow_external_redirect=False,
             force_scheme_change=False):
    """Return a redirect response.  Like Werkzeug's redirect but this
    one checks for external redirects too.  If a redirect to an external
    target was requested `BadRequest` is raised unless
    `allow_external_redirect` was explicitly set to `True`.

    Leading slashes are ignored which makes it unsuitable to redirect
    to URLs returned from `url_for` and others.  Use `redirect_to`
    to redirect to arbitrary endpoints or `_redirect` to redirect to
    unchecked resources outside the URL root.

    By default the redirect will not change the URL scheme of the current
    request (if there is one).  This behavior can be changed by setting
    the force_scheme_change to False.
    """
    # leading slashes are ignored, if we redirect to "/foo" or "foo"
    # does not matter, in both cases we want to be below our clanwebsite root.
    url = url.lstrip('/')

    if not allow_external_redirect:
        #: check if the url is on the same server
        #: and make it an external one
        try:
            url = check_external_url(get_application(), url)
        except ValueError:
            raise BadRequest()

    # keep the current URL schema if we have an active request if we
    # should.  If https enforcement is set we suppose that the site_url
    # is already set to an https value.
    request = get_request()
    if request and not force_scheme_change and \
       not request.app.cfg['force_https']:
        url = request.environ['wsgi.url_scheme'] + ':' + url.split(':', 1)[1]

    return _redirect(url, code)
示例#15
0
 def privilege(self):
     return get_application().privileges.get(self.name)
示例#16
0
def init_database():
    """ This is for inserting our new table"""
    from pyClanSphere.application import get_application
    engine = get_application().database_engine
    metadata.create_all(engine)
示例#17
0
def _strip_url(url):
    """Strip an URL so that only the path is left."""
    cfg = get_application().cfg
    if url.startswith(cfg['site_url']):
        url = url[len(cfg['site_url']):]
    return url.lstrip('/')
示例#18
0
def make_external_url(path):
    """Return an external url for the given path."""
    return urljoin(get_application().cfg['site_url'], path.lstrip('/'))
示例#19
0
 def __init__(self, group, initial=None):
     forms.Form.__init__(self, initial)
     self.app = get_application()
     self.group = group
示例#20
0
 def as_dict(self):
     result = self._values.copy()
     result.update(self._i18n_values.get(str(get_application().locale), {}))
     return result
示例#21
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))
示例#22
0
 def __init__(self, imaccount, initial=None):
     forms.Form.__init__(self, initial)
     self.app = get_application()
     self.imaccount = imaccount