Example #1
0
def delete_category(blog_id, category_id, confirm='N'):
    user = auth.is_logged_in(request)
    blog = Blog.load(blog_id)
    permission = auth.is_blog_admin(user, blog)

    category = Category.load(category_id, blog_id=blog.id)
    auth.check_category_editing_lock(blog)

    tags = template_tags(blog=blog, user=user)

    from core.utils import Status

    if request.forms.getunicode('confirm') == user.logout_nonce:
        message = 'Category {} successfully deleted'.format(category.for_log)
        url = '{}/blog/{}/categories'.format(BASE_URL, blog.id)
        action = 'Return to the category listing'

        reparent_categories = Category.update(
            parent_category=category.parent_category).where(
                Category.parent_category == category)
        reparent_categories.execute()

        delete_category = PageCategory.delete().where(
            PageCategory.category == category.id)
        delete_category.execute()

        category.delete_instance()

        tags.status = Status(type='success',
                             message=message,
                             action=action,
                             url=url,
                             close=False)

    else:
        message = (
            'You are about to delete category <b>{}</b> from blog <b>{}</b>.'.
            format(category.for_display, blog.for_display))

        yes = {
            'label': 'Yes, delete this category',
            'id': 'delete',
            'name': 'confirm',
            'value': user.logout_nonce
        }
        no = {
            'label': 'No, return to category properties',
            'url': '{}/blog/{}/category/{}'.format(BASE_URL, blog.id,
                                                   category.id)
        }

        tags.status = Status(message=message,
                             type='warning',
                             close=False,
                             yes=yes,
                             no=no)

    tags.category = category

    return report(tags, 'blog_delete_category', category)
Example #2
0
def blog_pages_in_category(blog_id, category_id):

    user = auth.is_logged_in(request)
    blog = Blog.load(blog_id)
    permission = auth.is_blog_editor(user, blog)
    errormsg = auth.check_category_editing_lock(blog, True)

    from core.models import Category
    category = Category.load(category_id, blog_id=blog.id)

    return listing(request, category, category.pages,
                   'blog', 'blog_pages_in_category',
                   user=user,
                   errormsg=errormsg,
                   search_ui='blog_pages_in_category',
                   search_context=blog_pages_in_category_search_results,
                   tags_data={'blog':blog}
                   )
Example #3
0
def blog_pages_in_category(blog_id, category_id):

    user = auth.is_logged_in(request)
    blog = Blog.load(blog_id)
    permission = auth.is_blog_editor(user, blog)
    errormsg = auth.check_category_editing_lock(blog, True)

    from core.models import Category
    category = Category.load(category_id, blog_id=blog.id)

    return listing(request,
                   category,
                   category.pages,
                   'blog',
                   'blog_pages_in_category',
                   user=user,
                   errormsg=errormsg,
                   search_ui='blog_pages_in_category',
                   search_context=blog_pages_in_category_search_results,
                   tags_data={'blog': blog})
Example #4
0
def template_preview_core(template_id):
    '''
    UI for generating a preview of a given template
    '''
    from core.models import Page, FileInfo, page_status
    from core.cms import fileinfo
    from core.cms import invalidate_cache

    invalidate_cache()

    template = Template.load(template_id)

    # TODO: only rebuild mappings if the dirty bit is set

    if template.template_type == template_type.index:

        fi = template.default_mapping.fileinfos
        test_preview_mapping(fi.count(), template)
        fi = fi.get()
        tags = template_tags(blog=template.blog,
                             template=template,
                             fileinfo=fi)

    elif template.template_type == template_type.page:
        try:
            fi = Page.load(int(request.query['use_page'])).fileinfos[0]
        except (KeyError, TypeError):
            fi = template.fileinfos
            test_preview_mapping(fi.count(), template)
            fi = fi.select().join(Page).where(
                FileInfo.page == Page.id,
                Page.blog == template.blog,
                Page.status == page_status.published,
            ).order_by(Page.publication_date.desc()).get()
        tags = template_tags(
            template=template,
            page=fi.page,
        )

    elif template.template_type == template_type.include:
        if template.publishing_mode != publishing_mode.ssi:
            from core.error import PreviewException
            raise PreviewException(
                'You can only preview server-side includes.')
        page = template.blog.pages.published.order_by(
            Page.publication_date.desc()).get()
        fi = page.fileinfos[0]
        tags = template_tags(
            template=template,
            page=page,
        )

    elif template.template_type == template_type.archive:

        if 'use_page' in request.query:
            page_list = [Page.load(int(request.query['use_page']))]
        elif 'use_category' in request.query:
            from core.models import Category
            page_list = Category.load(int(
                request.query['use_category'])).pages.published.limit(1)
        elif 'use_tag' in request.query:
            from core.models import Tag
            page_list = Tag.load(int(
                request.query['use_tag'])).pages.published.limit(1)
        else:
            page_list = template.blog.pages.published.limit(1)

        fi = fileinfo.build_archives_fileinfos_by_mappings(template,
                                                           pages=page_list)
        test_preview_mapping(len(fi), template)
        fi = fi[0]

        archive_pages = fileinfo.generate_archive_context_from_fileinfo(
            fi.xref.archive_xref, template.blog.pages.published, fi)

        tags = template_tags(blog=template.blog,
                             archive=archive_pages,
                             archive_context=fi,
                             fileinfo=fi,
                             template=template)

    elif template.template_type in (template_type.media, template_type.system):
        from core.error import PreviewException
        raise PreviewException(
            'Template {} is of a type that cannot yet be previewed.'.format(
                template.for_log))

    import time
    from core.template import tplt
    tc = time.clock
    start = tc()
    tpl_output = tplt(template, tags)
    end = tc()

    tpl_output = r'<!-- Produced by template {}. Total render time:{} secs -->{}'.format(
        template.for_log, end - start, tpl_output)

    preview_file_path, preview_url = fi.make_preview()

    from core.cms import queue
    queue.write_file(tpl_output, template.blog.path, preview_file_path)

    return ("{}?_={}".format(preview_url, template.modified_date.microsecond))
