コード例 #1
0
ファイル: media.py プロジェクト: alanhdu/eventum
def upload():
    """Upload an image to Eventum

    :returns: A JSON containing the status of the file upload, or error
              messages, if any.
    :rtype: json
    """
    form = UploadImageForm(request.form)
    if form.validate_on_submit():
        f = request.files['image']
        if f:
            filename = create_filename(f, request.form['filename'])
            upload_folder = current_app.config['EVENTUM_UPLOAD_FOLDER']
            if not os.path.isdir(upload_folder):
                os.mkdir(upload_folder)
            f.save(os.path.join(upload_folder, filename))
            default_path = os.path.join(
                current_app.config['EVENTUM_UPLOAD_FOLDER'],
                filename,
            )
            image = Image(filename=filename,
                          default_path=default_path,
                          creator=g.user)
            image.save()
            return jsonify({"status": "true"})
    if form.errors:
        return jsonify(form.errors)
    return jsonify({"status": "error"})
コード例 #2
0
ファイル: import_images.py プロジェクト: coreatcu/new-website
def import_from_directory(path_to_images):

    connect("eventum")
    creator = User.objects().get(gplus_id="super")

    filenames = os.listdir(path_to_images)
    filenames = [fn for fn in filenames if not fn.startswith(".")]
    failures = []

    for filename in filenames:

        if Image.objects(filename=filename).count() > 0:
            img = Image.objects().get(filename=filename)
            img.delete()

        old_path = os.path.join(path_to_images, filename)
        shutil.copy(old_path, config["UPLOAD_FOLDER"])

        default_path = config["RELATIVE_UPLOAD_FOLDER"] + filename
        image = Image(filename=filename, default_path=default_path, creator=creator)
        try:
            image.save()
        except ValidationError as e:
            failures.append(filename)
            print "FAIL: %s" % filename
            print e

    print "Processed %s images." % len(filenames)
    print "%s success." % (len(filenames) - len(failures))
    print "%s failures." % len(failures)
コード例 #3
0
ファイル: media.py プロジェクト: pythonthings/eventum
def upload():
    """Upload an image to Eventum

    :returns: A JSON containing the status of the file upload, or error
              messages, if any.
    :rtype: json
    """
    form = UploadImageForm(request.form)
    if form.validate_on_submit():
        f = request.files['image']
        if f:
            filename = create_filename(f, request.form['filename'])
            upload_folder = current_app.config['EVENTUM_UPLOAD_FOLDER']
            if not os.path.isdir(upload_folder):
                os.mkdir(upload_folder)
            f.save(os.path.join(upload_folder, filename))
            default_path = os.path.join(
                current_app.config['EVENTUM_UPLOAD_FOLDER'],
                filename,
            )
            image = Image(filename=filename,
                          default_path=default_path,
                          creator=g.user)
            image.save()
            return jsonify({"status": "true"})
    if form.errors:
        return jsonify(form.errors)
    return jsonify({"status": "error"})
コード例 #4
0
ファイル: media.py プロジェクト: pythonthings/eventum
def delete(filename):
    """View all of the uploaded images.

    **Route:** ``/admin/media/delete/<filename>``

    **Methods:** ``POST``
    """
    if Image.objects(filename=filename).count() == 1:
        image = Image.objects().get(filename=filename)
        image.delete()
    else:
        flash('Invalid filename', ERROR_FLASH)
    return redirect(url_for('.index'))
コード例 #5
0
ファイル: media.py プロジェクト: alanhdu/eventum
def delete(filename):
    """View all of the uploaded images.

    **Route:** ``/admin/media/delete/<filename>``

    **Methods:** ``POST``
    """
    if Image.objects(filename=filename).count() == 1:
        image = Image.objects().get(filename=filename)
        image.delete()
    else:
        flash('Invalid filename', ERROR_FLASH)
    return redirect(url_for('.index'))
