示例#1
0
    def get_list(self,
                 endpoint=None,
                 page=1,
                 per_page=None,
                 url_args=None,
                 raise_if_empty=True):
        """Return a dict with pagination, the current posts, number of pages,
        total posts and all that stuff for further processing.
        """
        if per_page is None:
            app = get_application()
            per_page = app.cfg['posts_per_page']

        # send the query
        offset = per_page * (page - 1)
        postlist = self.order_by(Post.pub_date.desc()) \
                       .offset(offset).limit(per_page).all()

        # if raising exceptions is wanted, raise it
        if raise_if_empty and (page != 1 and not postlist):
            raise NotFound()

        pagination = Pagination(endpoint, page, per_page, self.count(),
                                url_args)

        return {'pagination': pagination, 'posts': postlist}
示例#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 gen_timestamped_slug(slug, content_type, pub_date=None):
    """Generate a timestamped slug, suitable for use as final URL path."""
    from rezine.application import get_application
    from rezine.i18n import to_blog_timezone
    cfg = get_application().cfg
    if pub_date is None:
        pub_date = datetime.utcnow()
    pub_date = to_blog_timezone(pub_date)

    prefix = cfg['blog_url_prefix'].strip(u'/')
    if prefix:
        prefix += u'/'

    if content_type == 'entry':
        fixed = cfg['fixed_url_date_digits']

        def handle_match(match):
            handler = _slug_parts.get(match.group(1))
            if handler is None:
                return match.group(0)
            return handler(pub_date, slug, fixed)

        full_slug = prefix + _placeholder_re.sub(handle_match,
                                                 cfg['post_url_format'])
    else:
        full_slug = u'%s%s' % (prefix, slug)
    return full_slug
示例#4
0
    def __init__(self, post, author, text, email=None, www=None, parent=None,
                 pub_date=None, submitter_ip='0.0.0.0', parser=None,
                 is_pingback=False, status=COMMENT_MODERATED):
        self.post = post
        if isinstance(author, basestring):
            self.user = None
            self._author = author
            self._email = email
            self._www = www
        else:
            assert email is www is None, \
                'email and www can only be provided if the author is ' \
                'an anonymous user'
            self.user = author

        if parser is None:
            parser = get_application().cfg['comment_parser']
        self.parser = parser
        self.text = text or ''
        self.parent = parent
        if pub_date is None:
            pub_date = datetime.utcnow()
        self.pub_date = pub_date
        self.blocked_msg = None
        self.submitter_ip = submitter_ip
        self.is_pingback = is_pingback
        self.status = status
示例#5
0
 def comments_closed(self):
     """True if commenting is no longer possible."""
     app = get_application()
     open_for = app.cfg['comments_open_for']
     if open_for == 0:
         return False
     return self.pub_date + timedelta(days=open_for) < datetime.utcnow()
示例#6
0
文件: text.py 项目: rockyburt/Rezine
def gen_timestamped_slug(slug, content_type, pub_date=None):
    """Generate a timestamped slug, suitable for use as final URL path."""
    from rezine.application import get_application
    from rezine.i18n import to_blog_timezone
    cfg = get_application().cfg
    if pub_date is None:
        pub_date = datetime.utcnow()
    pub_date = to_blog_timezone(pub_date)

    prefix = cfg['blog_url_prefix'].strip(u'/')
    if prefix:
        prefix += u'/'

    if content_type == 'entry':
        fixed = cfg['fixed_url_date_digits']
        def handle_match(match):
            handler = _slug_parts.get(match.group(1))
            if handler is None:
                return match.group(0)
            return handler(pub_date, slug, fixed)

        full_slug = prefix + _placeholder_re.sub(
            handle_match, cfg['post_url_format'])
    else:
        full_slug = u'%s%s' % (prefix, slug)
    return full_slug
示例#7
0
 def comments_closed(self):
     """True if commenting is no longer possible."""
     app = get_application()
     open_for = app.cfg['comments_open_for']
     if open_for == 0:
         return False
     return self.pub_date + timedelta(days=open_for) < datetime.utcnow()