Example #5
0
def save_page(page, user, blog=None):
    '''
    Saves edits to a page in the CMS.
    Note that this function does _not_ perform permission checking. In other words, it doesn't
    verify if the user described in the `user` parameter does in fact have permissions to
    edit the page in question.

    :param page:
        Page object whose data is to be saved. If this is None, then it is assumed that we are
        creating a new page.
    :param user:
        The user object associated with the save action for this page. If this is a newly-created page,
        the page's user will be set to this.
    :param blog:
        The blog object under which the page will be created, if this is a newly-created page.

    '''

    getunicode = request.forms.getunicode

    # invalidate_cache()

    save_action = int(request.forms.get('save'))

    original_page_status = page_status.unpublished
    new_basename = getunicode('basename')

    if page is None:

        # CREATE NEW PAGE ENTRY

        page = Page()
        page.user = user.id
        page.blog = blog.id

        page.basename = create_basename(getunicode('page_title'),
            page.blog)
        original_page_basename = page.basename

        time_now = datetime.datetime.utcnow()

        page.publication_date = time_now
        page.created_date = time_now

    else:

        # UPDATE EXISTING ENTRY

        # Queue neighbor actions for page BEFORE modification

        if page.status == page_status.published:
            if not (save_action & save_action_list.UNPUBLISH_PAGE):
                queue_page_actions((page.next_page, page.previous_page),no_neighbors=True, no_archive=True)
                queue_page_archive_actions(page)

        original_page_status = page.status
        original_page_basename = page.basename

        page.modified_date = datetime.datetime.utcnow()

        change_basename = False

        if new_basename is not None:
            if new_basename == "":
                change_basename = True
                new_basename = create_basename(getunicode('page_title'),
                    page.blog)
            if new_basename != original_page_basename:
                change_basename = True

        new_publication_date = datetime.datetime.strptime(
            request.forms.get('publication_date'), DATE_FORMAT)

        if change_basename:
            page.basename = create_basename(new_basename, page.blog)

        page.publication_date = page._date_to_utc(page.blog.timezone, new_publication_date).replace(tzinfo=None)

    page.title = getunicode('page_title')
    page.text = getunicode('page_text')
    page.status = page_status.modes[int(request.forms.get('publication_status'))]
    page.tag_text = getunicode('page_tag_text')
    page.excerpt = getunicode('page_excerpt')

    change_note = getunicode('change_note')

    msg = []

    # UNPUBLISH

    if (
        (save_action & save_action_list.UNPUBLISH_PAGE and page.status == page_status.published) or  # unpublished a published page
        (original_page_status == page_status.published and page.status == page_status.unpublished)  # set a published page to draft
        ):

        unpublish_page(page)
        msg.append("Page <b>{}</b> unpublished successfully.")

    # SET UNPUBLISHED TO PUBLISHED

    elif original_page_status == page_status.unpublished and (save_action & save_action_list.UPDATE_LIVE_PAGE):
        page.status = page_status.published
        msg.append("Set to publish.")

    # SAVE DRAFT

    if (save_action & save_action_list.SAVE_TO_DRAFT):

        try:
            save_result = page.save(user, False, False, change_note)
        except PageNotChanged:
            save_result = (None, None)

        msg.append("Page <b>{}</b> saved successfully.")

        # Assign categories for page

        categories = []

        for n in request.forms.allitems():
            if n[0][:8] == 'cat-sel-':
                try:
                    category_id = int(n[0][8:])
                except ValueError:
                    category_id = None
                else:
                    categories.append(category_id)

        if not categories:
            categories.append(blog.default_category.id)
            msg.append(" Default category auto-assigned for page.")

        page_categories = []

        primary = None

        for n in page.categories:
            if n.category.id not in categories:
                delete_category = PageCategory.delete().where(
                    PageCategory.id == n.id)
                delete_category.execute()
            else:
                page_categories.append(n.category.id)
                if n.primary is True:
                    primary = n

        for n in categories:
            if n not in page_categories:
                new_page_category = PageCategory.create(
                    page=page,
                    category=Category.load(n, blog_id=page.blog.id),
                    primary=False)

        if primary is None:
            n = page.categories[0]
            n.primary = True
            n.save()

        delete_page_fileinfo(page)
        build_archives_fileinfos((page,))
        build_pages_fileinfos((page,))

    # UPDATE TAGS

    if getunicode('tag_text') is not None:
        import json
        tag_text = json.loads(getunicode('tag_text'))
        add_tags_to_page(tag_text, page)
        delete_orphaned_tags(page.blog)

    # QUEUE CHANGES FOR PUBLICATION (if any)

    if ((save_action & save_action_list.UPDATE_LIVE_PAGE)
        and (page.status == page_status.published)):

        queue_ssi_actions(page.blog)
        queue_page_actions((page,))
        queue_index_actions(page.blog)

        msg.append(" Live page updated.")

    # DETECT ANY PAGE CHANGES

    if (
        (save_action & (save_action_list.SAVE_TO_DRAFT + save_action_list.UPDATE_LIVE_PAGE))
        and (save_result[1]) is None):

        msg.append(" (Page unchanged.)")

    # RETURN REPORT

    tags = template_tags(page=page, user=user)

    status = Status(
        type='success',
        message=' / '.join(msg),
        vals=(page.for_log,)
        )

    tags.status = status
    tags._save_action = save_action
    tags._save_action_list = save_action_list

    return tags
