コード例 #1
0
ファイル: validators.py プロジェクト: rockyburt/Rezine
 def validator(form, value):
     items = value.split()
     if len(items) > 1:
         raise ValidationError(_(u'You have to enter a valid net address.'))
     items = items[0].split(':')
     if len(items) not in (1, 2):
         raise ValidationError(_(u'You have to enter a valid net address.'))
     elif len(items) == 2 and not items[1].isdigit():
         raise ValidationError(_(u'The port has to be numeric'))
コード例 #2
0
ファイル: validators.py プロジェクト: rockyburt/Rezine
 def validator(form, value):
     items = value.split()
     if len(items) > 1:
         raise ValidationError(_(u'You have to enter a valid net address.'))
     items = items[0].split(':')
     if len(items) not in (1, 2):
         raise ValidationError(_(u'You have to enter a valid net address.'))
     elif len(items) == 2 and not items[1].isdigit():
         raise ValidationError(_(u'The port has to be numeric'))
コード例 #3
0
ファイル: validators.py プロジェクト: rockyburt/Rezine
 def validator(form, value):
     if '<' in value or '>' in value:
         raise ValidationError(_(u'Invalid character, < or > are not allowed.'))
     if value == '/':
         raise ValidationError(_(u'URL prefix must not be a sole slash.'))
     if value:
         if value[:1] != '/':
             raise ValidationError(_(u'URL prefix must start with a slash.'))
         if value[-1:] == '/':
             raise ValidationError(_(u'URL prefix must not end with a slash.'))
コード例 #4
0
ファイル: validators.py プロジェクト: rockyburt/Rezine
 def validator(form, value):
     if '<' in value or '>' in value:
         raise ValidationError(
             _(u'Invalid character, < or > are not allowed.'))
     if value == '/':
         raise ValidationError(_(u'URL prefix must not be a sole slash.'))
     if value:
         if value[:1] != '/':
             raise ValidationError(
                 _(u'URL prefix must start with a slash.'))
         if value[-1:] == '/':
             raise ValidationError(
                 _(u'URL prefix must not end with a slash.'))
コード例 #5
0
ファイル: blog.py プロジェクト: rockyburt/Rezine
def show_tag(req, slug, page=1):
    """Show all posts categoryged with a given tag slug.

    Available template variables:

        `posts`:
            a list of post objects we want to display

        `pagination`:
            a pagination object to render a pagination

        `tag`
            the tag object for this page

    :Template name: ``show_tag.html``
    :URL endpoint: ``blog/show_tag``
    """
    tag = Tag.query.filter_by(slug=slug).first(True)
    per_page = req.app.theme.settings['tag.per_page']
    data = tag.posts.theme_lightweight('tag') \
                    .published().get_list(page=page, endpoint='blog/show_tag',
                                          per_page=per_page,
                                          url_args=dict(slug=slug))

    add_link('alternate', url_for('blog/atom_feed', tag=slug),
             'application/atom+xml',
             _(u'All posts tagged %s') % tag.name)
    return render_response('show_tag.html', tag=tag, **data)
コード例 #6
0
ファイル: blog.py プロジェクト: rockyburt/Rezine
def show_author(req, username, page=1):
    """Show the user profile of an author / editor or administrator.

    Available template variables:

        `posts`:
            a list of post objects this author wrote and are
            visible on this page

        `pagination`:
            a pagination object to render a pagination

        `user`
            the user object for this author

    :Template name: ``show_author.html``
    :URL endpoint: ``blog/show_author``
    """
    user = User.query.filter_by(username=username).first()
    if user is None or not user.is_author:
        raise NotFound()

    per_page = req.app.theme.settings['author.per_page']
    data = user.posts.theme_lightweight('author').published() \
                     .get_list(page=page, per_page=per_page,
                               endpoint='blog/show_author',
                               url_args=dict(username=user.username))

    add_link('alternate', url_for('blog/atom_feed', author=user.username),
             'application/atom+xml',
             _(u'All posts written by %s') % user.display_name)

    return render_response('show_author.html', user=user, **data)
コード例 #7
0
ファイル: validators.py プロジェクト: rockyburt/Rezine
 def validator(form, value):
     if '<' in value or '>' in value or '\\' in value:
         raise ValidationError(_(u'Invalid character, <, > or \\ are not '
         'allowed.'))
     if value:
         if value.startswith('/'):
             raise ValidationError(_(u'URL format cannot start with a slash.'))
         if value.find('//') >= 0:
             raise ValidationError(_(u'URL cannot contain //.'))
         if value.find('/../') >= 0 or value.startswith('../'):
             raise ValidationError(_(u'URL cannot contain a reference to'
             'parent path.'))
         for match in _placeholder_re.finditer(value):
             if match.group(1) not in _slug_parts:
                 raise ValidationError(_(u'Unknown format code %s.') %
                                       match.group())
コード例 #8
0
ファイル: blog.py プロジェクト: rockyburt/Rezine
def show_category(req, slug, page=1):
    """Show all posts categoryged with a given category slug.

    Available template variables:

        `posts`:
            a list of post objects we want to display

        `pagination`:
            a pagination object to render a pagination

        `category`
            the category object for this page

    :Template name: ``show_category.html``
    :URL endpoint: ``blog/show_category``
    """
    category = Category.query.filter_by(slug=slug).first(True)
    per_page = req.app.theme.settings['category.per_page']
    data = category.posts.theme_lightweight('category') \
                   .published().get_list(page=page, per_page=per_page,
                                         endpoint='blog/show_category',
                                         url_args=dict(slug=slug))

    add_link('alternate', url_for('blog/atom_feed', category=slug),
             'application/atom+xml', _(u'All posts in category %s') % category.name)
    return render_response('show_category.html', category=category, **data)
