""" Created by Gotham on 03-08-2018. """ from telegram import InlineKeyboardButton, InlineKeyboardMarkup, ReplyKeyboardMarkup, ReplyKeyboardRemove, ForceReply from telegram.ext import ConversationHandler, CommandHandler, MessageHandler, Filters, CallbackQueryHandler import flood_protection from helper import HackerRankAPI from utility import Utility import os timeouts = flood_protection.Spam_settings() LANG, OTHER, CODE, DECODE, FILE, TESTCASES, FILETEST = range(4000, 4007) class ComHandler: def __init__(self, api_key, fallback): self.compiler = HackerRankAPI(api_key=api_key) self.conv_handler = ConversationHandler( entry_points=[CommandHandler('compiler', self.compilers)], allow_reentry=True, states={ LANG: [CallbackQueryHandler(self.lang, pass_user_data=True, pattern=r'\w*comp1\b')], CODE: [CallbackQueryHandler(self.code, pass_user_data=True, pattern=r'\w*so1\b')], DECODE: [MessageHandler(Filters.text, self.decode, pass_user_data=True)], TESTCASES: [MessageHandler(Filters.text, self.testcases, pass_user_data=True)], OTHER: [MessageHandler(Filters.text, self.other, pass_user_data=True)], FILE: [MessageHandler(Filters.document, self.filer, pass_user_data=True)], FILETEST: [MessageHandler(Filters.document, self.filetest, pass_user_data=True)] }, fallbacks=[fallback] ) @staticmethod @timeouts.wrapper def compilers(bot, update): keyboard = [[InlineKeyboardButton("C++", callback_data='cppcomp1'), InlineKeyboardButton("Python", callback_data='pythoncomp1')], [InlineKeyboardButton("C", callback_data='ccomp1'), InlineKeyboardButton("Java", callback_data='javacomp1')], [InlineKeyboardButton("Python3", callback_data='python3comp1'), InlineKeyboardButton("Java8", callback_data='java8comp1')], [InlineKeyboardButton("Other", callback_data='othercomp1')]] reply_markup = InlineKeyboardMarkup(keyboard) update.message.reply_text('Please select the language', reply_markup=reply_markup) return LANG # FUNCTION TO GET THE PROGRAMMING LANGUAGE def lang(self, bot, update, user_data): query = update.callback_query val = query.data val = str(val).replace("comp1", "") if val == "other": # IF USER CHOOSES OTHER s1 = "" for language in self.compiler.supportedlanguages(): s1 = s1 + language + ", " bot.edit_message_text(text="" + s1[:-2], chat_id=query.message.chat_id, message_id=query.message.message_id) bot.send_message(chat_id=query.message.chat_id, text="Enter the name of a language from the above list", reply_markup=ForceReply(True)) return OTHER else: # ELSE ASKING WETHER HE WANTS TO SEND SOURCE CODE OR A .TXT FILE user_data['lang'] = val keyboard = [[InlineKeyboardButton("Enter Source Code", callback_data='codeso1'), InlineKeyboardButton("Send a .txt file", callback_data='fileso1')]] reply_markup = InlineKeyboardMarkup(keyboard) bot.edit_message_text(text="please select", reply_markup=reply_markup, chat_id=query.message.chat_id, message_id=query.message.message_id) return CODE # FUNCTION TO GET THE SOURCE CODE OR .TXT FILE AS INPUT @staticmethod def code(bot, update, user_data): query = update.callback_query val = query.data val = str(val).replace("so1", "") if val == "code": bot.edit_message_text( text="selected", chat_id=query.message.chat_id, message_id=query.message.message_id) bot.send_message(chat_id=query.message.chat_id, text="please enter your code\n" "Please make sure that " "the first line is not a comment line", reply_markup=ForceReply(True)) return DECODE elif val == "file": bot.edit_message_text(text="please send your .txt file\nMaximum size 2mb", chat_id=query.message.chat_id, message_id=query.message.message_id) return FILE else: return ConversationHandler.END # FUNCTION TO GET TESTCASE FILE def filetest(self, bot, update, user_data): file_id = update.message.document.file_id if ComHandler.check_file_size(update): return ConversationHandler.END newFile = bot.get_file(file_id) newFile.download('test.txt') with open('test.txt', 'rt') as f: source = f.read() s1 = (str(user_data['code'])).replace("«", "<<").replace("»", ">>") result = self.compiler.run({'source': s1, 'lang': user_data['lang'], 'testcases': [source] }) Utility.paginate(bot, update, result) user_data.clear() os.remove('test.txt') return ConversationHandler.END @staticmethod def check_file_size(update): file_size = update.message.document.file_size if file_size > 2097152: update.message.reply_text("FILE SIZE GREATER THAN 2 MB") return True return False # FUNCTION TO DOWNLOAD THE FILE SENT AND EXTRACT ITS CONTENTS @staticmethod def filer(bot, update, user_data): file_id = update.message.document.file_id if ComHandler.check_file_size(update): return ConversationHandler.END newFile = bot.get_file(file_id) newFile.download('abcd.txt') with open('abcd.txt', 'r') as f: source = f.read() user_data['code'] = source custom_keyboard = [['#no test case', '#send a .txt file']] reply_markup = ReplyKeyboardMarkup(custom_keyboard, one_time_keyboard=True, resize_keybord=True) update.message.reply_text( 'Please send test cases together as you would do in online ide\nIf you dont want to provide test cases select #no test case\n I you want to send test cases as .txt file select #send a .txt file', reply_markup=reply_markup) # REMOVING THE FILE AFTER PROCESS IS COMPLETE os.remove('abcd.txt') return TESTCASES # FUNCTION TO GET THE SOURCE CODE SENT BY USER @staticmethod def decode(bot, update, user_data): user_data['code'] = update.message.text custom_keyboard = [['#no test case', '#send a .txt file']] reply_markup = ReplyKeyboardMarkup(custom_keyboard, one_time_keyboard=True, resize_keybord=True) update.message.reply_text( 'Please send test cases together as you would do in online ide\nIf you dont want to provide test cases select #no test case\n I you want to send test cases as .txt file select #send a .txt file', reply_markup=reply_markup) return TESTCASES # FUNCTION TO GET THE TEST CASES FROM THE USER def testcases(self, bot, update, user_data): markup = ReplyKeyboardRemove() s = update.message.text if s == "#send a .txt file": update.message.reply_text("Please send your testcases as a .txt file\nMaximum size 2mb", reply_markup=markup) return FILETEST # CONVERTING UNICODE CHARACTER TO DOUBLE GREATER THAN OR LESS THAN # WEIRD s1 = (str(user_data['code'])).replace("«", "<<").replace("»", ">>") if s == "#no test case": # USING COMPILER FUNCTION FROM helper.py script result = self.compiler.run({'source': s1, 'lang': user_data['lang'] }) # GETTING OUTPUT FROM result CLASS in helper.py script Utility.paginate(bot, update, result) else: # AGAIN THE SAME DRILL result = self.compiler.run({'source': s1, 'lang': user_data['lang'], 'testcases': [s] }) Utility.paginate(bot, update, result) user_data.clear() return ConversationHandler.END # FUNCTION FOR THE CASE WHERE USER HAD SELECTED OTHER @staticmethod def other(bot, update, user_data): s = update.message.text user_data['lang'] = s keyboard = [[InlineKeyboardButton("Enter Source Code", callback_data='codeso1'), InlineKeyboardButton("Send a file", callback_data='fileso1')]] reply_markup = InlineKeyboardMarkup(keyboard) update.message.reply_text("please select", reply_markup=reply_markup) return CODE