コード例 #6
0
ファイル: images.py プロジェクト: coreatcu/new-website
def create_images(num_images, superuser, printer):
    """Creates ``num_images`` image objects in the database.  It will download
    sample images from http://lorempixel.com, and add database entries.

    :param int num_images: The number of images to create
    :param superuser: The superuser object to associate with the images.
    :type superuser: :class:`~app.models.User`
    :param printer: The object to manage progress printing.
    :type printer: :class:`~script.cli.ProgressPrinter`

    :returns: A list of images that now exist.
    :rtype: list(:class:`~app.models.Image`)
    """
    print "Generating images..."
    printer.line()

    successes = []
    failures = []
    skips = []
    for width in range(400, 1600, (1600 - 400) / num_images):
        height = width / 2
        filename = BASE_FILENAME.format(width, height)
        path = config['UPLOAD_FOLDER'] + filename
        url = BASE_URL.format(width, height)

        printer.begin_status_line(filename)

        # Download image if it doesn't exist already
        if not exists(path):
            try:
                urllib.urlretrieve(url, path)
            except IOError:
                failures.append((filename, ''))
                printer.status_fail()
                continue  # Failed to download, move on to the next image.

        # Insert or fetch image from database
        if Image.objects(filename=filename).count() == 0:
            image = Image(filename=filename,
                          default_path=path,
                          creator=superuser)
            image.save()
            successes.append((filename, path))
            printer.status_success()
        else:
            skips.append((filename, path))
            printer.status_skip()

    printer.line()
    printer.results(len(successes), len(skips), len(failures))
    return successes + skips
コード例 #7
0
ファイル: __init__.py プロジェクト: alanhdu/eventum
    def register_delete_rules(self):
        """Registers rules for how Mongoengine handles the deletion of objects
        that are being referenced by other objects.

        See the documentation for
        :func:`mongoengine.model.register_delete_rule` for more information.

        All delete rules for User fields must by DENY, because User objects
        should never be deleted.  Lists of reference fields should PULL, to
        remove deleted objects from the list, and all others should NULLIFY
        """
        from eventum.models import (Event, EventSeries, User, Post, BlogPost,
                                    Image)
        from mongoengine import NULLIFY, PULL, DENY

        Event.register_delete_rule(EventSeries, 'events', PULL)
        Image.register_delete_rule(BlogPost, 'images', PULL)
        Image.register_delete_rule(User, 'image', NULLIFY)
        Image.register_delete_rule(BlogPost, 'featured_image', NULLIFY)
        Image.register_delete_rule(Event, 'image', NULLIFY)
        EventSeries.register_delete_rule(Event, 'parent_series', NULLIFY)
        User.register_delete_rule(Event, 'creator', DENY)
        User.register_delete_rule(Image, 'creator', DENY)
        User.register_delete_rule(Post, 'author', DENY)
        User.register_delete_rule(Post, 'posted_by', DENY)
コード例 #8
0
    def register_delete_rules(self):
        """Registers rules for how Mongoengine handles the deletion of objects
        that are being referenced by other objects.

        See the documentation for
        :func:`mongoengine.model.register_delete_rule` for more information.

        All delete rules for User fields must by DENY, because User objects
        should never be deleted.  Lists of reference fields should PULL, to
        remove deleted objects from the list, and all others should NULLIFY
        """
        from eventum.models import (Event, EventSeries, User, Post, BlogPost,
                                    Image)
        from mongoengine import NULLIFY, PULL, DENY

        Event.register_delete_rule(EventSeries, 'events', PULL)
        Image.register_delete_rule(BlogPost, 'images', PULL)
        Image.register_delete_rule(User, 'image', NULLIFY)
        Image.register_delete_rule(BlogPost, 'featured_image', NULLIFY)
        Image.register_delete_rule(Event, 'image', NULLIFY)
        EventSeries.register_delete_rule(Event, 'parent_series', NULLIFY)
        User.register_delete_rule(Event, 'creator', DENY)
        User.register_delete_rule(Image, 'creator', DENY)
        User.register_delete_rule(Post, 'author', DENY)
        User.register_delete_rule(Post, 'posted_by', DENY)