コード例 #9
0
ファイル: blog.py プロジェクト: rockyburt/Rezine
def show_category(req, slug, page=1):
    """Show all posts categoryged with a given category slug.

    Available template variables:

        `posts`:
            a list of post objects we want to display

        `pagination`:
            a pagination object to render a pagination

        `category`
            the category object for this page

    :Template name: ``show_category.html``
    :URL endpoint: ``blog/show_category``
    """
    category = Category.query.filter_by(slug=slug).first(True)
    per_page = req.app.theme.settings['category.per_page']
    data = category.posts.theme_lightweight('category') \
                   .published().get_list(page=page, per_page=per_page,
                                         endpoint='blog/show_category',
                                         url_args=dict(slug=slug))

    add_link('alternate', url_for('blog/atom_feed', category=slug),
             'application/atom+xml',
             _(u'All posts in category %s') % category.name)
    return render_response('show_category.html', category=category, **data)
コード例 #10
0
ファイル: blog.py プロジェクト: rockyburt/Rezine
def show_author(req, username, page=1):
    """Show the user profile of an author / editor or administrator.

    Available template variables:

        `posts`:
            a list of post objects this author wrote and are
            visible on this page

        `pagination`:
            a pagination object to render a pagination

        `user`
            the user object for this author

    :Template name: ``show_author.html``
    :URL endpoint: ``blog/show_author``
    """
    user = User.query.filter_by(username=username).first()
    if user is None or not user.is_author:
        raise NotFound()

    per_page = req.app.theme.settings['author.per_page']
    data = user.posts.theme_lightweight('author').published() \
                     .get_list(page=page, per_page=per_page,
                               endpoint='blog/show_author',
                               url_args=dict(username=user.username))

    add_link('alternate', url_for('blog/atom_feed', author=user.username),
             'application/atom+xml', _(u'All posts written by %s') %
             user.display_name)

    return render_response('show_author.html', user=user, **data)
コード例 #11
0
ファイル: blog.py プロジェクト: rockyburt/Rezine
def archive(req, year=None, month=None, day=None, page=1):
    """Render the monthly archives.

    Available template variables:

        `posts`:
            a list of post objects we want to display

        `pagination`:
            a pagination object to render a pagination

        `year` / `month` / `day`:
            integers or None, useful to entitle the page

    :Template name: ``archive.html``
    :URL endpoint: ``blog/archive``
    """
    if not year:
        return render_response('archive.html', month_list=True,
                               **Post.query.published().for_index()
                                     .get_archive_summary())

    url_args = dict(year=year, month=month, day=day)
    per_page = req.app.theme.settings['archive.per_page']
    data = Post.query.theme_lightweight('archive_overview') \
               .published().for_index().date_filter(year, month, day) \
               .get_list(page=page, endpoint='blog/archive',
                         url_args=url_args, per_page=per_page)

    add_link('alternate', url_for('blog/atom_feed', **url_args),
             'application/atom+xml', _(u'Recent Posts Feed'))

    return render_response('archive.html', year=year, month=month, day=day,
                           date=date(year, month or 1, day or 1),
                           month_list=False, **data)
コード例 #12
0
ファイル: blog.py プロジェクト: rockyburt/Rezine
def show_tag(req, slug, page=1):
    """Show all posts categoryged with a given tag slug.

    Available template variables:

        `posts`:
            a list of post objects we want to display

        `pagination`:
            a pagination object to render a pagination

        `tag`
            the tag object for this page

    :Template name: ``show_tag.html``
    :URL endpoint: ``blog/show_tag``
    """
    tag = Tag.query.filter_by(slug=slug).first(True)
    per_page = req.app.theme.settings['tag.per_page']
    data = tag.posts.theme_lightweight('tag') \
                    .published().get_list(page=page, endpoint='blog/show_tag',
                                          per_page=per_page,
                                          url_args=dict(slug=slug))

    add_link('alternate', url_for('blog/atom_feed', tag=slug),
             'application/atom+xml', _(u'All posts tagged %s') % tag.name)
    return render_response('show_tag.html', tag=tag, **data)
コード例 #13
0
def flash(msg, type='info'):
    """Add a message to the message flash buffer.

    The default message type is "info", other possible values are
    "add", "remove", "error", "ok" and "configure". The message type affects
    the icon and visual appearance.

    The flashes messages appear only in the admin interface!
    """
    assert type in \
        ('info', 'add', 'remove', 'error', 'ok', 'configure', 'warning')
    if type == 'error':
        msg = (u'<strong>%s:</strong> ' % _('Error')) + msg
    if type == 'warning':
        msg = (u'<strong>%s:</strong> ' % _('Warning')) + msg

    local.request.session.setdefault('admin/flashed_messages', []).\
            append((type, msg))
コード例 #14
0
ファイル: config.py プロジェクト: rockyburt/Rezine
 def __init__(self, message_or_exception):
     if isinstance(message_or_exception, basestring):
         message = message_or_exception
         error = None
     else:
         message = _(u'Could not save configuration file: %s') % \
                   str(message_or_exception).decode('utf-8', 'ignore')
         error = message_or_exception
     InternalError.__init__(self, message)
     self.original_exception = error
コード例 #15
0
ファイル: feed.py プロジェクト: rockyburt/Rezine
    def configure(self, request):
        form = FeedImportForm()

        if request.method == 'POST' and form.validate(request.form):
            feed = request.files.get('feed')
            if form.data['download_url']:
                try:
                    feed = open_url(form.data['download_url']).stream
                except Exception, e:
                    log.exception(_('Error downloading feed'))
                    flash(_(u'Error downloading from URL: %s') % e, 'error')
            if not feed:
                return redirect_to('import/feed')

            try:
                blog = parse_feed(feed)
            except Exception, e:
                log.exception(_(u'Error parsing uploaded file'))
                flash(_(u'Error parsing feed: %s') % e, 'error')
