Esempio n. 1
0
    def _generate(self):
        now = datetime.utcnow()
        posts = iter(Post.query.order_by(Post.last_update.desc()))
        try:
            first_post = posts.next()
            last_update = first_post.last_update
            posts = chain((first_post,), posts)
        except StopIteration:
            first_post = None
            last_update = now

        feed_id = build_tag_uri(self.app, last_update, 'zxa_export', 'full')
        yield (XML_PREAMBLE % {
            'version':      escape(rezine.__version__),
            'title':        escape(self.app.cfg['blog_title']),
            'subtitle':     escape(self.app.cfg['blog_tagline']),
            'atom_ns':      ATOM_NS,
            'rezine_ns':      ZINE_NS,
            'id':           escape(feed_id),
            'blog_url':     escape(self.app.cfg['blog_url']),
            'updated':      format_iso8601(last_update),
            'language':     self.app.cfg['language']
        }).encode('utf-8')

        def dump_node(node):
            return etree.tostring(node, encoding='utf-8')

        for participant in self.participants:
            participant.before_dump()

        # dump configuration
        cfg = self.z('configuration')
        for key, value in self.app.cfg.export():
            self.z('item', key=key, text=value, parent=cfg)
        yield dump_node(cfg)

        # allow plugins to dump trees
        for participant in self.participants:
            rv = participant.dump_data()
            if rv is not None:
                yield dump_node(rv)

        # look up all the users and add them as dependencies if they
        # have written a comment or created a post.
        for user in User.query.all():
            if user.posts.count() > 0 or user.comments.count() > 0:
                self._register_user(user)

        # dump all the posts
        for post in posts:
            yield dump_node(self._dump_post(post))

        # if we have dependencies (very likely) dump them now
        if self._dependencies:
            yield '<rezine:dependencies>'
            for node in self._dependencies.itervalues():
                yield dump_node(node)
            yield '</rezine:dependencies>'

        yield XML_EPILOG.encode('utf-8')
Esempio n. 2
0
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')
Esempio n. 3
0
 def reescape_escaped_content(match):
     before, content, after = match.groups()
     return before + escape(content) + after
Esempio n. 4
0
 def escape_if_good_idea(match):
     before, content, after = match.groups()
     if not content.lstrip().startswith("<![CDATA["):
         content = escape(content)
     return before + content + after
Esempio n. 5
0
 def reescape_escaped_content(match):
     before, content, after = match.groups()
     return before + escape(content) + after
Esempio n. 6
0
 def escape_if_good_idea(match):
     before, content, after = match.groups()
     if not content.lstrip().startswith('<![CDATA['):
         content = escape(content)
     return before + content + after
Esempio n. 7
0
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')