Example #6
0
def delete_category(blog_id, category_id, confirm='N'):
    user = auth.is_logged_in(request)
    blog = Blog.load(blog_id)
    permission = auth.is_blog_admin(user, blog)

    category = Category.load(category_id, blog_id=blog.id)
    auth.check_category_editing_lock(blog)

    tags = template_tags(
        blog=blog,
        user=user)

    from core.utils import Status

    if request.forms.getunicode('confirm') == user.logout_nonce:
        message = 'Category {} successfully deleted'.format(
            category.for_log)
        url = '{}/blog/{}/categories'.format(BASE_URL, blog.id)
        action = 'Return to the category listing'

        reparent_categories = Category.update(
            parent_category=category.parent_category).where(
                Category.parent_category == category)
        reparent_categories.execute()

        delete_category = PageCategory.delete().where(
            PageCategory.category == category.id)
        delete_category.execute()

        category.delete_instance()

        tags.status = Status(
            type='success',
            message=message,
            action=action,
            url=url,
            close=False)

    else:
        message = ('You are about to delete category <b>{}</b> from blog <b>{}</b>.'.format(
            category.for_display,
            blog.for_display))

        yes = {
                'label':'Yes, delete this category',
                'id':'delete',
                'name':'confirm',
                'value':user.logout_nonce}
        no = {
            'label':'No, return to category properties',
            'url':'{}/blog/{}/category/{}'.format(
                BASE_URL, blog.id, category.id)
            }

        tags.status = Status(
            message=message,
            type='warning',
            close=False,
            yes=yes,
            no=no
            )

    tags.category = category

    return report(tags, 'blog_delete_category', category)
Example #7
0
def edit_category(blog_id, category_id):
    user = auth.is_logged_in(request)
    blog = Blog.load(blog_id)
    permission = auth.is_blog_admin(user, blog)

    category = Category.load(category_id, blog_id=blog.id)
    auth.check_category_editing_lock(blog)

    category_list = [n for n in blog.categories]

    top_level_category = Category(
        id=None,
        title='[Top-level category]',
        parent=None
        )

    category_list.insert(0, top_level_category)

    tags = template_tags(
        blog=blog,
        user=user)

    from core.utils import Status
    status = []

    if request.method == "POST":
        new_category_title = request.forms.getunicode('category_title')
        old_category_title = category.title

        if new_category_title != old_category_title:

            category.title = new_category_title
            category.save()

            status.append(
                ['Category <b>{}</b> was renamed to <b>{}</b>.',
                [old_category_title, new_category_title]])

        old_parent_category = category.parent_category
        try:
            new_parent_category = int(request.forms.getunicode('category_parent'))
        except ValueError:
            new_parent_category = None

        new_basename = request.forms.getunicode('category_basename')
        if category.basename != new_basename:
            category.basename = new_basename
            category.save()

            status.append(['Category basename was changed.',
                []])

        if old_parent_category != new_parent_category:
            category.parent_category = new_parent_category
            category.save()

            if new_parent_category is not None:
                new_category = Category.load(
                    category_id=new_parent_category,
                    blog=blog)
            else:
                new_category = top_level_category

            status.append(['Category <b>{}</b> was reparented to <b>{}</b>.',
                [category.title, new_category.for_log]])

        if request.forms.getunicode('default') == "Y":
            clear_default_categories = Category.update(
                default=False).where(
                    Category.blog == blog,
                    Category.default == True)
            clear_default_categories.execute()
            category.default = True
            category.save()

            status.append(['Category <b>{}</b> was set to default for blog <b>{}</b>.',
                [category.title, blog.for_log]])

    if len(status) > 0:
        message = ''
        vals = []
        for n in status:
            message += n[0]
            for m in n[1]:
                vals.append(m)
            vals.append('{}/blog/{}/purge'.format(BASE_URL, blog.id))
        tags.status = Status(type='success',
            message=message + '<br/><a href="{}">Purge and republish this blog</a> to make these changes take effect.',
            vals=vals)

    # from core.ui_kv import kv_ui
    from core.ui import kv
    kv_ui_data = kv.ui(category.kv_list())

    from core.ui import sidebar
    tags.sidebar = sidebar.render_sidebar(
            panel_set='edit_category',
            # status_badge=status_badge,
            kv_object='Category',
            kv_objectid=category.id,
            kv_ui=kv_ui_data)

    tpl = template('edit/category',
        category=category,
        category_list=category_list,
        menu=generate_menu('blog_edit_category', category),
        search_context=(search_contexts['sites'], None),
        **tags.__dict__)

    return tpl