コード例 #16
0
ファイル: validators.py プロジェクト: rockyburt/Rezine
 def validator(form, value):
     if '<' in value or '>' in value or '\\' in value:
         raise ValidationError(
             _(u'Invalid character, <, > or \\ are not '
               'allowed.'))
     if value:
         if value.startswith('/'):
             raise ValidationError(
                 _(u'URL format cannot start with a slash.'))
         if value.find('//') >= 0:
             raise ValidationError(_(u'URL cannot contain //.'))
         if value.find('/../') >= 0 or value.startswith('../'):
             raise ValidationError(
                 _(u'URL cannot contain a reference to'
                   'parent path.'))
         for match in _placeholder_re.finditer(value):
             if match.group(1) not in _slug_parts:
                 raise ValidationError(
                     _(u'Unknown format code %s.') % match.group())
コード例 #17
0
 def __init__(self, message_or_exception):
     if isinstance(message_or_exception, basestring):
         message = message_or_exception
         error = None
     else:
         message = _(u'Could not save configuration file: %s') % \
                   str(message_or_exception).decode('utf-8', 'ignore')
         error = message_or_exception
     InternalError.__init__(self, message)
     self.original_exception = error
コード例 #18
0
ファイル: wordpress.py プロジェクト: rockyburt/Rezine
    def configure(self, request):
        form = WordPressImportForm()

        if request.method == "POST" and form.validate(request.form):
            dump = request.files.get("dump")
            if form.data["download_url"]:
                try:
                    dump = open_url(form.data["download_url"]).stream
                except Exception, e:
                    log.exception(_("Error downloading feed"))
                    flash(_(u"Error downloading from URL: %s") % e, "error")
            if not dump:
                return redirect_to("import/wordpress")

            try:
                blog = parse_feed(dump)
            except Exception, e:
                raise
                log.exception(_(u"Error parsing uploaded file"))
                flash(_(u"Error parsing uploaded file: %s") % e, "error")
コード例 #19
0
    def configure(self, request):
        form = WordPressImportForm()

        if request.method == 'POST' and form.validate(request.form):
            dump = request.files.get('dump')
            if form.data['download_url']:
                try:
                    dump = open_url(form.data['download_url']).stream
                except Exception, e:
                    log.exception(_('Error downloading feed'))
                    flash(_(u'Error downloading from URL: %s') % e, 'error')
            if not dump:
                return redirect_to('import/wordpress')

            try:
                blog = parse_feed(dump)
            except Exception, e:
                raise
                log.exception(_(u'Error parsing uploaded file'))
                flash(_(u'Error parsing uploaded file: %s') % e, 'error')
コード例 #20
0
ファイル: feed.py プロジェクト: rockyburt/Rezine
def parse_feed(fd):
    tree = etree.parse(fd).getroot()
    if tree.tag == 'rss':
        parser_class = RSSParser
    elif tree.tag == atom.feed:
        parser_class = AtomParser
    else:
        raise FeedImportError(_('Unknown feed uploaded.'))
    parser = parser_class(tree)
    parser.parse()
    return parser.blog
コード例 #21
0
ファイル: 001_split_tables.py プロジェクト: rockyburt/Rezine
 def process_result_value(self, value, dialect):
     from rezine.utils.zeml import load_parser_data
     try:
         return load_parser_data(value)
     except ValueError: # Parser data invalid. Database corruption?
         from rezine.i18n import _
         from rezine.utils import log
         log.exception(_(u'Error when loading parsed data from database. '
                         u'Maybe the database was manually edited and got '
                         u'corrupted? The system returned an empty value.'))
         return {}
コード例 #22
0
ファイル: __init__.py プロジェクト: rockyburt/Rezine
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)
コード例 #23
0
ファイル: __init__.py プロジェクト: rockyburt/Rezine
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)
コード例 #24
0
 def process_result_value(self, value, dialect):
     from rezine.utils.zeml import load_parser_data
     try:
         return load_parser_data(value)
     except ValueError:  # Parser data invalid. Database corruption?
         from rezine.i18n import _
         from rezine.utils import log
         log.exception(
             _(u'Error when loading parsed data from database. '
               u'Maybe the database was manually edited and got '
               u'corrupted? The system returned an empty value.'))
         return {}
コード例 #25
0
ファイル: blog.py プロジェクト: rockyburt/Rezine
def dispatch_content_type(req):
    """Show the post for a specific content type."""
    slug = req.path[1:]

    # feed for the post
    if slug.endswith('/feed.atom'):
        slug = slug[:-10]
        want_feed = True
    else:
        want_feed = False

    post = Post.query.filter_by(slug=slug).first()

    if post is None:
        # if the post does not exist, check if a post with a trailing slash
        # exists.  If it does, redirect to that post.  This is allows users
        # to emulate folders and to get relative links working.
        if not slug.endswith('/'):
            real_post = Post.query.filter_by(slug=slug + '/').first()
            if real_post is None:
                raise NotFound()
            # if we want the feed, we don't want a redirect
            elif want_feed:
                post = real_post
            else:
                return redirect_to(real_post)
        else:
            raise NotFound()

    # make sure the current user can access that page.
    if not post.can_read():
        raise Forbidden()

    # feed requested?  jump to the feed page
    if want_feed:
        return atom_feed(req, post=post)

    # create the comment form
    form = NewCommentForm(post, req.user)
    if post.comments_enabled or post.comments:
        add_link('alternate', post.comment_feed_url, 'application/atom+xml',
                 _(u'Comments Feed'))

    # now dispatch to the correct view
    handler = req.app.content_type_handlers.get(post.content_type)
    if handler is None:
        log.warn('No handler for the content type %r found.' %
                 post.content_type)
        raise NotFound()

    return handler(req, post, form)
