diff --git a/reverse_image_search_bot/bot.py b/reverse_image_search_bot/bot.py index c799e6b..a4cdee3 100644 --- a/reverse_image_search_bot/bot.py +++ b/reverse_image_search_bot/bot.py @@ -3,9 +3,12 @@ import sys from threading import Thread -from telegram import Bot, TelegramError, Update -from telegram.ext import CallbackQueryHandler, CommandHandler, Filters, MessageHandler, Updater +from telegram import Bot, Update, ForceReply +from telegram.error import TelegramError +from telegram.ext import Application, CallbackQueryHandler, CommandHandler, filters, MessageHandler +from telegram.constants import MessageType +from queue import Queue from . import settings from .commands import best_match, callback_best_match, gif_image_search, group_image_reply_search, image_search_link, \ start, sticker_image_search, unknown @@ -14,55 +17,63 @@ logger = logging.getLogger(__name__) -def error(bot: Bot, update: Update, error: TelegramError): +def has_photo(update: Update) -> bool: + return update.message.photo is not None + + +def has_video_or_document(update: Update) -> bool: + return update.message.video is not None or update.message.document is not None + + +def error(application: Application, context, error: TelegramError): """Log all errors from the telegram bot api Args: - bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object. - update (:obj:`telegram.update.Update`): Telegram Api Update Object + application (:obj:`telegram.Application`): Telegram Api Application Object. + context (:obj:`telegram.ext.CallbackContext`): Telegram Api CallbackContext Object error (:obj:`telegram.error.TelegramError`): Telegram Api TelegramError Object """ - logger.warning('Update "%s" caused error "%s"' % (update, error)) + logger.warning('Update "%s" caused error "%s"' % (context.update, error)) def main(): - updater = Updater(settings.TELEGRAM_API_TOKEN) - dispatcher = updater.dispatcher + application = Application.builder().token(settings.TELEGRAM_API_TOKEN).build() def stop_and_restart(): - """Gracefully stop the Updater and replace the current process with a new one.""" - updater.stop() + """Gracefully stop the Application and replace the current process with a new one.""" + application.stop() os.execl(sys.executable, sys.executable, *sys.argv) - def restart(bot: Bot, update: Update): + def restart(update: Update, context): """Start the restarting process Args: - bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object. update (:obj:`telegram.update.Update`): Telegram Api Update Object + context (:obj:`telegram.ext.CallbackContext`): Telegram Api CallbackContext Object """ update.message.reply_text('Bot is restarting...') logger.info('Gracefully restarting...') Thread(target=stop_and_restart).start() - dispatcher.add_handler(CommandHandler("start", start)) - dispatcher.add_handler(CommandHandler("help", start)) - dispatcher.add_handler(CommandHandler('restart', restart, filters=Filters.user(username='@<>'))) - dispatcher.add_handler(CommandHandler('reply_search', group_image_reply_search)) - dispatcher.add_handler(CommandHandler('best_match', best_match, pass_args=True)) - dispatcher.add_handler(CallbackQueryHandler(callback_best_match)) + application.add_handler(CommandHandler("start", start)) + application.add_handler(CommandHandler("help", start)) + application.add_handler(CommandHandler('restart', restart, filters=filters.User(username='@<>'))) + application.add_handler(CommandHandler('reply_search', group_image_reply_search)) + application.add_handler(CommandHandler('best_match', best_match)) + application.add_handler(CallbackQueryHandler(callback_best_match)) - dispatcher.add_handler(MessageHandler(Filters.sticker, sticker_image_search)) - dispatcher.add_handler(MessageHandler(Filters.photo, image_search_link)) - dispatcher.add_handler(MessageHandler(Filters.video | Filters.document, gif_image_search)) - dispatcher.add_handler(MessageHandler(Filters.command, unknown)) + application.add_handler(MessageHandler(filters.PHOTO, image_search_link)) + application.add_handler(MessageHandler(filters.VIDEO, gif_image_search)) + application.add_handler(MessageHandler(filters.Document, gif_image_search)) + application.add_handler(MessageHandler(filters.Sticker, sticker_image_search)) + application.add_handler(MessageHandler(filters.COMMAND, unknown)) # log all errors - dispatcher.add_error_handler(error) + application.add_error_handler(error) - updater.start_polling() + application.run_polling() logger.info('Started bot. Waiting for requests...') - updater.idle() + application.idle() if __name__ == '__main__': diff --git a/reverse_image_search_bot/commands.py b/reverse_image_search_bot/commands.py index 87e6272..d2eb4d5 100644 --- a/reverse_image_search_bot/commands.py +++ b/reverse_image_search_bot/commands.py @@ -5,8 +5,11 @@ from PIL import Image from moviepy.video.io.VideoFileClip import VideoFileClip -from telegram import Bot, ChatAction, InlineKeyboardButton, InlineKeyboardMarkup, Update -from telegram.parsemode import ParseMode + +from telegram.constants import ParseMode +from telegram import Bot, InlineKeyboardButton, InlineKeyboardMarkup, Update +from telegram.constants import ChatAction +from telegram.ext import CallbackContext from reverse_image_search_bot.utils import dict_to_str from .image_search import BingReverseImageSearchEngine, \ @@ -14,12 +17,12 @@ TinEyeReverseImageSearchEngine, YandexReverseImageSearchEngine -def start(bot: Bot, update: Update): +async def start(update: Update, context: CallbackContext): """Send Start / Help message to client. Args: - bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object. update (:obj:`telegram.update.Update`): Telegram Api Update Object + context (:obj:`telegram.ext.CallbackContext`): Telegram Api Callback Context Object """ reply = """*ReVot - Reverse Image Search Bot (MS AZURE)* @@ -35,11 +38,15 @@ def start(bot: Bot, update: Update): (cosmos) """ - update.message.reply_text(reply, parse_mode=ParseMode.MARKDOWN) + await context.bot.send_message(chat_id=update.effective_chat.id, text=reply, parse_mode=ParseMode.MARKDOWN) current_dir = os.path.dirname(os.path.realpath(__file__)) image_dir = os.path.join(current_dir, 'images/example_usage.png') - bot.send_photo(update.message.chat_id, photo=open(image_dir, 'rb'), caption='Example Usage') + + if os.path.exists(image_dir): + await context.bot.send_photo(chat_id=update.effective_chat.id, photo=open(image_dir, 'rb'), caption='Example Usage') + else: + await context.bot.send_message(chat_id=update.effective_chat.id, text='Example image not found.') def group_image_reply_search(bot: Bot, update: Update): @@ -106,21 +113,29 @@ def sticker_image_search(bot: Bot, update: Update): general_image_search(bot, update, converted_image, 'png') -def image_search_link(bot: Bot, update: Update): +async def image_search_link(update: Update, context: CallbackContext): """Send a reverse image search link for the image he sent us to the client Args: - bot (:obj:`telegram.bot.Bot`): Telegram Api Bot Object. update (:obj:`telegram.update.Update`): Telegram Api Update Object + context (:obj:`telegram.ext.CallbackContext`): Telegram Api Callback Context Object """ - update.message.reply_text('Please wait for your results ...') - bot.send_chat_action(chat_id=update.message.chat_id, action=ChatAction.TYPING) + await context.bot.send_message(chat_id=update.effective_chat.id, text='Please wait for your results ...') - photo = bot.getFile(update.message.photo[-1].file_id) - with io.BytesIO() as image_buffer: - photo.download(out=image_buffer) - with io.BufferedReader(image_buffer) as image_file: - general_image_search(bot, update, image_file) + if update.effective_message.photo: + photo = update.effective_message.photo[-1] + elif update.effective_message.document: + photo = update.effective_message.document + else: + await context.bot.send_message(chat_id=update.effective_chat.id, text='No image found.') + return + + file = await photo.get_file() + image_buffer = io.BytesIO() + await file.download_to_memory(destination=image_buffer) + image_buffer.seek(0) + with io.BufferedReader(image_buffer) as image_file: + await general_image_search(context.bot, update, image_file) def general_image_search(bot: Bot, update: Update, image_file, image_extension: str=None): diff --git a/reverse_image_search_bot/settings.py b/reverse_image_search_bot/settings.py new file mode 100644 index 0000000..bcf9e74 --- /dev/null +++ b/reverse_image_search_bot/settings.py @@ -0,0 +1,9 @@ +TELEGRAM_API_TOKEN = '7737944585:AAE88ao4k3bmTkxb0hl4V0YfChtmujqx8rE' + +UPLOADER = { + 'uploader': 'reverse_image_search_bot.uploaders.file_system.FileSystemUploader', + 'url': 'myguest.virtualbox.org', + 'configuration': { + 'path': '/path/to/ReVot/', + } +}