Example #8
0
def edit_category(blog_id, category_id):
    user = auth.is_logged_in(request)
    blog = Blog.load(blog_id)
    permission = auth.is_blog_admin(user, blog)

    category = Category.load(category_id, blog_id=blog.id)
    auth.check_category_editing_lock(blog)

    category_list = [n for n in blog.categories]

    top_level_category = Category(id=None,
                                  title='[Top-level category]',
                                  parent=None)

    category_list.insert(0, top_level_category)

    tags = template_tags(blog=blog, user=user)

    from core.utils import Status
    status = []

    if request.method == "POST":
        new_category_title = request.forms.getunicode('category_title')
        old_category_title = category.title

        if new_category_title != old_category_title:

            category.title = new_category_title
            category.save()

            status.append([
                'Category <b>{}</b> was renamed to <b>{}</b>.',
                [old_category_title, new_category_title]
            ])

        old_parent_category = category.parent_category
        try:
            new_parent_category = int(
                request.forms.getunicode('category_parent'))
        except ValueError:
            new_parent_category = None

        new_basename = request.forms.getunicode('category_basename')
        if category.basename != new_basename:
            category.basename = new_basename
            category.save()

            status.append(['Category basename was changed.', []])

        if old_parent_category != new_parent_category:
            category.parent_category = new_parent_category
            category.save()

            if new_parent_category is not None:
                new_category = Category.load(category_id=new_parent_category,
                                             blog=blog)
            else:
                new_category = top_level_category

            status.append([
                'Category <b>{}</b> was reparented to <b>{}</b>.',
                [category.title, new_category.for_log]
            ])

        if request.forms.getunicode('default') == "Y":
            clear_default_categories = Category.update(default=False).where(
                Category.blog == blog, Category.default == True)
            clear_default_categories.execute()
            category.default = True
            category.save()

            status.append([
                'Category <b>{}</b> was set to default for blog <b>{}</b>.',
                [category.title, blog.for_log]
            ])

    if len(status) > 0:
        message = ''
        vals = []
        for n in status:
            message += n[0]
            for m in n[1]:
                vals.append(m)
            vals.append('{}/blog/{}/purge'.format(BASE_URL, blog.id))
        tags.status = Status(
            type='success',
            message=message +
            '<br/><a href="{}">Purge and republish this blog</a> to make these changes take effect.',
            vals=vals)

    # from core.ui_kv import kv_ui
    from core.ui import kv
    kv_ui_data = kv.ui(category.kv_list())

    from core.ui import sidebar
    tags.sidebar = sidebar.render_sidebar(
        panel_set='edit_category',
        # status_badge=status_badge,
        kv_object='Category',
        kv_objectid=category.id,
        kv_ui=kv_ui_data)

    tpl = template('edit/category',
                   category=category,
                   category_list=category_list,
                   menu=generate_menu('blog_edit_category', category),
                   search_context=(search_contexts['sites'], None),
                   **tags.__dict__)

    return tpl