示例#8
0
    def __init__(self, title, author, text, slug=None, pub_date=None,
                 last_update=None, comments_enabled=True,
                 pings_enabled=True, status=STATUS_PUBLISHED,
                 parser=None, uid=None, content_type='entry', extra=None):
        app = get_application()
        self.content_type = content_type
        self.title = title
        self.author = author
        if parser is None:
            parser = app.cfg['default_parser']

        self.parser = parser
        self.text = text or u''
        if extra:
            self.extra = dict(extra)
        else:
            self.extra = {}

        self.comments_enabled = comments_enabled
        self.pings_enabled = pings_enabled
        self.status = status

        # set times now, they depend on status being set
        self.touch_times(pub_date)
        if last_update is not None:
            self.last_update = last_update

        # now bind the slug for which we need the times set.
        self.bind_slug(slug)

        # generate a UID if none is given
        if uid is None:
            uid = build_tag_uri(app, self.pub_date, content_type, self.slug)
        self.uid = uid
示例#9
0
    def get_list(self, endpoint=None, page=1, per_page=None,
                 url_args=None, raise_if_empty=True):
        """Return a dict with pagination, the current posts, number of pages,
        total posts and all that stuff for further processing.
        """
        if per_page is None:
            app = get_application()
            per_page = app.cfg['posts_per_page']

        # send the query
        offset = per_page * (page - 1)
        postlist = self.order_by(Post.pub_date.desc()) \
                       .offset(offset).limit(per_page).all()

        # if raising exceptions is wanted, raise it
        if raise_if_empty and (page != 1 and not postlist):
            raise NotFound()

        pagination = Pagination(endpoint, page, per_page,
                                self.count(), url_args)

        return {
            'pagination':       pagination,
            'posts':            postlist
        }
示例#10
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)
示例#11
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 rezine.application import get_application
    if get_application().cfg['ascii_slugs']:
        return gen_ascii_slug(text, delim)
    return gen_unicode_slug(text, delim)
示例#12
0
文件: text.py 项目: rockyburt/Rezine
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 rezine.application import get_application
    if get_application().cfg['ascii_slugs']:
        return gen_ascii_slug(text, delim)
    return gen_unicode_slug(text, delim)
