def process_callback_query(self, user_id, chat_id, message_id, data):
        next_state = self
        command_array = data.split(" ")

        # only accept "/publish <draft/published>" callback queries
        if len(command_array) == 2 and command_array[0] == "/publish" and command_array[1] in [state.value for state in PostState]:

            publish_type = command_array[1]

            # check if previously selected post still exists
            post = self.bot.persistence.get_post(self.post_id)
            if post is not None:

                is_published = self.bot.publish(post.id, PostState(publish_type))

                # publishing successful
                if is_published:
                    self.bot.edit_message_text(chat_id, message_id
                                               , "<b>" + post.title + "</b> has been <b>published</b> as <b>"
                                               + ("draft" if publish_type == PostState.DRAFT.value else "final post") + "</b>."
                                               , parse_mode=ParseMode.HTML.value)

                    # if published as post -> go back to main menu
                    if publish_type == PostState.PUBLISHED.value:
                        from packages.states.navigation.idlestate import IdleState
                        next_state = IdleState(self.bot, user_id, chat_id=chat_id)
                    else:
                        next_state = SelectDraftUpdateState(self.bot, user_id, post.id, chat_id=chat_id)

                # publishing not successful
                else:
                    self.bot.edit_message_text(chat_id, self.message_id
                                               , "It seems publishing is not possible..."
                                               , parse_mode=ParseMode.HTML.value)
                    next_state = PublishDraftState(self.bot, user_id, post.id, chat_id=chat_id)

            # previously selected post no longer exists
            else:
                self.bot.send_message(chat_id
                                      , "It seems the draft you selected no longer exists..."
                                      , parse_mode=ParseMode.HTML.value)

                # show remaining drafts for updating
                user_drafts = self.bot.persistence.get_posts(user_id=user_id, status=PostState.DRAFT)
                if len(user_drafts) > 0:
                    from packages.states.draft.updatedraftstate import UpdateDraftState
                    next_state = UpdateDraftState(self.bot, user_id, chat_id=chat_id)
                # no remaining drafts -> automatically go back to main menu
                else:
                    from packages.states.navigation.idlestate import IdleState
                    next_state = IdleState(self.bot, user_id, chat_id=chat_id)

        else:
            next_state = super().process_callback_query(user_id, chat_id, message_id, data)

        return next_state
    def process_callback_query(self, user_id, chat_id, message_id, data):
        next_state = self
        command_array = data.split(" ")

        # only accept "/deleteposttag <tag_id>" callback queries
        if len(command_array) == 2 and command_array[0] == "/deleteposttag":

            tag_id = command_array[1]

            # check if previously selected post still exists
            post = self.bot.persistence.get_post(self.post_id)
            if post is not None:

                deleted_tag = self.bot.persistence.delete_post_tag(post.id, tag_id)

                # tag removal successful
                if deleted_tag is not None:
                    self.bot.edit_message_text(chat_id, message_id
                                               , "Tag <b>" + deleted_tag.name + "</b> has been <b>deleted</b> from draft <b>" + post.title + "</b>."
                                               , parse_mode=ParseMode.HTML.value)
                # tag removal not successful
                else:
                    self.bot.edit_message_text(chat_id, self.message_id
                                               , "It seems the tag you selected no longer exists..."
                                               , parse_mode=ParseMode.HTML.value)

                # show remaining tags for deletion
                if len(post.tags) - (1 if deleted_tag is not None else 0) > 0:
                    next_state = DeleteTagState(self.bot, user_id, post.id, chat_id=chat_id)
                # no remaining tags -> automatically go back to update option menu
                else:
                    next_state = SelectDraftUpdateState(self.bot, user_id, post.id, chat_id=chat_id)

            # previously selected post no longer exists
            else:
                self.bot.send_message(chat_id
                                      , "It seems the draft you selected no longer exists..."
                                      , parse_mode=ParseMode.HTML.value)

                # show remaining drafts for updating
                user_drafts = self.bot.persistence.get_posts(user_id=user_id, status=PostState.DRAFT)
                if len(user_drafts) > 0:
                    from packages.states.draft.updatedraftstate import DeleteDraftState
                    next_state = DeleteDraftState(self.bot, user_id, chat_id=chat_id)
                # no remaining drafts -> automatically go back to main menu
                else:
                    from packages.states.navigation.idlestate import IdleState
                    next_state = IdleState(self.bot, user_id, chat_id=chat_id)

        else:
            next_state = super().process_callback_query(user_id, chat_id, message_id, data)

        return next_state
    def test_user(self):
        user_id = 1
        user_state = IdleState(None, user_id)
        user_name = "user1"
        user = self.db.add_user(user_id, user_state, name=user_name)
        users = self.db.get_users()
        updated_user = self.db.update_user(user_id, user_state, name="updated_user")

        self.assertTrue(len(users) == 1)
        self.assertTrue(user in users)
        self.assertTrue(self.db.get_user(user_id) == updated_user)
        self.assertEqual(self.db.delete_user(user_id), updated_user)
    def process_callback_query(self, user_id, chat_id, message_id, data):
        next_state = self
        command_array = data.split(" ")

        # only accept "/confirmdraftdeletion <confirm/back>" callback queries
        if len(command_array
               ) == 2 and command_array[0] == "/confirmdraftdeletion":

            # confirmed draft deletion
            if command_array[1] == "/confirm":

                deleted_post = self.bot.persistence.delete_post(
                    self.post_id) if self.bot.unpublish(self.post_id) else None

                # post removal successful
                if deleted_post is not None:
                    self.bot.edit_message_text(chat_id,
                                               message_id,
                                               "Draft <b>" +
                                               deleted_post.title +
                                               "</b> has been <b>deleted</b>.",
                                               parse_mode=ParseMode.HTML.value)
                # post removal not successful
                else:
                    self.bot.edit_message_text(
                        chat_id,
                        self.message_id,
                        "It seems the draft you selected no longer exists...",
                        parse_mode=ParseMode.HTML.value)

                # show remaining drafts for deletion
                user_drafts = self.bot.persistence.get_posts(
                    user_id=user_id, status=PostState.DRAFT)
                if len(user_drafts) > 0:
                    from packages.states.draft.deletedraftstate import DeleteDraftState
                    next_state = DeleteDraftState(self.bot,
                                                  user_id,
                                                  chat_id=chat_id)
                # no remaining drafts -> automatically go back to main menu
                else:
                    from packages.states.navigation.idlestate import IdleState
                    next_state = IdleState(self.bot, user_id, chat_id=chat_id)

        else:
            next_state = super().process_callback_query(
                user_id, chat_id, message_id, data)

        return next_state
    def process_message(self, user_id, chat_id, text, entities):
        next_state = self
        text = text.strip(' \t\n\r')

        # let super() handle any bot commands
        if text.startswith("/") or "bot_command" in [
                entity["type"] for entity in entities
        ]:
            next_state = super().process_message(user_id, chat_id, text,
                                                 entities)

        # accept simple text as post title
        else:
            # remove inline keyboard from latest bot message (by leaving out reply_options parameter)
            self.build_state_message(chat_id,
                                     self.welcome_message,
                                     message_id=self.message_id)

            # try to create new draft
            post = self.bot.persistence.add_post(user_id, text,
                                                 PostState.DRAFT,
                                                 "Bildergalerie", "")

            # post creation was successful -> show post update options
            if post is not None:
                self.bot.send_message(chat_id,
                                      "Draft <b>" + text +
                                      "</b> has been <b>created</b>.",
                                      parse_mode=ParseMode.HTML.value)
                from packages.states.navigation.selectdraftupdatestate import SelectDraftUpdateState
                next_state = SelectDraftUpdateState(self.bot,
                                                    user_id,
                                                    post.id,
                                                    chat_id=chat_id)

            # post creation failed -> back to main menu
            else:
                self.bot.send_message(
                    chat_id,
                    "New draft could not be created. Returning to main menu.",
                    parse_mode=ParseMode.HTML.value)
                next_state = IdleState(self.bot, user_id, chat_id=chat_id)

        return next_state
    def process_callback_query(self, user_id, chat_id, message_id, data):
        next_state = self
        command_array = data.split(" ")

        # only accept "/confirmpostdeletion <confirm/back>" callback queries
        if len(command_array) == 2 and command_array[0] == "/confirmpostdeletion":

            # confirmed post deletion
            if command_array[1] == "/confirm":

                deleted_post = self.bot.persistence.delete_post(self.post_id) if self.bot.unpublish(self.post_id) else None
                original_post_id = None if deleted_post.original_post is None else deleted_post.original_post.id

                # delete all predecessor posts
                while original_post_id:
                    original_post = self.bot.persistence.delete_post(original_post_id)
                    original_post_id = None if not (original_post and original_post.original_post) else original_post.original_post.id

                # post removal successful
                if deleted_post is not None:
                    self.bot.edit_message_text(chat_id, message_id
                                               , "Post <b>" + deleted_post.title + "</b> has been <b>deleted</b>."
                                               , parse_mode=ParseMode.HTML.value)
                # post removal not successful
                else:
                    self.bot.edit_message_text(chat_id, self.message_id
                                               , "It seems the post you selected no longer exists..."
                                               , parse_mode=ParseMode.HTML.value)

                # show remaining posts for deletion
                user_posts = self.bot.persistence.get_posts(user_id=user_id, status=PostState.PUBLISHED)
                if len([post for post in user_posts if post.status == PostState.PUBLISHED]) \
                        > len([draft for draft in user_posts if draft.status == PostState.DRAFT and draft.original_post is not None]):
                    from packages.states.post.deletepoststate import DeletePostState
                    next_state = DeletePostState(self.bot, user_id, chat_id=chat_id)
                # no remaining posts -> automatically go back to main menu
                else:
                    from packages.states.navigation.idlestate import IdleState
                    next_state = IdleState(self.bot, user_id, chat_id=chat_id)

        else:
            next_state = super().process_callback_query(user_id, chat_id, message_id, data)

        return next_state