Example #9
0
def save_page(page, user, blog=None):
    '''
    Saves edits to a page in the CMS.
    Note that this function does _not_ perform permission checking. In other words, it doesn't
    verify if the user described in the `user` parameter does in fact have permissions to
    edit the page in question.

    :param page:
        Page object whose data is to be saved. If this is None, then it is assumed that we are
        creating a new page.
    :param user:
        The user object associated with the save action for this page. If this is a newly-created page,
        the page's user will be set to this.
    :param blog:
        The blog object under which the page will be created, if this is a newly-created page.

    '''

    getunicode = request.forms.getunicode

    # invalidate_cache()

    save_action = int(request.forms.get('save'))

    original_page_status = page_status.unpublished
    new_basename = getunicode('basename')

    if page is None:

        # CREATE NEW PAGE ENTRY

        page = Page()
        page.user = user.id
        page.blog = blog.id

        page.basename = create_basename(getunicode('page_title'), page.blog)
        original_page_basename = page.basename

        time_now = datetime.datetime.utcnow()

        page.publication_date = time_now
        page.created_date = time_now

    else:

        # UPDATE EXISTING ENTRY

        # Queue neighbor actions for page BEFORE modification

        if page.status == page_status.published:
            if not (save_action & save_action_list.UNPUBLISH_PAGE):
                queue_page_actions((page.next_page, page.previous_page),
                                   no_neighbors=True,
                                   no_archive=True)
                queue_page_archive_actions(page)

        original_page_status = page.status
        original_page_basename = page.basename

        page.modified_date = datetime.datetime.utcnow()

        change_basename = False

        if new_basename is not None:
            if new_basename == "":
                change_basename = True
                new_basename = create_basename(getunicode('page_title'),
                                               page.blog)
            if new_basename != original_page_basename:
                change_basename = True

        new_publication_date = datetime.datetime.strptime(
            request.forms.get('publication_date'), DATE_FORMAT)

        if change_basename:
            page.basename = create_basename(new_basename, page.blog)

        page.publication_date = page._date_to_utc(
            page.blog.timezone, new_publication_date).replace(tzinfo=None)

    page.title = getunicode('page_title')
    page.text = getunicode('page_text')
    page.status = page_status.modes[int(
        request.forms.get('publication_status'))]
    page.tag_text = getunicode('page_tag_text')
    page.excerpt = getunicode('page_excerpt')

    change_note = getunicode('change_note')

    msg = []

    # UNPUBLISH

    if ((save_action & save_action_list.UNPUBLISH_PAGE
         and page.status == page_status.published)
            or  # unpublished a published page
        (original_page_status == page_status.published
         and page.status == page_status.unpublished
         )  # set a published page to draft
        ):

        unpublish_page(page)
        msg.append("Page <b>{}</b> unpublished successfully.")

    # SET UNPUBLISHED TO PUBLISHED

    elif original_page_status == page_status.unpublished and (
            save_action & save_action_list.UPDATE_LIVE_PAGE):
        page.status = page_status.published
        msg.append("Set to publish.")

    # SAVE DRAFT

    if (save_action & save_action_list.SAVE_TO_DRAFT):

        try:
            save_result = page.save(user, False, False, change_note)
        except PageNotChanged:
            save_result = (None, None)

        msg.append("Page <b>{}</b> saved successfully.")

        # Assign categories for page

        categories = []

        for n in request.forms.allitems():
            if n[0][:8] == 'cat-sel-':
                try:
                    category_id = int(n[0][8:])
                except ValueError:
                    category_id = None
                else:
                    categories.append(category_id)

        if not categories:
            categories.append(blog.default_category.id)
            msg.append(" Default category auto-assigned for page.")

        page_categories = []

        primary = None

        for n in page.categories:
            if n.category.id not in categories:
                delete_category = PageCategory.delete().where(
                    PageCategory.id == n.id)
                delete_category.execute()
            else:
                page_categories.append(n.category.id)
                if n.primary is True:
                    primary = n

        for n in categories:
            if n not in page_categories:
                new_page_category = PageCategory.create(
                    page=page,
                    category=Category.load(n, blog_id=page.blog.id),
                    primary=False)

        if primary is None:
            n = page.categories[0]
            n.primary = True
            n.save()

        delete_page_fileinfo(page)
        build_archives_fileinfos((page, ))
        build_pages_fileinfos((page, ))

    # UPDATE TAGS

    if getunicode('tag_text') is not None:
        import json
        tag_text = json.loads(getunicode('tag_text'))
        add_tags_to_page(tag_text, page)
        delete_orphaned_tags(page.blog)

    # QUEUE CHANGES FOR PUBLICATION (if any)

    if ((save_action & save_action_list.UPDATE_LIVE_PAGE)
            and (page.status == page_status.published)):

        queue_ssi_actions(page.blog)
        queue_page_actions((page, ))
        queue_index_actions(page.blog)

        msg.append(" Live page updated.")

    # DETECT ANY PAGE CHANGES

    if ((save_action &
         (save_action_list.SAVE_TO_DRAFT + save_action_list.UPDATE_LIVE_PAGE))
            and (save_result[1]) is None):

        msg.append(" (Page unchanged.)")

    # RETURN REPORT

    tags = template_tags(page=page, user=user)

    status = Status(type='success',
                    message=' / '.join(msg),
                    vals=(page.for_log, ))

    tags.status = status
    tags._save_action = save_action
    tags._save_action_list = save_action_list

    return tags