コード例 #9
0
ファイル: events.py プロジェクト: pythonthings/eventum
def create():
    """Create a new event.

    **Route:** ``/admin/events/create``

    **Methods:** ``GET, POST``
    """

    form = CreateEventForm(request.form)
    if form.validate_on_submit():
        try:
            EventsHelper.create_event(form, g.user)
        except EventumError.GCalAPI as e:
            flash(e.message, ERROR_FLASH)

        return redirect(url_for('.index'))
    if form.errors:
        for error in form.errors:
            for message in form.errors[error]:
                flash(message, ERROR_FLASH)

    upload_form = UploadImageForm()
    delete_form = DeleteEventForm()
    images = Image.objects()
    return render_template('eventum_events/create.html', form=form,
                           delete_form=delete_form, upload_form=upload_form,
                           images=images)
コード例 #10
0
ファイル: events.py プロジェクト: coreatcu/new-website
    def _image(self):
        """Gets an image to associate with the event, from the database.

        :returns: The image.
        :rtype: :class:'~app.models.Image'
        """
        return random.choice(Image.objects())
コード例 #11
0
ファイル: media.py プロジェクト: coreatcu/new-website
def view():
    """Displays all uploaded images.

    **Route:** ``/admin/media/view``

    **Methods:** ``GET``
    """
    images = Image.objects()
    return render_template('eventum_media/view.html', images=images)
コード例 #12
0
ファイル: posts.py プロジェクト: coreatcu/new-website
    def _images(self):
        """Gets a list of images from the database if any exist.

        :returns: The images.
        :rtype: list(:class:`~app.models.Image`)
        """
        # Fetch self.images if it hasn't been fetched
        if self.images is None:
            self.images = list(Image.objects().limit(5))
        return self.images
コード例 #13
0
def new():
    """Create a new blog post.

    **Route:** ``/admin/posts/new``

    **Methods:** ``POST``
    """
    form = CreateBlogPostForm(request.form)
    form.author.choices = [(str(u.id),
                            u.name + " (You)" if u == g.user else u.name)
                           for u in User.objects()]
    form.author.data = str(g.user.id)
    upload_form = UploadImageForm()
    if form.validate_on_submit():
        author = User.objects().get(id=ObjectId(form.author.data))
        images = [Image.objects().get(filename=fn) for fn in form.images.data]
        tags = Tag.get_or_create_tags(form.tags.data)
        post = BlogPost(title=form.title.data,
                        slug=form.slug.data,
                        images=images,
                        markdown_content=form.body.data,
                        author=author,
                        posted_by=g.user,
                        post_tags=tags)
        post.save()

        if form.published.data:
            post.publish()
        else:
            post.unpublish()

        if form.preview.data is True:
            return redirect(url_for('blog.preview', slug=post.slug))

        return redirect(url_for('.index'))
    images = Image.objects()
    return render_template('eventum_posts/edit.html',
                           user=g.user,
                           form=form,
                           images=images,
                           upload_form=upload_form)
コード例 #14
0
ファイル: media.py プロジェクト: alanhdu/eventum
def index():
    """View all of the uploaded images.

    **Route:** ``/admin/media``

    **Methods:** ``GET``
    """
    images = Image.objects()
    form = UploadImageForm()
    return render_template('eventum_media/media.html',
                           images=images,
                           form=form)
コード例 #15
0
ファイル: media.py プロジェクト: alanhdu/eventum
def select():
    """Displays all uploaded images, with mode depending on parameter passed in

    **Route:** ``/admin/media/image``

    **Methods:** ``GET``
    """
    images = Image.objects()

    fmt = "eventum_media/image_{image_mode!s}.html"
    template_name = fmt.format(image_mode=request.args.get("mode"))
    return render_template(template_name, images=images)
コード例 #16
0
def image_with_same_name(form, field):
    """A validator that ensures that there is an image in the database with the
    filename that is the same as the field's data.

    :param form: The parent form
    :type form: :class:`Form`
    :param field: The field to validate
    :type field: :class:`Field`
    """
    if Image.objects(filename=field.data).count() != 1:
        return ValidationError(
            message="Can't find image '{}' in the database".format(field.data))