Exemple #7
0
    def process_message(self, user_id, chat_id, text, entities):
        next_state = self
        text = text.strip(' \t\n\r')

        # let super() handle any bot commands
        if text.startswith("/") or "bot_command" in [
                entity["type"] for entity in entities
        ]:
            next_state = super().process_message(user_id, chat_id, text,
                                                 entities)

        # accept simple text as tag list
        else:
            # remove inline keyboard from latest bot message (by leaving out reply_options parameter)
            self.build_state_message(chat_id,
                                     self.welcome_message,
                                     message_id=self.message_id)

            # check if previously selected post still exists
            post = self.bot.persistence.get_post(self.post_id)
            if post is not None:

                new_tags = []
                for new_tag_name in [
                        x.strip(' \t\n\r')
                        for x in re.split("[,\t\n\r]", text)
                ]:

                    # ignore "empty" tags
                    if len(new_tag_name) == 0:
                        continue

                    tag = self.bot.persistence.add_post_tag(
                        post.id, new_tag_name)
                    if tag is not None:
                        new_tags.append(tag.name)

                if len(new_tags) > 0:
                    self.bot.send_message(chat_id,
                                          "Tag(s) <b>" + ", ".join(new_tags) +
                                          "</b> have been added to draft <b>" +
                                          post.title + "</b>.",
                                          parse_mode=ParseMode.HTML.value)
                else:
                    self.bot.send_message(
                        chat_id,
                        "<b>No tags(s) added</b>. All specified tag(s) were already assigned to draft <b>"
                        + post.title + "</b>.",
                        parse_mode=ParseMode.HTML.value)

                next_state = AddTagState(self.bot,
                                         user_id,
                                         self.post_id,
                                         chat_id=chat_id)

            # previously selected post no longer exists
            else:
                self.bot.send_message(
                    chat_id,
                    "It seems the draft you selected no longer exists...",
                    parse_mode=ParseMode.HTML.value)

                # show remaining drafts for updating
                user_drafts = self.bot.persistence.get_posts(
                    user_id=user_id, status=PostState.DRAFT)
                if len(user_drafts) > 0:
                    from packages.states.draft.updatedraftstate import UpdateDraftState
                    next_state = UpdateDraftState(self.bot,
                                                  user_id,
                                                  chat_id=chat_id)
                # no remaining drafts -> automatically go back to main menu
                else:
                    from packages.states.navigation.idlestate import IdleState
                    next_state = IdleState(self.bot, user_id, chat_id=chat_id)

        return next_state
    def process_callback_query(self, user_id, chat_id, message_id, data):
        next_state = self
        command_array = data.split(" ")

        # only accept "/deletepostimage <image_id>" callback queries
        if len(command_array) == 2 and command_array[0] == "/deletepostimage":

            image_id = command_array[1]

            # check if previously selected post still exists
            post = self.bot.persistence.get_post(self.post_id)
            if post is not None:

                deleted_image = self.bot.persistence.delete_post_image(
                    post.id, image_id)

                # image removal successful
                if deleted_image is not None:
                    self.bot.edit_message_text(
                        chat_id,
                        message_id,
                        "Image <b>" + deleted_image.name +
                        "</b> has been <b>deleted</b> from draft <b>" +
                        post.title + "</b>.",
                        parse_mode=ParseMode.HTML.value)
                # image removal not successful
                else:
                    self.bot.edit_message_text(
                        chat_id,
                        self.message_id,
                        "It seems the image you selected no longer exists...",
                        parse_mode=ParseMode.HTML.value)

                # show remaining images for deletion
                post_images = post.gallery.images + (
                    [post.title_image] if post.title_image is not None else [])
                if len(post_images) - (1 if deleted_image is not None else
                                       0) > 0:
                    next_state = DeleteImageState(self.bot,
                                                  user_id,
                                                  post.id,
                                                  chat_id=chat_id)
                # no remaining images -> automatically go back to update option menu
                else:
                    next_state = SelectDraftUpdateState(self.bot,
                                                        user_id,
                                                        self.post_id,
                                                        chat_id=chat_id)

            # previously selected post no longer exists
            else:
                self.bot.send_message(
                    chat_id,
                    "It seems the draft you selected no longer exists...",
                    parse_mode=ParseMode.HTML.value)

                # show remaining drafts for updating
                user_drafts = self.bot.persistence.get_posts(
                    user_id=user_id, status=PostState.DRAFT)
                if len(user_drafts) > 0:
                    from packages.states.draft.updatedraftstate import DeleteDraftState
                    next_state = DeleteDraftState(self.bot,
                                                  user_id,
                                                  chat_id=chat_id)
                # no remaining drafts -> automatically go back to main menu
                else:
                    from packages.states.navigation.idlestate import IdleState
                    next_state = IdleState(self.bot, user_id, chat_id=chat_id)

        # only accept "/previewpostimage <image_id>" callback queries
        elif len(command_array
                 ) == 2 and command_array[0] == "/previewpostimage":

            image_id = command_array[1]

            # remove inline keyboard from latest bot message (by leaving out reply_options parameter)
            self.build_state_message(chat_id,
                                     self.welcome_message,
                                     message_id=self.message_id)

            # check if previously selected post still exists
            post = self.bot.persistence.get_post(self.post_id)
            if post is not None:

                preview_image = None
                for image in post.gallery.images + ([
                        post.title_image
                ] if post.title_image is not None else []):
                    # ignore "wrong" images
                    if str(image.id) != str(image_id):
                        continue
                    else:
                        preview_image = image

                # image found -> preview
                if image is not None:
                    self.bot.send_photo(
                        chat_id,
                        image.thumb_id if image.thumb_id else image.file_id,
                        caption=image.caption)
                # image not found
                else:
                    self.bot.edit_message_text(
                        chat_id,
                        self.message_id,
                        "It seems the image you selected no longer exists...",
                        parse_mode=ParseMode.HTML.value)

                next_state = DeleteImageState(self.bot,
                                              user_id,
                                              self.post_id,
                                              chat_id=chat_id)

            # previously selected post no longer exists
            else:
                self.bot.send_message(
                    chat_id,
                    "It seems the draft you selected no longer exists...",
                    parse_mode=ParseMode.HTML.value)

                # show remaining drafts for updating
                user_drafts = self.bot.persistence.get_posts(
                    user_id=user_id, status=PostState.DRAFT)
                if len(user_drafts) > 0:
                    from packages.states.draft.updatedraftstate import DeleteDraftState
                    next_state = DeleteDraftState(self.bot,
                                                  user_id,
                                                  chat_id=chat_id)
                # no remaining drafts -> automatically go back to main menu
                else:
                    from packages.states.navigation.idlestate import IdleState
                    next_state = IdleState(self.bot, user_id, chat_id=chat_id)
        else:
            next_state = super().process_callback_query(
                user_id, chat_id, message_id, data)

        return next_state