示例#13
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:`~rezine.application.get_application` and check it for `None`.
    The database engine is stored on the application object as `database_engine`.
    """
    from rezine.application import get_application
    return get_application().database_engine
示例#14
0
 def parser_missing(self):
     """If the parser for this post is not available this property will
     be `True`.  If such as post is edited the text area is grayed out
     and tells the user to reinstall the plugin that provides that
     parser.  Because it doesn't know the name of the plugin, the
     preferred was is telling it the parser which is available using
     the `parser` property.
     """
     app = get_application()
     return self.parser not in app.parsers
示例#15
0
文件: log.py 项目: rockyburt/Rezine
 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))
示例#16
0
文件: log.py 项目: rockyburt/Rezine
 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))
示例#17
0
 def parser_missing(self):
     """If the parser for this post is not available this property will
     be `True`.  If such as post is edited the text area is grayed out
     and tells the user to reinstall the plugin that provides that
     parser.  Because it doesn't know the name of the plugin, the
     preferred was is telling it the parser which is available using
     the `parser` property.
     """
     app = get_application()
     return self.parser not in app.parsers
示例#18
0
    def theme_lightweight(self, key):
        """A query for lightweight settings based on the theme.  For example
        to use the lightweight settings for the author overview page you can
        use this query::

            Post.query.theme_lightweight('author_overview')
        """
        theme_settings = get_application().theme.settings
        deferred = theme_settings.get('sql.%s.deferred' % key)
        lazy = theme_settings.get('sql.%s.lazy' % key)
        return self.lightweight(deferred, lazy)
示例#19
0
文件: feed.py 项目: rockyburt/Rezine
 def __init__(self, tree):
     self.app = get_application()
     self.tree = tree
     self.tags = []
     self.categories = []
     self.authors = []
     self.posts = []
     self.blog = None
     self.extensions = [extension(self.app, self, tree)
                        for extension in self.app.feed_importer_extensions
                        if self.feed_type in extension.feed_types]
示例#20
0
    def theme_lightweight(self, key):
        """A query for lightweight settings based on the theme.  For example
        to use the lightweight settings for the author overview page you can
        use this query::

            Post.query.theme_lightweight('author_overview')
        """
        theme_settings = get_application().theme.settings
        deferred = theme_settings.get('sql.%s.deferred' % key)
        lazy = theme_settings.get('sql.%s.lazy' % key)
        return self.lightweight(deferred, lazy)
示例#21
0
文件: log.py 项目: rockyburt/Rezine
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))
示例#22
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['blog_email']
     if not from_addr:
         from_addr = 'noreply@' + urlparse(app.cfg['blog_url']) \
                 [1].split(':')[0]
     self.from_addr = u'%s <%s>' % (app.cfg['blog_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)
示例#23
0
文件: log.py 项目: rockyburt/Rezine
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))
示例#24
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 Rezine 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:
        blog_url = urlparse.urlsplit(app.cfg['blog_url'])
        if allow_internal_requests and \
           parts.scheme in ('http', 'https') and \
           blog_url.netloc == parts.netloc and \
           parts.path.startswith(blog_url.path):
            path = parts.path[len(blog_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
示例#25
0
 def requires_moderation(self):
     """This is `True` if the comment requires moderation with the
     current moderation settings.  This does not check if the comment
     is already moderated.
     """
     if not self.anonymous:
         return False
     moderate = get_application().cfg['moderate_comments']
     if moderate == MODERATE_ALL:
         return True
     elif moderate == MODERATE_NONE:
         return False
     return db.execute(
         comments.select(
             (comments.c.author == self._author)
             & (comments.c.email == self._email)
             & (comments.c.status == COMMENT_MODERATED))).fetchone() is None
示例#26
0
 def requires_moderation(self):
     """This is `True` if the comment requires moderation with the
     current moderation settings.  This does not check if the comment
     is already moderated.
     """
     if not self.anonymous:
         return False
     moderate = get_application().cfg['moderate_comments']
     if moderate == MODERATE_ALL:
         return True
     elif moderate == MODERATE_NONE:
         return False
     return db.execute(comments.select(
         (comments.c.author == self._author) &
         (comments.c.email == self._email) &
         (comments.c.status == COMMENT_MODERATED)
     )).fetchone() is None
示例#27
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)
示例#28
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)
示例#29
0
    def __init__(self,
                 title,
                 author,
                 text,
                 slug=None,
                 pub_date=None,
                 last_update=None,
                 comments_enabled=True,
                 pings_enabled=True,
                 status=STATUS_PUBLISHED,
                 parser=None,
                 uid=None,
                 content_type='entry',
                 extra=None):
        app = get_application()
        self.content_type = content_type
        self.title = title
        self.author = author
        if parser is None:
            parser = app.cfg['default_parser']

        self.parser = parser
        self.text = text or u''
        if extra:
            self.extra = dict(extra)
        else:
            self.extra = {}

        self.comments_enabled = comments_enabled
        self.pings_enabled = pings_enabled
        self.status = status

        # set times now, they depend on status being set
        self.touch_times(pub_date)
        if last_update is not None:
            self.last_update = last_update

        # now bind the slug for which we need the times set.
        self.bind_slug(slug)

        # generate a UID if none is given
        if uid is None:
            uid = build_tag_uri(app, self.pub_date, content_type, self.slug)
        self.uid = uid
示例#30
0
文件: net.py 项目: rockyburt/Rezine
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 Rezine 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:
        blog_url = urlparse.urlsplit(app.cfg['blog_url'])
        if allow_internal_requests and \
           parts.scheme in ('http', 'https') and \
           blog_url.netloc == parts.netloc and \
           parts.path.startswith(blog_url.path):
            path = parts.path[len(blog_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
示例#31
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 blog 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 blog_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)
示例#32
0
文件: http.py 项目: rockyburt/Rezine
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 blog 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 blog_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)
示例#33
0
def parse(input_data, parser=None, reason='unknown'):
    """Generate a doc tree out of the data provided.  If we are not in unbound
    mode the `process-doc-tree` event is sent so that plugins can modify
    the tree in place. The reason is useful for plugins to find out if they
    want to render it or now. For example a normal blog post would have the
    reason 'post', a comment 'comment', an isolated page from a plugin maybe
    'page' etc.
    """
    input_data = u'\n'.join(input_data.splitlines())
    app = get_application()
    if parser is None:
        try:
            parser = app.parsers[app.cfg['default_parser']]
        except KeyError:
            # the plugin that provided the default parser is not
            # longer available.  reset the config value to the builtin
            # parser and parse afterwards.
            t = app.cfg.edit()
            t.revert_to_default('default_parser')
            t.commit()
            parser = app.parsers[app.cfg['default_parser']]
    else:
        try:
            parser = app.parsers[parser]
        except KeyError:
            raise ValueError('parser %r does not exist' % (parser,))

    tree = parser.parse(input_data, reason)

    #! allow plugins to alter the doctree.
    for callback in iter_listeners('process-doc-tree'):
        item = callback(tree, input_data, reason)
        if item is not None:
            tree = item

    return tree
示例#34
0
def parse(input_data, parser=None, reason="unknown"):
    """Generate a doc tree out of the data provided.  If we are not in unbound
    mode the `process-doc-tree` event is sent so that plugins can modify
    the tree in place. The reason is useful for plugins to find out if they
    want to render it or now. For example a normal blog post would have the
    reason 'post', a comment 'comment', an isolated page from a plugin maybe
    'page' etc.
    """
    input_data = u"\n".join(input_data.splitlines())
    app = get_application()
    if parser is None:
        try:
            parser = app.parsers[app.cfg["default_parser"]]
        except KeyError:
            # the plugin that provided the default parser is not
            # longer available.  reset the config value to the builtin
            # parser and parse afterwards.
            t = app.cfg.edit()
            t.revert_to_default("default_parser")
            t.commit()
            parser = app.parsers[app.cfg["default_parser"]]
    else:
        try:
            parser = app.parsers[parser]
        except KeyError:
            raise ValueError("parser %r does not exist" % (parser,))

    tree = parser.parse(input_data, reason)

    #! allow plugins to alter the doctree.
    for callback in iter_listeners("process-doc-tree"):
        item = callback(tree, input_data, reason)
        if item is not None:
            tree = item

    return tree
示例#35
0
    def __init__(self,
                 post,
                 author,
                 text,
                 email=None,
                 www=None,
                 parent=None,
                 pub_date=None,
                 submitter_ip='0.0.0.0',
                 parser=None,
                 is_pingback=False,
                 status=COMMENT_MODERATED):
        self.post = post
        if isinstance(author, basestring):
            self.user = None
            self._author = author
            self._email = email
            self._www = www
        else:
            assert email is www is None, \
                'email and www can only be provided if the author is ' \
                'an anonymous user'
            self.user = author

        if parser is None:
            parser = get_application().cfg['comment_parser']
        self.parser = parser
        self.text = text or ''
        self.parent = parent
        if pub_date is None:
            pub_date = datetime.utcnow()
        self.pub_date = pub_date
        self.blocked_msg = None
        self.submitter_ip = submitter_ip
        self.is_pingback = is_pingback
        self.status = status
示例#36
0
def send_notification(type, message, user=Ellipsis):
    """Convenience function.  Get the application object and deliver the
    notification to it's NotificationManager.

    The message must be a valid ZEML formatted message.  The following
    top-level elements are available for marking up the message:

    title
        The title of the notification.  Some systems may only transmit this
        part of the message.

    summary
        An optional quick summary.  If the text is short enough it can be
        omitted and the system will try to transmit the longtext in that
        case.  The upper limit for the summary should be around 100 chars.

    details
        If given this may either contain a paragraph with textual information
        or an ordered or unordered list of text or links.  The general markup
        rules apply.

    longtext
        The full text of this notification.  May contain some formattings.

    actions
        If given this may contain an unordered list of action links.  These
        links may be transmitted together with the notification.

    Additionally if there is an associated page with the notification,
    somewhere should be a link element with a "selflink" class.  This can be
    embedded in the longtext or actions (but any other element too).

    Example markup::

        <title>New comment on "Foo bar baz"</title>
        <summary>Mr. Miracle wrote a new comment: "This is awesome."</summary>
        <details>
          <ul>
            <li><a href="http://miracle.invalid/">Mr. Miracle</a>
            <li><a href="mailto:[email protected]">E-Mail</a>
          </ul>
        </details>
        <longtext>
          <p>This is awesome.  Keep it up!
          <p>Love your work
        </longtext>
        <actions>
          <ul>
            <li><a href="http://.../link" class="selflink">all comments</a>
            <li><a href="http://.../?action=delete">delete it</a>
            <li><a href="http://.../?action=approve">approve it</a>
          </ul>
        </actions>

    Example plaintext rendering (e-mail)::

        Subject: New comment on "Foo bar baz"

        Mr. Miracle             http://miracle.invalid/
        E-Mail                  [email protected]

        > This is awesome.   Keep it up!
        > Love your work.

        Actions:
          - delete it           http://.../?action=delete
          - approve it          http://.../?action=approve

    Example IM notification rendering (jabber)::

        New comment on "Foo bar baz."  Mr. Miracle wrote anew comment:
        "This is awesome".  http://.../link
    """
    get_application().notification_manager.send(
        Notification(type, message, user)
    )
示例#37
0
 def as_dict(self):
     result = self._values.copy()
     result.update(self._i18n_values.get(str(get_application().locale), {}))
     return result
示例#38
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 rezine.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 u''.join(result)
示例#39
0
def _strip_url(url):
    """Strip an URL so that only the path is left."""
    cfg = get_application().cfg
    if url.startswith(cfg['blog_url']):
        url = url[len(cfg['blog_url']):]
    return url.lstrip('/')
示例#40
0
 def as_dict(self):
     result = self._values.copy()
     result.update(self._i18n_values.get(str(get_application().locale), {}))
     return result
示例#41
0
 def privilege(self):
     return get_application().privileges.get(self.name)
示例#42
0
 def _privileges(self):
     return get_application().content_type_privileges[self.content_type]
示例#43
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 rezine.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 u''.join(result)
示例#44
0
 def for_index(self):
     """Return all the types for the index."""
     types = get_application().cfg['index_content_types']
     if len(types) == 1:
         return self.filter_by(content_type=types[0])
     return self.filter(Post.content_type.in_(types))
示例#45
0
 def privilege(self):
     return get_application().privileges.get(self.name)
示例#46
0
def make_external_url(path):
    """Return an external url for the given path."""
    return urljoin(get_application().cfg['blog_url'], path.lstrip('/'))
示例#47
0
 def for_index(self):
     """Return all the types for the index."""
     types = get_application().cfg['index_content_types']
     if len(types) == 1:
         return self.filter_by(content_type=types[0])
     return self.filter(Post.content_type.in_(types))
示例#48
0
文件: http.py 项目: rockyburt/Rezine
def make_external_url(path):
    """Return an external url for the given path."""
    return urljoin(get_application().cfg['blog_url'], path.lstrip('/'))
示例#49
0
def send_notification(type, message, user=Ellipsis):
    """Convenience function.  Get the application object and deliver the
    notification to it's NotificationManager.

    The message must be a valid ZEML formatted message.  The following
    top-level elements are available for marking up the message:

    title
        The title of the notification.  Some systems may only transmit this
        part of the message.

    summary
        An optional quick summary.  If the text is short enough it can be
        omitted and the system will try to transmit the longtext in that
        case.  The upper limit for the summary should be around 100 chars.

    details
        If given this may either contain a paragraph with textual information
        or an ordered or unordered list of text or links.  The general markup
        rules apply.

    longtext
        The full text of this notification.  May contain some formattings.

    actions
        If given this may contain an unordered list of action links.  These
        links may be transmitted together with the notification.

    Additionally if there is an associated page with the notification,
    somewhere should be a link element with a "selflink" class.  This can be
    embedded in the longtext or actions (but any other element too).

    Example markup::

        <title>New comment on "Foo bar baz"</title>
        <summary>Mr. Miracle wrote a new comment: "This is awesome."</summary>
        <details>
          <ul>
            <li><a href="http://miracle.invalid/">Mr. Miracle</a>
            <li><a href="mailto:[email protected]">E-Mail</a>
          </ul>
        </details>
        <longtext>
          <p>This is awesome.  Keep it up!
          <p>Love your work
        </longtext>
        <actions>
          <ul>
            <li><a href="http://.../link" class="selflink">all comments</a>
            <li><a href="http://.../?action=delete">delete it</a>
            <li><a href="http://.../?action=approve">approve it</a>
          </ul>
        </actions>

    Example plaintext rendering (e-mail)::

        Subject: New comment on "Foo bar baz"

        Mr. Miracle             http://miracle.invalid/
        E-Mail                  [email protected]

        > This is awesome.   Keep it up!
        > Love your work.

        Actions:
          - delete it           http://.../?action=delete
          - approve it          http://.../?action=approve

    Example IM notification rendering (jabber)::

        New comment on "Foo bar baz."  Mr. Miracle wrote anew comment:
        "This is awesome".  http://.../link
    """
    get_application().notification_manager.send(
        Notification(type, message, user))
示例#50
0
def _strip_url(url):
    """Strip an URL so that only the path is left."""
    cfg = get_application().cfg
    if url.startswith(cfg['blog_url']):
        url = url[len(cfg['blog_url']):]
    return url.lstrip('/')
示例#51
0
 def _privileges(self):
     return get_application().content_type_privileges[self.content_type]