コード例 #26
0
ファイル: blog.py プロジェクト: rockyburt/Rezine
def dispatch_content_type(req):
    """Show the post for a specific content type."""
    slug = req.path[1:]

    # feed for the post
    if slug.endswith('/feed.atom'):
        slug = slug[:-10]
        want_feed = True
    else:
        want_feed = False

    post = Post.query.filter_by(slug=slug).first()

    if post is None:
        # if the post does not exist, check if a post with a trailing slash
        # exists.  If it does, redirect to that post.  This is allows users
        # to emulate folders and to get relative links working.
        if not slug.endswith('/'):
            real_post = Post.query.filter_by(slug=slug + '/').first()
            if real_post is None:
                raise NotFound()
            # if we want the feed, we don't want a redirect
            elif want_feed:
                post = real_post
            else:
                return redirect_to(real_post)
        else:
            raise NotFound()

    # make sure the current user can access that page.
    if not post.can_read():
        raise Forbidden()

    # feed requested?  jump to the feed page
    if want_feed:
        return atom_feed(req, post=post)

    # create the comment form
    form = NewCommentForm(post, req.user)
    if post.comments_enabled or post.comments:
        add_link('alternate', post.comment_feed_url, 'application/atom+xml',
                 _(u'Comments Feed'))

    # now dispatch to the correct view
    handler = req.app.content_type_handlers.get(post.content_type)
    if handler is None:
        log.warn('No handler for the content type %r found.' % post.content_type)
        raise NotFound()

    return handler(req, post, form)
コード例 #27
0
ファイル: pluginsystem.py プロジェクト: rockyburt/Rezine
def make_setup_error(exc_info=None):
    """Create a new SetupError for the last exception and log it."""
    if exc_info is None:
        exc_info = sys.exc_info()

    # log the exception
    log.exception(_(u'Plugin setup error'), 'pluginsystem', exc_info)
    exc_type, exc_value, tb = exc_info

    # if the exception is already a SetupError we only
    # have to return it unchanged.
    if isinstance(exc_value, SetupError):
        return exc_value

    # otherwise create an error message for it and return a new
    # exception.
    error, (filename, line) = summarize_exception(exc_info)
    return SetupError(_(u'Exception happend on setup: '
                        u'%(error)s (%(file)s, line %(line)d)') % {
        'error':    escape(error),
        'file':     filename,
        'line':     line
    })
コード例 #28
0
ファイル: account.py プロジェクト: rockyburt/Rezine
def profile(request):
    form = EditProfileForm(request.user)
    if request.method == 'POST':
        if request.form.get('cancel'):
            return form.redirect('account/index')
        elif request.form.get('delete'):
            return redirect_to('account/delete')
        elif form.validate(request.form):
            form.save_changes()
            db.commit()
            flash(_(u'Your profile was updated successfully.'), 'info')
            return form.redirect('account/index')
    return render_account_response('account/edit_profile.html', 'profile',
                                   form=form.as_widget())
コード例 #29
0
ファイル: pluginsystem.py プロジェクト: rockyburt/Rezine
def make_setup_error(exc_info=None):
    """Create a new SetupError for the last exception and log it."""
    if exc_info is None:
        exc_info = sys.exc_info()

    # log the exception
    log.exception(_(u'Plugin setup error'), 'pluginsystem', exc_info)
    exc_type, exc_value, tb = exc_info

    # if the exception is already a SetupError we only
    # have to return it unchanged.
    if isinstance(exc_value, SetupError):
        return exc_value

    # otherwise create an error message for it and return a new
    # exception.
    error, (filename, line) = summarize_exception(exc_info)
    return SetupError(
        _(u'Exception happend on setup: '
          u'%(error)s (%(file)s, line %(line)d)') % {
              'error': escape(error),
              'file': filename,
              'line': line
          })
コード例 #30
0
class RSTParser(BaseParser):
    """A reStructured Text parser."""

    name = _(u'Rezine-rST')
    settings = dict(file_insertion_enabled=0,
                    raw_enabled=0,
                    output_encoding='unicode',
                    input_encoding='unicode',
                    initial_header_level=4)

    docutils_publish = staticmethod(docutils.core.publish_parts)

    def parse(self, input_data, reason):
        parts = self.docutils_publish(input_data,
                                      writer_name='html',
                                      settings_overrides=self.settings)
        return parse_html(parts['html_body'])
コード例 #31
0
ファイル: account.py プロジェクト: rockyburt/Rezine
def notification_settings(request):
    """Allow the user to change his notification settings."""
    form = make_notification_form(request.user)
    if request.method == 'POST' and form.validate(request.form):
        form.apply()
        db.commit()
        flash(_('Notification settings changed.'), 'configure')
        return form.redirect('account/notification_settings')

    return render_account_response('account/notification_settings.html',
        'notifications', form=form.as_widget(), systems=sorted(
            request.app.notification_manager.systems.values(),
            key=lambda x: x.name.lower()
        ), notification_types=sorted(
            request.app.notification_manager.types(request.user),
            key=lambda x: x.description.lower()
        )
    )
コード例 #32
0
ファイル: blog.py プロジェクト: rockyburt/Rezine
def index(req, page=1):
    """Render the most recent posts.

    Available template variables:

        `posts`:
            a list of post objects we want to display

        `pagination`:
            a pagination object to render a pagination

    :Template name: ``index.html``
    :URL endpoint: ``blog/index``
    """
    data = Post.query.theme_lightweight('index').published() \
               .for_index().get_list(endpoint='blog/index',
                                     page=page)

    add_link('alternate', url_for('blog/atom_feed'), 'application/atom+xml',
             _(u'Recent Posts Feed'))
    return render_response('index.html', **data)