Exemple #9
0
    def process_message(self, user_id, chat_id, text, entities):
        next_state = self
        text = text.strip(' \t\n\r')

        # let super() handle any bot commands
        if text.startswith("/") or "bot_command" in [
                entity["type"] for entity in entities
        ]:
            next_state = super().process_message(user_id, chat_id, text,
                                                 entities)

        # accept simple text as new post title
        else:
            # remove inline keyboard from latest bot message (by leaving out reply_options parameter)
            self.build_state_message(chat_id,
                                     self.welcome_message,
                                     message_id=self.message_id)

            # check if previously selected post still exists
            post = self.bot.persistence.get_post(self.post_id)
            if post is not None:
                new_title = text

                updated_post = self.bot.persistence.update_post(
                    post.id, post.user.id, new_title, post.status,
                    post.gallery.title, post.content,
                    None if post.title_image is None else post.title_image.id,
                    post.tmsp_publish, None
                    if post.original_post is None else post.original_post.id)

                # post update successful
                if updated_post is not None:
                    self.bot.send_message(
                        chat_id,
                        "Draft title has been updated to <b>" +
                        updated_post.title + "</b>.",
                        parse_mode=ParseMode.HTML.value)
                # post update not successful
                else:
                    self.bot.send_message(chat_id,
                                          "Draft title could not be updated.",
                                          parse_mode=ParseMode.HTML.value)

                next_state = SelectDraftUpdateState(self.bot,
                                                    user_id,
                                                    self.post_id,
                                                    chat_id=chat_id)

            # previously selected post no longer exists
            else:
                self.bot.send_message(
                    chat_id,
                    "It seems the draft you selected no longer exists...",
                    parse_mode=ParseMode.HTML.value)

                # show remaining drafts for updating
                user_drafts = self.bot.persistence.get_posts(
                    user_id=user_id, status=PostState.DRAFT)
                if len(user_drafts) > 0:
                    from packages.states.draft.updatedraftstate import UpdateDraftState
                    next_state = UpdateDraftState(self.bot,
                                                  user_id,
                                                  chat_id=chat_id)
                # no remaining drafts -> automatically go back to main menu
                else:
                    from packages.states.navigation.idlestate import IdleState
                    next_state = IdleState(self.bot, user_id, chat_id=chat_id)

        return next_state
    def process_callback_query(self, user_id, chat_id, message_id, data):
        next_state = self
        command_array = data.split(" ")

        # only accept "/previewcontent" callback queries
        if len(command_array) == 1 and command_array[0] == "/previewcontent":

            # check if previously selected post still exists
            post = self.bot.persistence.get_post(self.post_id)
            if post is not None:

                # replace edit instructions with current draft content
                self.bot.edit_message_text(chat_id, self.message_id, post.content)

                next_state = EditDraftContentState(self.bot, user_id, post.id, chat_id=chat_id)

            # previously selected post no longer exists
            else:
                self.bot.send_message(chat_id
                                      , "It seems the draft you selected no longer exists..."
                                      , parse_mode=ParseMode.HTML.value)

                # show remaining drafts for updating
                user_drafts = self.bot.persistence.get_posts(user_id=user_id, status=PostState.DRAFT)
                if len(user_drafts) > 0:
                    from packages.states.draft.updatedraftstate import UpdateDraftState
                    next_state = UpdateDraftState(self.bot, user_id, chat_id=chat_id)
                # no remaining drafts -> automatically go back to main menu
                else:
                    from packages.states.navigation.idlestate import IdleState
                    next_state = IdleState(self.bot, user_id, chat_id=chat_id)

        # only accept "/formatting" callback queries
        elif len(command_array) == 1 and command_array[0] == "/formatting":

            # check if previously selected post still exists
            post = self.bot.persistence.get_post(self.post_id)
            if post is not None:

                message = "Following <b>Markdown</b> options are supported:\r\n\r\n" \
                    + "Heading 1-6: #..# text\r\n" \
                    + "Bold text: <b>**text**</b>\r\n" \
                    + "Italic text: <i>*text*</i>\r\n" \
                    + "Web link: [text](http://www.example.com/)\r\n" \
                    + "Inline code: <code>`some code`</code>\r\n" \
                    + "Pre-formatted code block <pre>```some code```</pre>"

                # replace edit instructions with Markdown formatting options
                self.bot.edit_message_text(chat_id, self.message_id, message, parse_mode=ParseMode.HTML.value)

                next_state = EditDraftContentState(self.bot, user_id, post.id, chat_id=chat_id)

            # previously selected post no longer exists
            else:
                self.bot.send_message(chat_id
                                      , "It seems the draft you selected no longer exists..."
                                      , parse_mode=ParseMode.HTML.value)

                # show remaining drafts for updating
                user_drafts = self.bot.persistence.get_posts(user_id=user_id, status=PostState.DRAFT)
                if len(user_drafts) > 0:
                    from packages.states.draft.updatedraftstate import UpdateDraftState
                    next_state = UpdateDraftState(self.bot, user_id, chat_id=chat_id)
                # no remaining drafts -> automatically go back to main menu
                else:
                    from packages.states.navigation.idlestate import IdleState
                    next_state = IdleState(self.bot, user_id, chat_id=chat_id)

        else:
            next_state = super().process_callback_query(user_id, chat_id, message_id, data)

        return next_state