コード例 #17
0
ファイル: validators.py プロジェクト: coreatcu/new-website
def image_with_same_name(form, field):
    """A validator that ensures that there is an image in the database with the
    filename that is the same as the field's data.

    :param form: The parent form
    :type form: :class:`Form`
    :param field: The field to validate
    :type field: :class:`Field`
    """
    if Image.objects(filename=field.data).count() != 1:
        return ValidationError(
            message="Can't find image '{}' in the database".format(field.data))
コード例 #18
0
ファイル: media.py プロジェクト: pythonthings/eventum
def select():
    """Displays all uploaded images, with mode depending on parameter passed in

    **Route:** ``/admin/media/image``

    **Methods:** ``GET``
    """
    images = Image.objects()

    fmt = "eventum_media/image_{image_mode!s}.html"
    template_name = fmt.format(image_mode=request.args.get("mode"))
    return render_template(template_name, images=images)
コード例 #19
0
ファイル: media.py プロジェクト: pythonthings/eventum
def index():
    """View all of the uploaded images.

    **Route:** ``/admin/media``

    **Methods:** ``GET``
    """
    images = Image.objects()
    form = UploadImageForm()
    return render_template('eventum_media/media.html',
                           images=images,
                           form=form)
コード例 #20
0
ファイル: gen.py プロジェクト: coreatcu/new-website
    def run(self):
        """Run the generation.  Uses the configurations passed to
        func:`__init__`.
        """

        # Setup: db connection, superuser, and printer.
        connect(config['MONGODB_SETTINGS']['DB'])
        try:
            superuser = User.objects().get(gplus_id='super')
        except DoesNotExist:
            print ('Failed to get superuser.  Try running:\n'
                   '\texport GOOGLE_AUTH_ENABLED=TRUE')
        printer = ProgressPrinter(self.quiet)

        # Images
        if self.should_gen_images:
            if self.wipe:
                self.warn('Image')
                print CLIColor.warning('Wiping Image database.')
                Image.drop_collection()
            create_images(12, superuser, printer)

        # Blog posts
        if self.should_gen_posts:
            if self.wipe:
                self.warn('BlogPost')
                print CLIColor.warning('Wiping BlogPost database.')
                BlogPost.drop_collection()
            create_posts(10, superuser, printer)

        # Events and event series
        if self.should_gen_events:
            if self.wipe:
                self.warn('Event and EventSeries')
                print CLIColor.warning('Wiping Event database.')
                Event.drop_collection()
                print CLIColor.warning('Wiping EventSeries database.')
                EventSeries.drop_collection()
            create_events(superuser, printer)
コード例 #21
0
ファイル: posts.py プロジェクト: coreatcu/new-website
def new():
    """Create a new blog post.

    **Route:** ``/admin/posts/new``

    **Methods:** ``POST``
    """
    form = CreateBlogPostForm(request.form)
    form.author.choices = [
        (str(u.id), u.name + " (You)" if u == g.user else u.name)
        for u in User.objects()
    ]
    form.author.data = str(g.user.id)
    upload_form = UploadImageForm()
    if form.validate_on_submit():
        author = User.objects().get(id=ObjectId(form.author.data))
        images = [Image.objects().get(filename=fn) for fn in form.images.data]
        tags = Tag.get_or_create_tags(form.tags.data)
        post = BlogPost(title=form.title.data,
                        slug=form.slug.data,
                        images=images,
                        markdown_content=form.body.data,
                        author=author,
                        posted_by=g.user, post_tags=tags)
        post.save()

        if form.published.data:
            post.publish()
        else:
            post.unpublish()

        if form.preview.data is True:
            return redirect(url_for('blog.preview', slug=post.slug))

        return redirect(url_for('.index'))
    images = Image.objects()
    return render_template('eventum_posts/edit.html', user=g.user, form=form,
                           images=images, upload_form=upload_form)