Example #10
0
def blog_import(blog_id):
    user = auth.is_logged_in(request)
    blog = Blog.load(blog_id)
    permission = auth.is_blog_publisher(user, blog)
    reason = auth.check_template_lock(blog, True)

    tags = template_tags(blog=blog, user=user)

    import os, settings
    import_path = os.path.join(settings.APPLICATION_PATH, "data",
                               "import.json")

    tags.status = reason

    if request.method == "POST":
        from core.models import db
        tpl = ''
        with db.atomic() as txn:
            import json
            from core.utils import string_to_date

            import_path = request.forms.getunicode('import_path')
            with open(import_path, 'r', encoding='utf8') as f:
                json_data = json.load(f)

            from core.models import page_status, MediaAssociation, Category
            from core.error import PageNotChanged
            from core.libs.peewee import InterfaceError
            from core.cms import media_filetypes
            format_str = "<b>{}</b> / (<i>{}</i>)"

            # TODO: go in chunks of 50 or something?
            # allow graceful disconnection?
            for n in json_data:
                q = []
                n_id = n['id']
                q.append("Checking {}".format(n_id))
                changed = False
                found = False
                match = Page.kv_get('legacy_id', n_id)
                if match.count() > 0:
                    if match[0].object_ref.blog == blog:
                        found = True
                        q.append(match[0].key + "/" + match[0].value +
                                 " / Exists: " +
                                 format_str.format(n['title'], n_id))
                        existing_entry = Page.load(match[0].objectid)
                        update = existing_entry.kv_get('update').count()
                        # raise Exception(update)
                        q.append('{} / {}'.format(
                            string_to_date(
                                n['modified_date']).replace(tzinfo=None),
                            existing_entry.modified_date))
                        if string_to_date(n['modified_date']).replace(
                                tzinfo=None
                        ) <= existing_entry.modified_date and update == 0:
                            q.append('Existing page {} not changed.'.format(
                                existing_entry.id))
                        else:
                            changed = True
                            q.append(
                                'Updating data for existing page {}.'.format(
                                    existing_entry.id))
                            existing_entry.title = n['title']
                            existing_entry.text = n['text']
                            existing_entry.basename = n['basename']
                            existing_entry.excerpt = n['excerpt']

                            existing_entry.created_date = string_to_date(
                                n['created_date']).replace(tzinfo=None)
                            existing_entry.modified_date = string_to_date(
                                n['modified_date']).replace(tzinfo=None)
                            existing_entry.publication_date = string_to_date(
                                n['publication_date']).replace(tzinfo=None)

                            try:
                                existing_entry.save(
                                    user, False, False,
                                    'New revision from import')
                            except PageNotChanged:
                                pass
                            except InterfaceError:
                                raise Exception(
                                    "Error saving {}. Check the JSON to make sure it's valid."
                                    .format(n_id))

                            for media in existing_entry.media:
                                media.kv_del()

                            existing_entry.clear_categories()
                            existing_entry.clear_kvs()
                            existing_entry.clear_tags()
                            existing_entry.clear_media()

                            entry = existing_entry

                if found is False:
                    q.append("Creating: " +
                             format_str.format(n['title'], n_id))
                    changed = True
                    new_entry = Page(
                        title=n['title'],
                        text=n['text'],
                        basename=n['basename'],
                        excerpt=n['excerpt'],
                        user=user,
                        blog=blog,
                        created_date=string_to_date(n['created_date']),
                        publication_date=string_to_date(n['publication_date']),
                        modified_date=string_to_date(n['modified_date']),
                    )

                    new_entry.modified_date = new_entry.publication_date

                    if n['status'] in ('Publish', 'Published', 'Live'):
                        new_entry.status = page_status.published

                    new_entry.save(user)

                    entry = new_entry

                    q.append("New ID: {}".format(entry.id))

                    # Everything from here on out is

                if changed:

                    # Register a legacy ID for the page

                    entry.kv_set("legacy_id", n["id"])
                    entry.kv_set("legacy_user", n["user_id"])

                    # Category assignments

                    categories = n['categories']
                    if categories == []:
                        saved_page_category = PageCategory.create(
                            page=entry,
                            category=blog.default_category,
                            primary=True).save()
                    else:
                        primary = True
                        for category in categories:
                            cat_exists = False

                            category_id = category['id']
                            existing_category = Category.kv_get(
                                'legacy_id', category_id)
                            if existing_category.count() > 0:
                                if existing_category[
                                        0].object_ref.blog == blog:
                                    cat_exists = True

                            if cat_exists is False:

                                q.append('Created new category {}/{}'.format(
                                    category_id, category['name']))
                                new_category = Category.create(
                                    blog=blog,
                                    title=category['name'],
                                    parent_category=getattr(
                                        category, 'parent', None))
                                new_category.save()

                                new_category.kv_set('legacy_id', category_id)
                            else:
                                new_category = Category.load(
                                    existing_category[0].objectid)
                                q.append(
                                    'Added to existing category {}/{}'.format(
                                        new_category.id, category['name']))

                            saved_page_category = PageCategory.create(
                                page=entry,
                                category=new_category,
                                primary=primary).save()
                            primary = False

                    # Check to make sure a default category exists for the whole blog.
                    # If not, assign one based on the lowest ID.
                    # This can always be reassigned later.

                    # Register tags

                    tags_added, tags_existing, _ = Tag.add_or_create(
                        n['tags'], page=entry)

                    q.append('Tags added: {}'.format(','.join(
                        n.tag for n in tags_added)))
                    q.append('Tags existing: {}'.format(','.join(
                        n.tag for n in tags_existing)))

                    # Register KVs

                    kvs = n['kvs']
                    for key in kvs:
                        if key != "":
                            value = kvs[key]
                            entry.kv_set(key, value)
                            q.append('KV: {}:{}'.format(key, value))

                    # Register media

                    media = n['media']

                    for m in media:

                        if 'path' not in m:
                            continue

                        path = os.path.split(m['path'])

                        try:
                            new_media = Media.get(Media.url == m['url'])
                        except:
                            new_media = Media(filename=path[1],
                                              path=m['path'],
                                              url=m['url'],
                                              type=media_filetypes.image,
                                              created_date=string_to_date(
                                                  m['created_date']),
                                              modified_date=string_to_date(
                                                  m['modified_date']),
                                              friendly_name=m['friendly_name'],
                                              user=user,
                                              blog=blog,
                                              site=blog.site)

                        # TODO: RBF
                        try:
                            new_media.save()
                        except Exception:
                            continue

                        media_association = MediaAssociation(media=new_media,
                                                             page=entry)

                        media_association.save()

                        # Save legacy ID to KV on media

                        if 'id' in m:
                            new_media.kv_set('legacy_id', m['id'])

                        q.append('IMG: {}'.format(new_media.url))

                        # add tags for media

                        q.append('Tags: {}'.format(m['tags']))
                        new_tags = Tag.add_or_create(m['tags'],
                                                     media=new_media)

                        kvs = m['kvs']
                        for key in kvs:
                            value = kvs[key]
                            new_media.kv_set(key, value)
                            q.append('KV: {}:{}'.format(key, value))

                    fileinfo.build_pages_fileinfos((entry, ))
                    fileinfo.build_archives_fileinfos((entry, ))

                tpl += ('<p>'.join(q)) + '<hr/>'
        return tpl

        # TODO:

        # Import or create categories as needed
        # Categories in export will need to have parent-child data
        # categories should have legacy identifiers where possible too

        # Import image files, assign those legacy KV identifiers
        # Modify URLs for imported images in posts
        # Make importing of image assets optional

    else:
        tpl = template(
            'ui/ui_blog_import',
            menu=generate_menu('blog_import', blog),
            # search_context=(search_context['blog'], blog),
            import_path=import_path,
            **tags.__dict__)

        return tpl