Exemple #11
0
    def process_photo_message(self,
                              user_id,
                              chat_id,
                              file_id,
                              thumb_id=None,
                              caption=None):
        next_state = self

        # remove inline keyboard from latest bot message (by leaving out reply_options parameter)
        self.build_state_message(chat_id,
                                 self.welcome_message,
                                 message_id=self.message_id)

        # check if previously selected post still exists
        post = self.bot.persistence.get_post(self.post_id)
        if post is not None:

            image = None
            # TODO move this code to bot? -> file = self.context.download_file(file_id)
            telegram_file = self.bot.get_file(file_id)
            if "result" in telegram_file and "file_path" in telegram_file[
                    "result"]:
                file_url = telegram_file["result"]["file_path"]
                file = self.bot.download_file(file_url)

                if file is not None:
                    file_name = str(self.message_id) + "." + file_url.rsplit(
                        ".", 1)[1]
                    image = self.bot.persistence.add_post_image(
                        post.id,
                        file_id,
                        file_name,
                        file,
                        thumb_id=thumb_id,
                        caption=caption)

            if image is not None:
                self.bot.send_message(
                    chat_id,
                    "Image <b>" + image.name +
                    "</b> has been <b>added</b> to draft <b>" + post.title +
                    "</b>.",
                    parse_mode=ParseMode.HTML.value)
            else:
                self.bot.send_message(chat_id,
                                      "<b>Image not added</b> to draft <b>" +
                                      post.title + "</b>.",
                                      parse_mode=ParseMode.HTML.value)

            next_state = AddImageState(self.bot,
                                       user_id,
                                       post.id,
                                       chat_id=chat_id)

        # previously selected post no longer exists
        else:
            self.bot.send_message(
                chat_id,
                "It seems the draft you selected no longer exists...",
                parse_mode=ParseMode.HTML.value)

            # show remaining drafts for updating
            user_drafts = self.bot.get_user_posts(user_id=user_id,
                                                  status=PostState.DRAFT)
            if len(user_drafts) > 0:
                from packages.states.draft.updatedraftstate import UpdateDraftState
                next_state = UpdateDraftState(self.bot,
                                              user_id,
                                              chat_id=chat_id)
            # no remaining drafts -> automatically go back to main menu
            else:
                from packages.states.navigation.idlestate import IdleState
                next_state = IdleState(self.bot, user_id, chat_id=chat_id)

        return next_state
    def process_callback_query(self, user_id, chat_id, message_id, data):
        next_state = self
        command_array = data.split(" ")

        # only accept "/confirmpostupdate <confirm/back>" callback queries
        if len(command_array
               ) == 2 and command_array[0] == "/confirmpostupdate":

            # confirmed post update
            if command_array[1] == "/confirm":

                # check if previously selected post still exists
                post = self.bot.persistence.get_post(self.post_id)
                if post is not None:

                    new_draft = self.bot.persistence.copy_post(self.post_id)

                    # draft creation successful
                    if new_draft is not None:
                        self.bot.edit_message_text(
                            chat_id,
                            message_id,
                            "New draft for modification of post <b>" +
                            new_draft.title + "</b> has been <b>created</b>.",
                            parse_mode=ParseMode.HTML.value)

                        # show update options for newly created draft
                        from packages.states.navigation.selectdraftupdatestate import SelectDraftUpdateState
                        next_state = SelectDraftUpdateState(self.bot,
                                                            user_id,
                                                            new_draft.id,
                                                            chat_id=chat_id)

                    # draft creation not successful
                    else:
                        self.bot.edit_message_text(
                            chat_id,
                            self.message_id,
                            "It seems the post you selected cannot be updated...",
                            parse_mode=ParseMode.HTML.value)

                        # show remaining posts for updating
                        user_posts = self.bot.persistence.get_posts(
                            user_id=user_id, status=PostState.PUBLISHED)
                        if len([post for post in user_posts if post.status == PostState.PUBLISHED]) \
                                > len([draft for draft in user_posts if draft.status == PostState.DRAFT and draft.original_post is not None]):
                            from packages.states.post.updatepoststate import UpdatePostState
                            next_state = UpdatePostState(self.bot,
                                                         user_id,
                                                         chat_id=chat_id)
                        # no remaining posts -> automatically go back to main menu
                        else:
                            from packages.states.navigation.idlestate import IdleState
                            next_state = IdleState(self.bot,
                                                   user_id,
                                                   chat_id=chat_id)

        else:
            next_state = super().process_callback_query(
                user_id, chat_id, message_id, data)

        return next_state