コード例 #22
0
ファイル: validators.py プロジェクト: coreatcu/new-website
    def __call__(self, form, field):
        """Called internally by :mod:`wtforms` on validation of the field.

        :param form: The parent form
        :type form: :class:`Form`
        :param field: The field to validate
        :type field: :class:`Field`

        :raises: :class:`wtforms.validators.ValidationError`
        """

        filename = '{}.'.format(field.data)
        if Image.objects(filename__startswith=filename).count():
            raise ValidationError(self.message)
コード例 #23
0
    def __call__(self, form, field):
        """Called internally by :mod:`wtforms` on validation of the field.

        :param form: The parent form
        :type form: :class:`Form`
        :param field: The field to validate
        :type field: :class:`Field`

        :raises: :class:`wtforms.validators.ValidationError`
        """

        filename = '{}.'.format(field.data)
        if Image.objects(filename__startswith=filename).count():
            raise ValidationError(self.message)
コード例 #24
0
ファイル: events.py プロジェクト: pythonthings/eventum
    def event_data_from_form(cls, form, creator=None):
        """Translate a :class:`~app.forms.CreateEventForm` or a subclass into a
        dictionary of event data.

        :param form: The form to translate.
        :type form: :class:`~app.forms.CreateEventForm` or a subclasss
        :param creator: The creator of the event.
        :type creator: :class:`~app.models.User`

        :returns: Event data.
        :rtype: dict
        """

        if not form:
            return {}
        event_image = None
        filename = form.event_image.data
        if filename and Image.objects(filename=filename).count() == 1:
            event_image = Image.objects().get(filename=filename)

        event_data = {
            'title': form.title.data,
            'slug': form.slug.data,
            'location': form.location.data,
            'start_time': form.start_time.data,
            'end_time': form.end_time.data,
            'published': form.published.data,
            'short_description_markdown': form.short_description.data,
            'long_description_markdown': form.long_description.data,
            'is_recurring': form.is_recurring.data,
            'facebook_url': form.facebook_url.data,
            'image': event_image
        }
        if creator:
            event_data['creator'] = creator
        return event_data
コード例 #25
0
ファイル: events.py プロジェクト: alanhdu/eventum
    def event_data_from_form(cls, form, creator=None):
        """Translate a :class:`~app.forms.CreateEventForm` or a subclass into a
        dictionary of event data.

        :param form: The form to translate.
        :type form: :class:`~app.forms.CreateEventForm` or a subclasss
        :param creator: The creator of the event.
        :type creator: :class:`~app.models.User`

        :returns: Event data.
        :rtype: dict
        """

        if not form:
            return {}
        event_image = None
        filename = form.event_image.data
        if filename and Image.objects(filename=filename).count() == 1:
            event_image = Image.objects().get(filename=filename)

        event_data = {
            'title': form.title.data,
            'slug': form.slug.data,
            'location': form.location.data,
            'start_time': form.start_time.data,
            'end_time': form.end_time.data,
            'published': form.published.data,
            'short_description_markdown': form.short_description.data,
            'long_description_markdown': form.long_description.data,
            'is_recurring': form.is_recurring.data,
            'facebook_url': form.facebook_url.data,
            'image': event_image
        }
        if creator:
            event_data['creator'] = creator
        return event_data
コード例 #26
0
ファイル: users.py プロジェクト: coreatcu/new-website
def index():
    """View and manage users.

    Whitelisted users are the only ones allowed to make user accounts.

    **Route:** ``/admin/users``

    **Methods:** ``GET``
    """

    upload_form = UploadImageForm()
    whitelist_form = AddToWhitelistForm()
    return render_template('eventum_users/users.html',
                           whitelist_form=whitelist_form,
                           upload_form=upload_form,
                           whitelist=Whitelist.objects(redeemed=False),
                           users=User.objects(),
                           images=Image.objects(),
                           current_user=g.user)