Example #11
0
def blog_import (blog_id):
    user = auth.is_logged_in(request)
    blog = Blog.load(blog_id)
    permission = auth.is_blog_publisher(user, blog)
    reason = auth.check_template_lock(blog, True)

    tags = template_tags(blog=blog,
        user=user)

    import os, settings
    import_path = os.path.join(
        settings.APPLICATION_PATH,
        "data",
        "import.json")

    tags.status = reason

    if request.method == "POST":
        from core.models import db
        tpl = ''
        with db.atomic() as txn:
            import json
            from core.utils import string_to_date

            import_path = request.forms.getunicode('import_path')
            with open(import_path, 'r', encoding='utf8') as f:
                json_data = json.load(f)

            from core.models import page_status, MediaAssociation, Category
            from core.error import PageNotChanged
            from core.libs.peewee import InterfaceError
            from core.cms import media_filetypes
            format_str = "<b>{}</b> / (<i>{}</i>)"

            # TODO: go in chunks of 50 or something?
            # allow graceful disconnection?
            for n in json_data:
                q = []
                n_id = n['id']
                q.append("Checking {}".format(n_id))
                changed = False
                found = False
                match = Page.kv_get('legacy_id', n_id)
                if match.count() > 0:
                    if match[0].object_ref.blog == blog:
                        found = True
                        q.append(match[0].key + "/" + match[0].value + " / Exists: " + format_str.format(n['title'], n_id))
                        existing_entry = Page.load(match[0].objectid)
                        update = existing_entry.kv_get('update').count()
                        # raise Exception(update)
                        q.append('{} / {}'.format(string_to_date(n['modified_date']).replace(tzinfo=None), existing_entry.modified_date
                            ))
                        if string_to_date(n['modified_date']).replace(tzinfo=None) <= existing_entry.modified_date and update == 0:
                            q.append('Existing page {} not changed.'.format(existing_entry.id))
                        else:
                            changed = True
                            q.append('Updating data for existing page {}.'.format(existing_entry.id))
                            existing_entry.title = n['title']
                            existing_entry.text = n['text']
                            existing_entry.basename = n['basename']
                            existing_entry.excerpt = n['excerpt']

                            existing_entry.created_date = string_to_date(n['created_date']).replace(tzinfo=None)
                            existing_entry.modified_date = string_to_date(n['modified_date']).replace(tzinfo=None)
                            existing_entry.publication_date = string_to_date(n['publication_date']).replace(tzinfo=None)

                            try:
                                existing_entry.save(user, False, False, 'New revision from import')
                            except PageNotChanged:
                                pass
                            except InterfaceError:
                                raise Exception("Error saving {}. Check the JSON to make sure it's valid.".format(n_id))

                            for media in existing_entry.media:
                                media.kv_del()

                            existing_entry.clear_categories()
                            existing_entry.clear_kvs()
                            existing_entry.clear_tags()
                            existing_entry.clear_media()

                            entry = existing_entry

                if found is False:
                    q.append("Creating: " + format_str.format(n['title'], n_id))
                    changed = True
                    new_entry = Page(
                        title=n['title'],
                        text=n['text'],
                        basename=n['basename'],
                        excerpt=n['excerpt'],
                        user=user,
                        blog=blog,
                        created_date=string_to_date(n['created_date']),
                        publication_date=string_to_date(n['publication_date']),
                        modified_date=string_to_date(n['modified_date']),
                    )

                    new_entry.modified_date = new_entry.publication_date

                    if n['status'] in ('Publish', 'Published', 'Live'):
                        new_entry.status = page_status.published

                    new_entry.save(user)

                    entry = new_entry

                    q.append("New ID: {}".format(entry.id))

                    # Everything from here on out is

                if changed:

                    # Register a legacy ID for the page

                    entry.kv_set("legacy_id", n["id"])
                    entry.kv_set("legacy_user", n["user_id"])

                    # Category assignments

                    categories = n['categories']
                    if categories == []:
                        saved_page_category = PageCategory.create(
                            page=entry,
                            category=blog.default_category,
                            primary=True).save()
                    else:
                        primary = True
                        for category in categories:
                            cat_exists = False

                            category_id = category['id']
                            existing_category = Category.kv_get('legacy_id', category_id)
                            if existing_category.count() > 0:
                                if existing_category[0].object_ref.blog == blog:
                                    cat_exists = True

                            if cat_exists is False:

                                q.append('Created new category {}/{}'.format(
                                    category_id, category['name']
                                    ))
                                new_category = Category.create(
                                    blog=blog,
                                    title=category['name'],
                                    parent_category=getattr(category, 'parent', None)
                                    )
                                new_category.save()

                                new_category.kv_set('legacy_id',
                                    category_id
                                    )
                            else:
                                new_category = Category.load(existing_category[0].objectid)
                                q.append('Added to existing category {}/{}'.format(
                                    new_category.id, category['name']
                                    ))

                            saved_page_category = PageCategory.create(
                                page=entry,
                                category=new_category,
                                primary=primary
                                ).save()
                            primary = False

                    # Check to make sure a default category exists for the whole blog.
                    # If not, assign one based on the lowest ID.
                    # This can always be reassigned later.

                    # Register tags

                    tags_added, tags_existing, _ = Tag.add_or_create(
                        n['tags'], page=entry)

                    q.append('Tags added: {}'.format(','.join(n.tag for n in tags_added)))
                    q.append('Tags existing: {}'.format(','.join(n.tag for n in tags_existing)))

                    # Register KVs

                    kvs = n['kvs']
                    for key in kvs:
                        if key != "":
                            value = kvs[key]
                            entry.kv_set(key, value)
                            q.append('KV: {}:{}'.format(key, value))

                    # Register media

                    media = n['media']

                    for m in media:

                        if 'path' not in m:
                            continue

                        path = os.path.split(m['path'])

                        try:
                            new_media = Media.get(Media.url == m['url'])
                        except:
                            new_media = Media(
                                filename=path[1],
                                path=m['path'],
                                url=m['url'],
                                type=media_filetypes.image,
                                created_date=string_to_date(m['created_date']),
                                modified_date=string_to_date(m['modified_date']),
                                friendly_name=m['friendly_name'],
                                user=user,
                                blog=blog,
                                site=blog.site
                                )

                        # TODO: RBF
                        try:
                            new_media.save()
                        except Exception:
                            continue

                        media_association = MediaAssociation(
                            media=new_media,
                            page=entry)

                        media_association.save()

                        # Save legacy ID to KV on media

                        if 'id' in m:
                            new_media.kv_set('legacy_id', m['id'])

                        q.append('IMG: {}'.format(new_media.url))

                        # add tags for media

                        q.append('Tags: {}'.format(m['tags']))
                        new_tags = Tag.add_or_create(m['tags'], media=new_media)

                        kvs = m['kvs']
                        for key in kvs:
                            value = kvs[key]
                            new_media.kv_set(key, value)
                            q.append('KV: {}:{}'.format(key, value))

                    fileinfo.build_pages_fileinfos((entry,))
                    fileinfo.build_archives_fileinfos((entry,))

                tpl += ('<p>'.join(q)) + '<hr/>'
        return tpl

        # TODO:

        # Import or create categories as needed
        # Categories in export will need to have parent-child data
        # categories should have legacy identifiers where possible too

        # Import image files, assign those legacy KV identifiers
        # Modify URLs for imported images in posts
        # Make importing of image assets optional

    else:
        tpl = template('ui/ui_blog_import',
            menu=generate_menu('blog_import', blog),
            # search_context=(search_context['blog'], blog),
            import_path=import_path,
            **tags.__dict__)

        return tpl