コード例 #33
0
ファイル: blog.py プロジェクト: rockyburt/Rezine
def index(req, page=1):
    """Render the most recent posts.

    Available template variables:

        `posts`:
            a list of post objects we want to display

        `pagination`:
            a pagination object to render a pagination

    :Template name: ``index.html``
    :URL endpoint: ``blog/index``
    """
    data = Post.query.theme_lightweight('index').published() \
               .for_index().get_list(endpoint='blog/index',
                                     page=page)

    add_link('alternate', url_for('blog/atom_feed'), 'application/atom+xml',
             _(u'Recent Posts Feed'))
    return render_response('index.html', **data)
コード例 #34
0
ファイル: blog.py プロジェクト: rockyburt/Rezine
def archive(req, year=None, month=None, day=None, page=1):
    """Render the monthly archives.

    Available template variables:

        `posts`:
            a list of post objects we want to display

        `pagination`:
            a pagination object to render a pagination

        `year` / `month` / `day`:
            integers or None, useful to entitle the page

    :Template name: ``archive.html``
    :URL endpoint: ``blog/archive``
    """
    if not year:
        return render_response(
            'archive.html',
            month_list=True,
            **Post.query.published().for_index().get_archive_summary())

    url_args = dict(year=year, month=month, day=day)
    per_page = req.app.theme.settings['archive.per_page']
    data = Post.query.theme_lightweight('archive_overview') \
               .published().for_index().date_filter(year, month, day) \
               .get_list(page=page, endpoint='blog/archive',
                         url_args=url_args, per_page=per_page)

    add_link('alternate', url_for('blog/atom_feed', **url_args),
             'application/atom+xml', _(u'Recent Posts Feed'))

    return render_response('archive.html',
                           year=year,
                           month=month,
                           day=day,
                           date=date(year, month or 1, day or 1),
                           month_list=False,
                           **data)
コード例 #35
0
def summarize_exception(exc_info):
    def _to_unicode(x):
        try:
            return unicode(x)
        except UnicodeError:
            return str(x).encode('utf-8', 'replace')

    exc_type, exc_value, tb = exc_info
    if isinstance(exc_type, basestring):
        prefix = _to_unicode(exc_type)
    else:
        prefix = _to_unicode(exc_type.__name__)
    message = _to_unicode(exc_value)

    filename = tb.tb_frame.f_globals.get('__file__')
    if filename is None:
        filename = _(u'unkown file')
    else:
        filename = _to_unicode(filename)
        if filename.endswith('.pyc'):
            filename = filename[:-1]

    return u'%s: %s' % (prefix, message), (filename, tb.tb_lineno)
コード例 #36
0
ファイル: validators.py プロジェクト: rockyburt/Rezine
 def validator(form, value):
     if not value.strip():
         raise ValidationError(_(u'The text must not be empty.'))
コード例 #37
0
ファイル: pagination.py プロジェクト: rockyburt/Rezine
    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)
コード例 #38
0
ファイル: blog.py プロジェクト: rockyburt/Rezine
def populate_feed(req, feed, author=None, year=None, month=None, day=None,
              category=None, tag=None, post=None):
    """Renders an atom feed requested.

    :URL endpoint: ``blog/atom_feed``
    """
    # the feed only contains published items
    query = Post.query.lightweight(lazy=('comments',)).published()

    # feed for a category
    if category is not None:
        category = Category.query.filter_by(slug=category).first(True)
        query = query.filter(Post.categories.contains(category))

    # feed for a tag
    if tag is not None:
        tag = Tag.query.filter_by(slug=tag).first(True)
        query = query.filter(Post.tags.contains(tag))

    # feed for an author
    if author is not None:
        author = User.query.filter_by(username=author).first(True)
        query = query.filter(Post.author == author)

    # feed for dates
    if year is not None:
        query = query.for_index().date_filter(year, month, day)

    # if no post slug is given we filter the posts by the cretereons
    # provided and pass them to the feed builder.  This will only return
    # a feed for posts with a content type listed in `index_content_types`
    if post is None:
        for post in query.for_index().order_by(Post.pub_date.desc()) \
                         .limit(15).all():
            alt_title = '%s @ %s' % (post.author.display_name, post.pub_date)
            feed.add_item(post.title or alt_title,
                          url_for(post, _external=True), unicode(post.body),
                          author_name=post.author.display_name,
                          pubdate=post.pub_date, unique_id=post.uid)

    # otherwise we create a feed for all the comments of a post.
    # the function is called this way by `dispatch_content_type`.
    else:
        comment_num = 1
        for comment in post.comments:
            if not comment.visible:
                continue
            uid = build_tag_uri(req.app, comment.pub_date, 'comment',
                                comment.id)
            title = _(u'Comment %(num)d on %(post)s') % {
                'num':  comment_num,
                'post': post.title
            }
            author = {'name': comment.author}
            if comment.www:
                author['uri'] = comment.www
            feed.add_item(title, url_for(comment, _external=True),
                          unicode(comment.body), author_name=author,
                          pubdate=comment.pub_date, unique_id=uid)
            comment_num += 1

    return feed.writeString('utf-8')
コード例 #39
0
ファイル: validators.py プロジェクト: rockyburt/Rezine
 def validator(form, value):
     if len(value) > 200:
         raise ValidationError(_(u'The slug is too long'))
     elif value.startswith('/'):
         raise ValidationError(_(u'The slug must not start with a slash'))
コード例 #40
0
ファイル: feed.py プロジェクト: rockyburt/Rezine
 def __init__(self, tree):
     raise FeedImportError(_('Importing of RSS feeds is currently '
                             'not possible.'))
