Edit a post.

    If requested over GET, shows the edit UI.
    If requested over POST, saves the post and shows the edit UI.

    :param path: Path to post to edit.

def edit(path):
    """Edit a post.

    If requested over GET, shows the edit UI.
    If requested over POST, saves the post and shows the edit UI.

    :param path: Path to post to edit.
    """
    context = {'path': path, 'site': site}
    post = find_post(path)
    if post is None:
        return error("No such post or page.", 404)

    current_auid = int(post.meta('author.uid') or current_user.uid)

    if (not current_user.can_edit_all_posts and
            current_auid != current_user.uid):
        return error("Cannot edit posts of other users.", 401)

    if request.method == 'POST':
        meta = {}
        for k, v in request.form.items():
            meta[k] = v
        meta.pop('_wysihtml5_mode', '')
        try:
            meta['author'] = get_user(meta['author.uid']).realname
            current_auid = int(meta['author.uid'])
            author_change_success = True
        except Exception:
            author_change_success = False
        if (not current_user.can_transfer_post_authorship or
                not author_change_success):
            meta['author'] = post.meta('author') or current_user.realname
            meta['author.uid'] = str(current_auid)

        twofile = post.is_two_file
        onefile = not twofile
        post.compiler.create_post(post.source_path, onefile=onefile,
                                  is_page=False, **meta)

        context['post_content'] = meta['content']

        if twofile:
            meta_path = os.path.splitext(path)[0] + '.meta'
            # We cannot save `content` as meta, otherwise things break badly
            meta.pop('content', '')
            with io.open(meta_path, 'w+', encoding='utf-8') as fh:
                fh.write(write_metadata(meta))
        scan_site()
        if db is not None:
            db.set('site:needs_rebuild', '1')
        else:
            site.coil_needs_rebuild = '1'
        post = find_post(path)
        context['action'] = 'save'
    else:
        context['action'] = 'edit'
        with io.open(path, 'r', encoding='utf-8') as fh:
            context['post_content'] = fh.read()
            if not post.is_two_file:
                context['post_content'] = context['post_content'].split(
                    '\n\n', 1)[1]

    context['post'] = post
    users = []
    if db is not None:
        uids = db.hgetall('users').values()
        for u in uids:
            u = u.decode('utf-8')
            realname, active = db.hmget('user:{0}'.format(u),
                                        'realname', 'active')
            if active in (u'1', b'1'):
                users.append((u, realname.decode('utf-8')))
    else:
        for u, d in app.config['COIL_USERS'].items():
            if d['active']:
                users.append((int(u), d['realname']))
    context['users'] = sorted(users)
    context['current_auid'] = current_auid
    context['title'] = 'Editing {0}'.format(post.title())
    context['is_html'] = post.compiler.name == 'html'
    return render('coil_post_edit.tmpl', context)