コード例 #27
0
ファイル: users.py プロジェクト: pythonthings/eventum
def index():
    """View and manage users.

    Whitelisted users are the only ones allowed to make user accounts.

    **Route:** ``/admin/users``

    **Methods:** ``GET``
    """

    upload_form = UploadImageForm()
    whitelist_form = AddToWhitelistForm()
    return render_template('eventum_users/users.html',
                           whitelist_form=whitelist_form,
                           upload_form=upload_form,
                           whitelist=Whitelist.objects(redeemed=False),
                           users=User.objects(),
                           images=Image.objects(),
                           current_user=g.user)
コード例 #28
0
ファイル: events.py プロジェクト: pythonthings/eventum
def edit(event_id):
    """Edit an existing event.

    **Route:** ``/admin/events/edit/<event_id>``

    **Methods:** ``GET, POST``

    :param str event_id: The ID of the event to edit.
    """

    try:
        event = Event.objects().get(id=event_id)
    except (DoesNotExist, ValidationError):
        flash('Cannot find event with id "{}"'.format(event_id), ERROR_FLASH)
        return redirect(url_for('.index'))

    if request.method == "POST":
        form = EditEventForm(event, request.form)
    else:
        form = EventsHelper.create_form(event, request)

    if form.validate_on_submit():
        try:
            EventsHelper.update_event(event, form)
        except EventumError.GCalAPI as e:
            flash(e.message, ERROR_FLASH)

        return redirect(url_for('.index'))
    if form.errors:
        for error in form.errors:
            for message in form.errors[error]:
                flash(message, ERROR_FLASH)

    delete_form = DeleteEventForm()
    upload_form = UploadImageForm()
    images = Image.objects()

    return render_template('eventum_events/edit.html', form=form, event=event,
                           delete_form=delete_form, upload_form=upload_form,
                           images=images)
コード例 #29
0
def add():
    """Add and email to the whitelist.

    **Route:** ``/admin/whitelist/add``

    **Methods:** ``POST``
    """
    form = AddToWhitelistForm(request.form)

    if form.user_type.data == 'fake_user':
        if form.validate_on_submit():
            fake_id = str(uuid.uuid4())
            fake_email = fake_id[:10] + "@fake-users.com"
            filename = form.fake_user_image.data
            try:
                fake_image = Image.objects().get(filename=filename)
                fake_user = User(email=fake_email,
                                 gplus_id=fake_id,
                                 name=form.name.data,
                                 user_type=form.user_type.data,
                                 image=fake_image)
            except Image.DoesNotExist:
                fake_user = User(email=fake_email,
                                 gplus_id=fake_id,
                                 name=form.name.data,
                                 user_type=form.user_type.data)
            fake_user.save()
        else:
            current_app.logger.warning(form.errors)
    else:
        user_exists = User.objects(email=form.email.data).count() != 0
        if form.validate_on_submit() and not user_exists:
            wl = Whitelist(email=form.email.data,
                           user_type=form.user_type.data)
            wl.save()
        else:
            current_app.logger.warning(form.errors)
    return redirect(url_for('users.index'))