コード例 #41
0
ファイル: __init__.py プロジェクト: rockyburt/Rezine
def _perform_import(app, blog, d):
    # import models here because they have the same names as our
    # importer objects this module exports
    from rezine.models import User, Tag, Category, Post, Comment
    author_mapping = {}
    tag_mapping = {}
    category_mapping = {}

    def prepare_author(author):
        """Adds an author to the author mapping and returns it."""
        if author.id not in author_mapping:
            author_rewrite = d['authors'][author.id]
            if author_rewrite != '__rezine_create_user':
                user = User.query.get(int(author_rewrite))
            else:
                query = User.query.filter_by(username=author.username)
                user = query.first()
                if user is None:
                    user = User(author.username, None, author.email,
                                author.real_name, author.description,
                                author.www, author.is_author)
                    if author.pw_hash:
                        user.pw_hash = author.pw_hash
                    user.own_privileges.update(author.privileges)
            author_mapping[author.id] = user
        return author_mapping[author.id]

    def prepare_tag(tag):
        """Get a tag for a tag."""
        t = tag_mapping.get(tag.slug)
        if t is not None:
            return t
        t = Tag.query.filter_by(slug=tag.slug).first()
        if t is not None:
            tag_mapping[tag.slug] = t
            return t
        t = Tag.query.filter_by(name=tag.name).first()
        if t is not None:
            tag_mapping[tag.slug] = t
            return t
        t = tag_mapping[tag.id] = Tag(tag.name, tag.slug)
        return t

    def prepare_category(category):
        """Get a category for a category."""
        c = category_mapping.get(category.slug)
        if c is not None:
            return c
        c = Category.query.filter_by(slug=category.slug).first()
        if c is not None:
            category_mapping[category.slug] = c
            return c
        c = Category.query.filter_by(name=category.name).first()
        if c is not None:
            category_mapping[category.slug] = c
            return c
        c = category_mapping[category.id] = Category(category.name,
                                                     category.description,
                                                     category.slug)
        return c

    # start debug output
    yield u'<ul>'

    # update blog configuration if user wants that
    if d['title']:
        app.cfg.change_single('blog_title', blog.title)
        yield u'<li>%s</li>\n' % _('set blog title from dump')
    if d['description']:
        app.cfg.change_single('blog_tagline', blog.description)
        yield u'<li>%s</li>\n' % _('set blog tagline from dump')

    # convert the posts now
    for old_post in blog.posts:
        # in theory that will never happen because there are no
        # checkboxes for already imported posts on the form, but
        # who knows what users manage to do and also skip posts
        # we don't want converted
        if old_post.already_imported or not d['posts'][old_post.id]:
            continue

        slug = old_post.slug
        while Post.query.autoflush(False).filter_by(slug=slug) \
                  .limit(1).count():
            slug = increment_string(slug)
        post = Post(old_post.title,
                    prepare_author(old_post.author),
                    old_post.text,
                    slug,
                    old_post.pub_date,
                    old_post.updated,
                    old_post.comments_enabled,
                    old_post.pings_enabled,
                    parser=old_post.parser,
                    uid=old_post.uid,
                    content_type=old_post.content_type,
                    status=old_post.status,
                    extra=old_post.extra)
        if old_post.parser_data is not None:
            post.parser_data.clear()
            post.parser_data.update(old_post.parser_data)
        yield u'<li><strong>%s</strong>' % escape(post.title)

        for tag in old_post.tags:
            post.tags.append(prepare_tag(tag))
            yield u'.'

        for category in old_post.categories:
            post.categories.append(prepare_category(category))
            yield u'.'

        # now the comments if user wants them.
        if d['comments'][old_post.id]:
            to_create = set(old_post.comments)
            created = {}

            def _create_comment(comment):
                parent = None
                if comment.parent is not None:
                    if comment.parent in created:
                        parent = created[comment.parent]
                    else:
                        parent = _create_comment(comment.parent)
                    to_create.discard(comment.parent)
                if isinstance(comment.author, Author):
                    author = prepare_author(comment.author)
                else:
                    author = comment.author
                rv = Comment(post, author, comment.body, comment.author_email,
                             comment.author_url, parent, comment.pub_date,
                             comment.remote_addr, comment.parser,
                             comment.is_pingback, comment.status)
                if comment.blocked_msg:
                    rv.blocked_msg = comment.blocked_msg
                created[comment] = rv
                return rv

            while to_create:
                _create_comment(to_create.pop())
                yield u'.'

        yield u' <em>%s</em></li>\n' % _('done')

    # send to the database
    yield u'<li>%s' % _('Committing transaction...')
    db.commit()

    # write config if we have
    if d['load_config']:
        yield u'<li>%s' % _('Updating configuration...')
        t = app.cfg.edit()
        for key, value in blog.config.iteritems():
            if key in t and key not in ignored_config_keys:
                t.set_from_string(key, value)
        t.commit()

    yield u' <em>%s</em></li></ul>' % _('done')
コード例 #42
0
ファイル: feed.py プロジェクト: rockyburt/Rezine
                try:
                    feed = open_url(form.data['download_url']).stream
                except Exception, e:
                    log.exception(_('Error downloading feed'))
                    flash(_(u'Error downloading from URL: %s') % e, 'error')
            if not feed:
                return redirect_to('import/feed')

            try:
                blog = parse_feed(feed)
            except Exception, e:
                log.exception(_(u'Error parsing uploaded file'))
                flash(_(u'Error parsing feed: %s') % e, 'error')
            else:
                self.enqueue_dump(blog)
                flash(_(u'Added imported items to queue.'))
                return redirect_to('admin/import')

        return self.render_admin_page('admin/import_feed.html',
                                      form=form.as_widget())