コード例 #30
0
def edit(post_id):
    """Edit an existing blog post.

    **Route:** ``/admin/posts/edit/<post_id>``

    **Methods:** ``GET, POST``

    :param str post_id: The ID of the post to edit.
    """
    try:
        object_id = ObjectId(post_id)
    except InvalidId:
        return abort(404)
    try:
        post = BlogPost.objects().with_id(object_id)
    except (DoesNotExist, ValidationError):
        flash('Cannot find blog post with id {}.'.format(post_id), ERROR_FLASH)
        return redirect(url_for('.index'))

    if request.method == 'POST':
        form = CreateBlogPostForm(request.form)
        form.author.choices = [(str(u.id),
                                u.name + " (You)" if u == g.user else u.name)
                               for u in User.objects()]
        form.author.default = str(g.user.id)

        if form.validate_on_submit():
            post.title = form.title.data
            post.author = User.objects.get(id=ObjectId(form.author.data))
            post.slug = form.slug.data
            post.markdown_content = form.body.data
            post.images = [
                Image.objects().get(filename=fn) for fn in form.images.data
            ]

            post.post_tags = Tag.get_or_create_tags(form.tags.data)
            if form.featured_image.data:
                post.featured_image = Image.objects().get(
                    filename=form.featured_image.data)
            else:
                post.featured_image = None
            post.save()

            if post.published != form.published.data:
                if form.published.data:
                    post.publish()
                    flash('Blogpost published', MESSAGE_FLASH)
                else:
                    post.unpublish()
                    flash('Blogpost unpublished', MESSAGE_FLASH)

            if form.preview.data is True:
                return redirect(url_for('blog.preview', slug=post.slug))

    upload_form = UploadImageForm()
    feat_img = post.featured_image.filename if post.featured_image else None
    form = CreateBlogPostForm(request.form,
                              title=post.title,
                              slug=post.slug,
                              published=post.published,
                              body=post.markdown_content,
                              images=[image.filename for image in post.images],
                              author=str(post.author.id),
                              featured_image=feat_img,
                              tags=post.post_tags)
    form.author.choices = [(str(u.id),
                            u.name + " (You)" if u == g.user else u.name)
                           for u in User.objects()]
    form.author.default = str(g.user.id)
    images = [image for image in Image.objects() if image not in post.images]

    return render_template('eventum_posts/edit.html',
                           user=g.user,
                           form=form,
                           post=post,
                           images=images,
                           upload_form=upload_form)
コード例 #31
0
ファイル: posts.py プロジェクト: coreatcu/new-website
def edit(post_id):
    """Edit an existing blog post.

    **Route:** ``/admin/posts/edit/<post_id>``

    **Methods:** ``GET, POST``

    :param str post_id: The ID of the post to edit.
    """
    try:
        object_id = ObjectId(post_id)
    except InvalidId:
        return abort(404)
    try:
        post = BlogPost.objects().with_id(object_id)
    except (DoesNotExist, ValidationError):
        flash('Cannot find blog post with id {}.'.format(post_id), ERROR_FLASH)
        return redirect(url_for('.index'))

    if request.method == 'POST':
        form = CreateBlogPostForm(request.form)
        form.author.choices = [
            (str(u.id), u.name + " (You)" if u == g.user else u.name)
            for u in User.objects()]
        form.author.default = str(g.user.id)

        if form.validate_on_submit():
            post.title = form.title.data
            post.author = User.objects.get(id=ObjectId(form.author.data))
            post.slug = form.slug.data
            post.markdown_content = form.body.data
            post.images = [
                Image.objects().get(filename=fn) for fn in form.images.data
            ]

            post.post_tags = Tag.get_or_create_tags(form.tags.data)
            if form.featured_image.data:
                post.featured_image = Image.objects().get(
                    filename=form.featured_image.data)
            else:
                post.featured_image = None
            post.save()

            if post.published != form.published.data:
                if form.published.data:
                    post.publish()
                    flash('Blogpost published', MESSAGE_FLASH)
                else:
                    post.unpublish()
                    flash('Blogpost unpublished', MESSAGE_FLASH)

            if form.preview.data is True:
                return redirect(url_for('blog.preview', slug=post.slug))

    upload_form = UploadImageForm()
    feat_img = post.featured_image.filename if post.featured_image else None
    form = CreateBlogPostForm(request.form,
                              title=post.title,
                              slug=post.slug,
                              published=post.published,
                              body=post.markdown_content,
                              images=[image.filename for image in post.images],
                              author=str(post.author.id),
                              featured_image=feat_img, tags=post.post_tags)
    form.author.choices = [
        (str(u.id), u.name + " (You)" if u == g.user else u.name)
        for u in User.objects()
    ]
    form.author.default = str(g.user.id)
    images = [image for image in Image.objects() if image not in post.images]

    return render_template('eventum_posts/edit.html',
                           user=g.user,
                           form=form,
                           post=post,
                           images=images,
                           upload_form=upload_form)