class Extension(object):
    """Extensions are instanciated for each parsing process."""
    feed_types = frozenset()

    def __init__(self, app, parser, root):
        self.app = app
        self.parser = parser
        self.root = root
コード例 #43
0
ファイル: blog.py プロジェクト: rockyburt/Rezine
def populate_feed(req,
                  feed,
                  author=None,
                  year=None,
                  month=None,
                  day=None,
                  category=None,
                  tag=None,
                  post=None):
    """Renders an atom feed requested.

    :URL endpoint: ``blog/atom_feed``
    """
    # the feed only contains published items
    query = Post.query.lightweight(lazy=('comments', )).published()

    # feed for a category
    if category is not None:
        category = Category.query.filter_by(slug=category).first(True)
        query = query.filter(Post.categories.contains(category))

    # feed for a tag
    if tag is not None:
        tag = Tag.query.filter_by(slug=tag).first(True)
        query = query.filter(Post.tags.contains(tag))

    # feed for an author
    if author is not None:
        author = User.query.filter_by(username=author).first(True)
        query = query.filter(Post.author == author)

    # feed for dates
    if year is not None:
        query = query.for_index().date_filter(year, month, day)

    # if no post slug is given we filter the posts by the cretereons
    # provided and pass them to the feed builder.  This will only return
    # a feed for posts with a content type listed in `index_content_types`
    if post is None:
        for post in query.for_index().order_by(Post.pub_date.desc()) \
                         .limit(15).all():
            alt_title = '%s @ %s' % (post.author.display_name, post.pub_date)
            feed.add_item(post.title or alt_title,
                          url_for(post, _external=True),
                          unicode(post.body),
                          author_name=post.author.display_name,
                          pubdate=post.pub_date,
                          unique_id=post.uid)

    # otherwise we create a feed for all the comments of a post.
    # the function is called this way by `dispatch_content_type`.
    else:
        comment_num = 1
        for comment in post.comments:
            if not comment.visible:
                continue
            uid = build_tag_uri(req.app, comment.pub_date, 'comment',
                                comment.id)
            title = _(u'Comment %(num)d on %(post)s') % {
                'num': comment_num,
                'post': post.title
            }
            author = {'name': comment.author}
            if comment.www:
                author['uri'] = comment.www
            feed.add_item(title,
                          url_for(comment, _external=True),
                          unicode(comment.body),
                          author_name=author,
                          pubdate=comment.pub_date,
                          unique_id=uid)
            comment_num += 1

    return feed.writeString('utf-8')
コード例 #44
0
ファイル: pagination.py プロジェクト: rockyburt/Rezine
    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)
コード例 #45
0
ファイル: validators.py プロジェクト: rockyburt/Rezine
 def validator(form, value):
     if not value.strip():
         raise ValidationError(_(u'The text must not be empty.'))
コード例 #46
0
ファイル: account.py プロジェクト: rockyburt/Rezine
def render_account_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-account-response-rendered`
    event.

    The second parameter can be the active menu item if wanted. For example
    ``'account.notifications'`` would show the notifications button in the
    account 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('account/index'), _(u'Dashboard'), []),
        ('profile', url_for('account/profile'), _(u'Profile'), []),
        ('notifications', url_for('account/notification_settings'),
         _(u'Notifications'), [])
    ]

    # add the about items to the navigation bar
    system_items = [
        ('about', url_for('account/about_rezine'), _(u'About'))
    ]
    if request.user.is_admin:
        # Current documentation is addressed for admins
        system_items.append(('help', url_for('account/help'), _(u'Help')))

    navigation_bar.append(('system', system_items[0][1], _(u'System'),
                           system_items))

    #! allow plugins to extend the navigation bar
    emit_event('modify-account-navigation-bar', request, 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 = []


    #! used to flash messages, add links to stylesheets, modify the admin
    #! context etc.
    emit_event('before-account-response-rendered', request, 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['account'] = {
        'user_can_enter_admin_panel':
                        request.user.has_privilege(ENTER_ADMIN_PANEL),
        '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('account/flashed_messages', [])],
        'active_pane': _active_menu_item
    }
    return render_response(template_name, **values)
コード例 #47
0
ファイル: wordpress.py プロジェクト: rockyburt/Rezine
    name = "wordpress"
    title = "WordPress"
    description = lazy_gettext(u'Handles import of WordPress "extended RSS" ' u" feeds.")

    def configure(self, request):
        form = WordPressImportForm()

        if request.method == "POST" and form.validate(request.form):
            dump = request.files.get("dump")
            if form.data["download_url"]:
                try:
                    dump = open_url(form.data["download_url"]).stream
                except Exception, e:
                    log.exception(_("Error downloading feed"))
                    flash(_(u"Error downloading from URL: %s") % e, "error")
            if not dump:
                return redirect_to("import/wordpress")

            try:
                blog = parse_feed(dump)
            except Exception, e:
                raise
                log.exception(_(u"Error parsing uploaded file"))
                flash(_(u"Error parsing uploaded file: %s") % e, "error")
            else:
                self.enqueue_dump(blog)
                flash(_(u"Added imported items to queue."))
                return redirect_to("admin/import")

        return self.render_admin_page("admin/import_wordpress.html", form=form.as_widget())
コード例 #48
0
    description = lazy_gettext(u'Handles import of WordPress "extended RSS" '
                               u' feeds.')

    def configure(self, request):
        form = WordPressImportForm()

        if request.method == 'POST' and form.validate(request.form):
            dump = request.files.get('dump')
            if form.data['download_url']:
                try:
                    dump = open_url(form.data['download_url']).stream
                except Exception, e:
                    log.exception(_('Error downloading feed'))
                    flash(_(u'Error downloading from URL: %s') % e, 'error')
            if not dump:
                return redirect_to('import/wordpress')

            try:
                blog = parse_feed(dump)
            except Exception, e:
                raise
                log.exception(_(u'Error parsing uploaded file'))
                flash(_(u'Error parsing uploaded file: %s') % e, 'error')
            else:
                self.enqueue_dump(blog)
                flash(_(u'Added imported items to queue.'))
                return redirect_to('admin/import')

        return self.render_admin_page('admin/import_wordpress.html',
                                      form=form.as_widget())
コード例 #49
0
ファイル: __init__.py プロジェクト: rockyburt/Rezine
def _perform_import(app, blog, d):
    # import models here because they have the same names as our
    # importer objects this module exports
    from rezine.models import User, Tag, Category, Post, Comment
    author_mapping = {}
    tag_mapping = {}
    category_mapping = {}

    def prepare_author(author):
        """Adds an author to the author mapping and returns it."""
        if author.id not in author_mapping:
            author_rewrite = d['authors'][author.id]
            if author_rewrite != '__rezine_create_user':
                user = User.query.get(int(author_rewrite))
            else:
                query = User.query.filter_by(username=author.username)
                user = query.first()
                if user is None:
                    user = User(author.username, None, author.email,
                                author.real_name, author.description,
                                author.www, author.is_author)
                    if author.pw_hash:
                        user.pw_hash = author.pw_hash
                    user.own_privileges.update(author.privileges)
            author_mapping[author.id] = user
        return author_mapping[author.id]

    def prepare_tag(tag):
        """Get a tag for a tag."""
        t = tag_mapping.get(tag.slug)
        if t is not None:
            return t
        t = Tag.query.filter_by(slug=tag.slug).first()
        if t is not None:
            tag_mapping[tag.slug] = t
            return t
        t = Tag.query.filter_by(name=tag.name).first()
        if t is not None:
            tag_mapping[tag.slug] = t
            return t
        t = tag_mapping[tag.id] = Tag(tag.name, tag.slug)
        return t

    def prepare_category(category):
        """Get a category for a category."""
        c = category_mapping.get(category.slug)
        if c is not None:
            return c
        c = Category.query.filter_by(slug=category.slug).first()
        if c is not None:
            category_mapping[category.slug] = c
            return c
        c = Category.query.filter_by(name=category.name).first()
        if c is not None:
            category_mapping[category.slug] = c
            return c
        c = category_mapping[category.id] = Category(category.name,
                                                     category.description,
                                                     category.slug)
        return c

    # start debug output
    yield u'<ul>'

    # update blog configuration if user wants that
    if d['title']:
        app.cfg.change_single('blog_title', blog.title)
        yield u'<li>%s</li>\n' % _('set blog title from dump')
    if d['description']:
        app.cfg.change_single('blog_tagline', blog.description)
        yield u'<li>%s</li>\n' % _('set blog tagline from dump')

    # convert the posts now
    for old_post in blog.posts:
        # in theory that will never happen because there are no
        # checkboxes for already imported posts on the form, but
        # who knows what users manage to do and also skip posts
        # we don't want converted
        if old_post.already_imported or not d['posts'][old_post.id]:
            continue

        slug = old_post.slug
        while Post.query.autoflush(False).filter_by(slug=slug) \
                  .limit(1).count():
            slug = increment_string(slug)
        post = Post(old_post.title, prepare_author(old_post.author),
                    old_post.text, slug, old_post.pub_date,
                    old_post.updated, old_post.comments_enabled,
                    old_post.pings_enabled, parser=old_post.parser,
                    uid=old_post.uid, content_type=old_post.content_type,
                    status=old_post.status, extra=old_post.extra)
        if old_post.parser_data is not None:
            post.parser_data.clear()
            post.parser_data.update(old_post.parser_data)
        yield u'<li><strong>%s</strong>' % escape(post.title)

        for tag in old_post.tags:
            post.tags.append(prepare_tag(tag))
            yield u'.'

        for category in old_post.categories:
            post.categories.append(prepare_category(category))
            yield u'.'

        # now the comments if user wants them.
        if d['comments'][old_post.id]:
            to_create = set(old_post.comments)
            created = {}

            def _create_comment(comment):
                parent = None
                if comment.parent is not None:
                    if comment.parent in created:
                        parent = created[comment.parent]
                    else:
                        parent = _create_comment(comment.parent)
                    to_create.discard(comment.parent)
                if isinstance(comment.author, Author):
                    author = prepare_author(comment.author)
                else:
                    author = comment.author
                rv = Comment(post, author, comment.body,
                             comment.author_email, comment.author_url, parent,
                             comment.pub_date, comment.remote_addr,
                             comment.parser, comment.is_pingback,
                             comment.status)
                if comment.blocked_msg:
                    rv.blocked_msg = comment.blocked_msg
                created[comment] = rv
                return rv

            while to_create:
                _create_comment(to_create.pop())
                yield u'.'

        yield u' <em>%s</em></li>\n' % _('done')

    # send to the database
    yield u'<li>%s' % _('Committing transaction...')
    db.commit()

    # write config if we have
    if d['load_config']:
        yield u'<li>%s' % _('Updating configuration...')
        t = app.cfg.edit()
        for key, value in blog.config.iteritems():
            if key in t and key not in ignored_config_keys:
                t.set_from_string(key, value)
        t.commit()

    yield u' <em>%s</em></li></ul>' % _('done')
コード例 #50
0
ファイル: validators.py プロジェクト: rockyburt/Rezine
 def validator(form, value):
     if len(value) > 200:
         raise ValidationError(_(u'The slug is too long'))
     elif value.startswith('/'):
         raise ValidationError(_(u'The slug must not start with a slash'))