From 50c1c7ebe5089c4e0d95ccf03e08ee72bdeddaa0 Mon Sep 17 00:00:00 2001 From: satanas Date: Tue, 12 Nov 2019 00:52:54 -0800 Subject: [PATCH] Updating all handlers except turns.py --- character.py | 283 -------------------------- commands.py | 17 +- database.py | 2 +- exceptions.py | 3 + campaign.py => handlers/campaign.py | 12 +- handlers/character.py | 231 +++++++++++++++++++++ charsheet.py => handlers/charsheet.py | 2 +- dm.py => handlers/dm.py | 0 roll.py => handlers/roll.py | 6 +- turns.py => handlers/turns.py | 0 help.py | 6 +- main.py | 14 +- serverless.yml | 1 + tests/test_character.py | 2 +- tests/test_roll.py | 2 +- 15 files changed, 264 insertions(+), 317 deletions(-) delete mode 100644 character.py rename campaign.py => handlers/campaign.py (76%) create mode 100644 handlers/character.py rename charsheet.py => handlers/charsheet.py (95%) rename dm.py => handlers/dm.py (100%) rename roll.py => handlers/roll.py (91%) rename turns.py => handlers/turns.py (100%) diff --git a/character.py b/character.py deleted file mode 100644 index a068b41..0000000 --- a/character.py +++ /dev/null @@ -1,283 +0,0 @@ -import sys -import requests -from urllib.parse import urlparse - -from roll import roll -from database import Database -from models.character import Character - -CLOSE_COMBAT_DISTANCE = 5 # feet - -SIZE_MODIFIER = { - 'Colossal': -8, - 'Small': 1, - 'Gargantuan': -4, - 'Tiny': 2, - 'Huge': -2, - 'Diminutive': 4, - 'Large': -1, - 'Fine': 8, - 'Medium': 0 -} - -def handler(bot, update): - db = Database() - chat_id = update.message.chat.id - text = update.message.text.replace(f'@{bot.get_me().username}', '').strip() - username = update.message.from_user.username if update.message.from_user.username else update.message.from_user.first_name - - if text.startswith('/import_char'): - response = import_character(text, db, requests.get) - if text.startswith('/link_char'): - response = link_character(text, db, chat_id, username) - elif text.startswith('/attack_roll'): - response = attack_roll(username, text, db) - elif text.startswith('/initiative_roll'): - response = initiative_roll(username, text, db) - elif text.startswith('/short_rest_roll'): - response = short_rest_roll(text, db, chat_id, username) - elif text.startswith('/weapons'): - response = get_weapons(text,db) - elif text.startswith('/status'): - response = get_status(text, db, chat_id, username) - elif text.startswith('/talk'): - response = talk(text) - bot.delete_message(chat_id=update.message.chat_id, message_id=update.message.message_id) - elif text.startswith('/say'): - response = chat(text, 'say') - bot.delete_message(chat_id=update.message.chat_id, message_id=update.message.message_id) - elif text.startswith('/yell'): - response = chat(text, 'yell') - bot.delete_message(chat_id=update.message.chat_id, message_id=update.message.message_id) - elif text.startswith('/whisper'): - response = chat(text, 'whisper') - bot.delete_message(chat_id=update.message.chat_id, message_id=update.message.message_id) - else: - response = "Invalid command" - - bot.send_message(chat_id=update.message.chat_id, text=response, parse_mode="Markdown") - -def talk(text): - command = text.replace('/talk', '').strip() - sep = command.find(" ") - character_name = command[:sep] - message = command[sep + 1:] - response = f"```\r\n{character_name} says:\r\n–{message}\r\n```" - - return response - -def chat(text, tone): - command = text.replace('/'+tone, '').strip() - sep = command.find(" ") - character_name = command[:sep] - message = command[sep + 1:] - if tone == 'yell': - message = message.upper() - elif tone == 'whisper': - message = f"__{message}__" - response = f"```\r\n{character_name} says:```\r\n–{message}\r\n" - - return response - -def import_character(text, db, get): - url = text.replace('/import_char', '').strip() - parsed_url = urlparse(url) - if parsed_url[0] == '': - return f'{url} is not a valid URL' - - response = get(url) - if response.status_code != 200: - return f'Error fetching {url} (status_code: {response.status_code})' - - character_data = response.json() - character_id = character_data['character']['id'] - character_name = character_data['character']['name'] - - if db.save_character_info(character_id, character_data) != None: - return f'Character "{character_name}" imported successfully!' - else: - return f'Something went wrong importing {character_name}' - -def link_character(text, db, chat_id, username): - command = text.replace('/link_char', '').strip() - params = [u.strip() for u in command.split(' ')] - - if (len(params) > 1): - character_id = params[0] - player = params[1].replace('@', '').strip() - else: - character_id = params[0] - player = username - - campaign_id, campaign = db.get_campaign(chat_id) - db.set_character_link(campaign_id, player, character_id) - - return f'Character with id {character_id} linked to {player} successfully!' - -def get_status(text, db, chat_id, username): - text = text.replace('/status', '').strip() - char = get_linked_character(text, db, chat_id, username) - - if char == None: - return f'Character not found' - else: - return (f'{char.name} | {char.race} {char._class} Level {char.level}\r\n' - f'HP: {char.current_hit_points}/{char.max_hit_points} | XP: {char.current_experience}') - -def get_weapons(text, db): - character_name = text.replace('/weapons', '').strip() - find_by_id = False - - character = db.get_character(character_name, find_by_id) - if character == None: - return f'Character "{character_name}" not found' - - if len(character.weapons) > 0: - weapons = [w.name for w in character.weapons] - return f'Weapons in {character_name}\'s inventory: {weapons}' - else: - return f'{character_name} does not have any weapon' - -def initiative_roll(username, text, db): - character_name = text.replace('/initiative_roll', '').strip() - find_by_id = False - - character = db.get_character(character_name, find_by_id) - if character == None: - return f'Character "{character_name}" not found' - - dice_notation = f'1d20+{character.dex_mod}' - results = roll(dice_notation) - dice_rolls = results[list(results.keys())[0]][0] - return f'@{username} initiave roll for {character_name} ({dice_notation}): {dice_rolls}' - -def attack_roll(username, text, db): - args = [a.strip() for a in text.replace('/attack_roll ', '').split(' ')] - if len(args) < 3: - return ('Invalid syntax. Usage:' - '\r\n/attack\\_roll (melee|range) \\[distance] \\[adv|disadv]') - - character_name = args[0] - weapon_name = args[1] - attack_type = args[2] - distance = 5 if len(args) <= 3 else args[3] - adv = False - disadv = False - if len(args) > 4 and args[4] == 'adv': - adv = True - elif len(args) > 4 and args[4] == 'disadv': - disadv = True - - mods = 0 - txt_mod = '' - adv_mod = '' - prof = '' - base_notation = '1d20' - distance = int(distance) - find_by_id = False - - character = db.get_character(character_name, find_by_id) - if character == None: - return f'Character "{character_name}" not found' - - weapon = character.get_weapon(weapon_name) - - if attack_type in ["ranged", "r"] and distance > weapon.long_range: - return f"You can attack a target beyond the range of your weapon ({weapon_name}, {weapon.long_range}ft)" - - prof = " + PRO(0)" - if character.has_weapon_proficiency(weapon_name): - mods += character.proficiency - prof = f" + PRO({character.proficiency})" - - if attack_type in ["melee", "m"]: - if weapon.has_finesse() and character.dex_mod > character.str_mod: - txt_mod += f" + DEX({character.dex_mod})" - mods += character.dex_mod - else: - txt_mod += f" + STR({character.str_mod})" - mods += character.str_mod - elif attack_type in ["ranged", "r"]: - if weapon.has_thrown() and character.str_mod > character.dex_mod: - txt_mod += f" + STR({character.str_mod})" - mods += character.str_mod - else: - txt_mod += f" + DEX({character.dex_mod})" - mods += character.dex_mod - - size_mod = SIZE_MODIFIER[character.size] - txt_mod += f" + SIZE({size_mod})" - mods += size_mod - - if attack_type in ["ranged", "r"] and \ - (distance <= CLOSE_COMBAT_DISTANCE or (distance >= weapon.range and distance <= weapon.long_range)): - if not adv: - adv_mod = " + DISADV" - elif disadv == True: - adv_mod = " + DISADV" - elif adv == True: - adv_mod = " + ADV" - - txt_formula = f"{base_notation}{prof}{txt_mod}{adv_mod}" - if mods > 0: - dice_notation = f"{base_notation}+{mods}" - else: - dice_notation = base_notation - - if adv_mod != "": - dice_notation = f"{dice_notation},{dice_notation}" - - results = roll(dice_notation) - dice_rolls = results[list(results.keys())[0]] - - return (f"@{username} attack roll for {character_name} with {weapon_name} ({attack_type}):" - f"\r\nFormula: {txt_formula}" - f"\r\n*{dice_notation}*: {dice_rolls}") - -def short_rest_roll(text, db, chat_id, username): - text = text.replace('/short_rest_roll', '').strip() - char = get_linked_character(text, db, chat_id, username) - - if char == None: - return f'Character not found' - - if char.hit_dice_used == char.level: - return f'{char.name} spent all the hit dice already. You need to take a long rest to replenish them.' - - dice_notation = f'1d{char.hit_dice}+{char.con_mod}' - results = roll(dice_notation) - dice_rolls = results[list(results.keys())[0]][0] - return f'@{username} short rest roll for {char.name} ({dice_notation}): {dice_rolls}' - -def ability_check(chat_id, username, ability): - pass - -def get_linked_character(text, db, chat_id, username): - param = text.replace('@', '').strip() - - campaign_id, campaign = db.get_campaign(chat_id) - - if not param: - character_param = db.get_character_id(campaign_id, username) - else: - character_param = db.get_character_id(campaign_id, param) - - if character_param == None: - character_param = param - find_by_id = False - else: - find_by_id = True - - char = db.get_character(character_param, find_by_id) - - return char - -#if __name__ == "__main__": -# db = Database() -# url = "https://dl.dropbox.com/s/awlpwcwi0eetdoq/ghamorz.json?dl=0" -# #import_character(url) -# #load_character('123456') -# #print(attack_roll('satanas82', '/attack_roll Ghamorz Javelin ranged 10', db)) -# #print(get_weapons('/weapons Ghamorz', db)) -# print(initiative_roll('/initiative_roll Ghamorz', db)) - diff --git a/commands.py b/commands.py index c096333..8132d8c 100644 --- a/commands.py +++ b/commands.py @@ -1,10 +1,10 @@ -from roll import handler as roll_handler -from charsheet import handler as charsheet_handler -from character import handler as character_handler -from turns import handler as turn_handler -from dm import handler as dm_handler -from campaign import handler as campaign_handler from exceptions import CommandNotFound, NotACommand +from handlers.roll import handler as roll_handler +from handlers.charsheet import handler as charsheet_handler +from handlers.character import handler as character_handler +from handlers.turns import handler as turn_handler +from handlers.dm import handler as dm_handler +from handlers.campaign import handler as campaign_handler # Each command should be defined using the expression below: # @@ -39,11 +39,10 @@ "/link_char": (character_handler, ["", "(username)"], "links character to target username or self username"), "/status": (character_handler, [""], "shows the list of weapons of a character"), "/weapons": (character_handler, [""], "shows the list of weapons of a character"), - "/attack_roll": (character_handler, ["", "", "", "(distance)", "(adv|disadv)"], "performs an attack roll on a character"), + "/attack_roll": (character_handler, ["", "", "(distance)", "(adv|disadv)"], "performs an attack roll on a character"), "/initiative_roll": (character_handler, [""], "performs an initiative roll for a character"), "/short_rest_roll": (character_handler, [""], "performs an short rest roll for a character"), - "/talk": (character_handler, [""], "prints a message using in-game conversation format"), - "/say": (character_handler, [""], "prints a normal message using in-game conversation format"), + "/say": (character_handler, [""], "prints a message using in-game conversation format"), "/whisper": (character_handler, [""], "prints a whisper message using in-game conversation format"), "/yell": (character_handler, [""], "prints a yell message using in-game conversation format"), } diff --git a/database.py b/database.py index e2fe53b..ef22341 100644 --- a/database.py +++ b/database.py @@ -71,7 +71,7 @@ def get_character_id(self, campaign_id, username): return None return result[username] - + def get_character(self, character, find_by_id): if find_by_id: result = self.firebase_db.get('/', f'/characters/{character}', params={'auth': FIREBASE_API_SECRET}) diff --git a/exceptions.py b/exceptions.py index 62d7ac2..8ddcab9 100644 --- a/exceptions.py +++ b/exceptions.py @@ -5,3 +5,6 @@ class CommandNotFound(Exception): class NotACommand(Exception): """Raised when the message from the chat is not a command""" pass + +class CharacterNotFound(Exception): + pass diff --git a/campaign.py b/handlers/campaign.py similarity index 76% rename from campaign.py rename to handlers/campaign.py index bbf43a6..826367f 100644 --- a/campaign.py +++ b/handlers/campaign.py @@ -1,24 +1,22 @@ from database import Database -def handler(bot, update): +def handler(bot, update, command, txt_args): db = Database() chat_id = update.message.chat.id text = update.message.text - response = "Invalid command" - if text.startswith('/start_campaign'): - response = start_campaign(chat_id, text, db) - elif text.startswith('/close_campaign'): + if command == '/start_campaign': + response = start_campaign(chat_id, txt_args, db) + elif command == '/close_campaign': response = close_campaign(chat_id, db) bot.send_message(chat_id=update.message.chat_id, text=response, parse_mode="Markdown") def start_campaign(chat_id, text, db): - name = text.replace('/start_campaign', '').strip() campaign_id, campaign = db.get_campaign(chat_id) if campaign_id != None or campaign != None: return 'There is an active campaign for this group. Close the active campaign before creating a new one' - db.create_campaign(chat_id, name) + db.create_campaign(chat_id, text) return "Campaign created successfully!" def close_campaign(chat_id, db): diff --git a/handlers/character.py b/handlers/character.py new file mode 100644 index 0000000..b500c96 --- /dev/null +++ b/handlers/character.py @@ -0,0 +1,231 @@ +import sys +import requests +from urllib.parse import urlparse + +from handlers.roll import roll +from database import Database +from models.character import Character +from exceptions import CharacterNotFound + +CLOSE_COMBAT_DISTANCE = 5 # feet + +SIZE_MODIFIER = { + 'Colossal': -8, + 'Small': 1, + 'Gargantuan': -4, + 'Tiny': 2, + 'Huge': -2, + 'Diminutive': 4, + 'Large': -1, + 'Fine': 8, + 'Medium': 0 +} + +def handler(bot, update, command, txt_args): + db = Database() + chat_id = update.message.chat.id + username = update.message.from_user.username if update.message.from_user.username else update.message.from_user.first_name + + if command == '/import_char': + response = import_character(txt_args, db, requests.get) + if command == '/link_char': + response = link_character(txt_args, db, chat_id, username) + elif command == '/attack_roll': + response = attack_roll(txt_args, db, chat_id, username) + elif command == '/initiative_roll': + response = initiative_roll(txt_args, db, chat_id, username) + elif command == '/short_rest_roll': + response = short_rest_roll(txt_args, db, chat_id, username) + elif command == '/weapons': + response = get_weapons(txt_args, db, chat_id, username) + elif command == '/status': + response = get_status(txt_args, db, chat_id, username) + elif command == '/say' or command == '/yell' or command == '/whisper': + response = talk(command, txt_args, db, chat_id, username) + #bot.delete_message(chat_id=update.message.chat_id, message_id=update.message.message_id) + + bot.send_message(chat_id=update.message.chat_id, text=response, parse_mode="Markdown") + +def import_character(url, db, get): + parsed_url = urlparse(url) + if parsed_url[0] == '': + return f'{url} is not a valid URL' + + response = get(url) + if response.status_code != 200: + return f'Error fetching {url} (status_code: {response.status_code})' + + character_data = response.json() + character_id = character_data['character']['id'] + character_name = character_data['character']['name'] + + if db.save_character_info(character_id, character_data) != None: + return f'Character "{character_name}" imported successfully!' + else: + return f'Something went wrong importing {character_name}' + +def link_character(args, db, chat_id, username): + params = [x.strip() for x in args.split(' ')] + + character_id = params[0] + if len(params) > 1: + player = params[1].replace('@', '').strip() + else: + player = username + + campaign_id, campaign = db.get_campaign(chat_id) + db.set_character_link(campaign_id, player, character_id) + + return f'Character with id {character_id} linked to {player} successfully!' + +def attack_roll(txt_args, db, chat_id, username): + args = [a.strip() for a in txt_args.split(' ')] + if len(args) < 2: + return ('Invalid syntax. Usage:' + '\r\n/attack\\_roll (melee|range) \\[distance] \\[adv|disadv]') + + weapon_name = args[0] + attack_type = args[1] + distance = 5 if len(args) <= 2 else args[2] + adv = False + disadv = False + if len(args) > 3 and args[3] == 'adv': + adv = True + elif len(args) > 3 and args[3] == 'disadv': + disadv = True + + mods = 0 + txt_mod = '' + adv_mod = '' + prof = '' + base_notation = '1d20' + distance = int(distance) + + character = get_linked_character(db, chat_id, username) + weapon = character.get_weapon(weapon_name) + + if attack_type in ["ranged", "r"] and distance > weapon.long_range: + return f"You can attack a target beyond the range of your weapon ({weapon_name}, {weapon.long_range}ft)" + + prof = " + PRO(0)" + if character.has_weapon_proficiency(weapon_name): + mods += character.proficiency + prof = f" + PRO({character.proficiency})" + + if attack_type in ["melee", "m"]: + if weapon.has_finesse() and character.dex_mod > character.str_mod: + txt_mod += f" + DEX({character.dex_mod})" + mods += character.dex_mod + else: + txt_mod += f" + STR({character.str_mod})" + mods += character.str_mod + elif attack_type in ["ranged", "r"]: + if weapon.has_thrown() and character.str_mod > character.dex_mod: + txt_mod += f" + STR({character.str_mod})" + mods += character.str_mod + else: + txt_mod += f" + DEX({character.dex_mod})" + mods += character.dex_mod + + size_mod = SIZE_MODIFIER[character.size] + txt_mod += f" + SIZE({size_mod})" + mods += size_mod + + if attack_type in ["ranged", "r"] and \ + (distance <= CLOSE_COMBAT_DISTANCE or (distance >= weapon.range and distance <= weapon.long_range)): + if not adv: + adv_mod = " + DISADV" + elif disadv == True: + adv_mod = " + DISADV" + elif adv == True: + adv_mod = " + ADV" + + txt_formula = f"{base_notation}{prof}{txt_mod}{adv_mod}" + if mods > 0: + dice_notation = f"{base_notation}+{mods}" + else: + dice_notation = base_notation + + if adv_mod != "": + dice_notation = f"{dice_notation},{dice_notation}" + + results = roll(dice_notation) + dice_rolls = results[list(results.keys())[0]] + + return (f"@{username} attack roll for {character.name} with {weapon_name} ({attack_type}):" + f"\r\nFormula: {txt_formula}" + f"\r\n*{dice_notation}*: {dice_rolls}") + +def initiative_roll(txt_args, db, chat_id, username): + character = get_linked_character(db, chat_id, username) + dice_notation = f'1d20+{character.dex_mod}' + results = roll(dice_notation) + dice_rolls = results[list(results.keys())[0]][0] + return f'@{username} initiave roll for {character.name} ({dice_notation}): {dice_rolls}' + +def short_rest_roll(txt_args, db, chat_id, username): + character = get_linked_character(db, chat_id, username) + + if character.hit_dice_used == character.level: + return f'{character.name} spent all the hit dice already. You need to take a long rest to replenish them.' + + dice_notation = f'1d{character.hit_dice}+{character.con_mod}' + results = roll(dice_notation) + dice_rolls = results[list(results.keys())[0]][0] + return f'@{username} short rest roll for {character.name} ({dice_notation}): {dice_rolls}' + +def get_weapons(other_username, db, chat_id, username): + search_param = other_username if other_username != '' else username + character = get_linked_character(db, chat_id, search_param) + + if len(character.weapons) > 0: + weapons = [w.name for w in character.weapons] + return f'Weapons in {character_name}\'s inventory: {weapons}' + else: + return f'{character_name} does not have any weapon' + +def get_status(other_username, db, chat_id, username): + search_param = other_username if other_username != '' else username + character = get_linked_character(db, chat_id, search_param) + + return (f'{character.name} | {character.race} {character._class} Level {character.level}\r\n' + f'HP: {character.current_hit_points}/{character.max_hit_points} | XP: {character.current_experience}') + +#response = talk(command, txt_args, db, chat_id, username) +def talk(command, txt_args, db, chat_id, username): + args = txt_args.split(' ') + if len(args) < 2: + return ('Invalid syntax. Usage:' + '\r\n' + command +' ') + + character_name = args[0] + message = args[1] + if command == 'yell': + message = message.upper() + elif command == 'whisper': + message = f"__{message}__" + + return f"```\r\n{character_name} says:\r\n–{message}\r\n```" + +def ability_check(chat_id, username, ability): + pass + +def get_linked_character(db, chat_id, username): + campaign_id, campaign = db.get_campaign(chat_id) + character_id = db.get_character_id(campaign_id, username) + char = db.get_character(character_id, find_by_id=True) + + if character == None: + raise CharacterNotFound + + return char + +#if __name__ == "__main__": +# db = Database() +# url = "https://dl.dropbox.com/s/awlpwcwi0eetdoq/ghamorz.json?dl=0" +# #import_character(url) +# #load_character('123456') +# #print(attack_roll('satanas82', '/attack_roll Ghamorz Javelin ranged 10', db)) +# #print(get_weapons('/weapons Ghamorz', db)) +# print(initiative_roll('/initiative_roll Ghamorz', db)) + diff --git a/charsheet.py b/handlers/charsheet.py similarity index 95% rename from charsheet.py rename to handlers/charsheet.py index a0af7b0..8249f9b 100644 --- a/charsheet.py +++ b/handlers/charsheet.py @@ -2,7 +2,7 @@ SHEETS_JSON_URL = "https://gist.githubusercontent.com/satanas/0d38dad2f1eae87143a4cd10206eece5/raw/b4bdf85be78e5e15f3a65c7c7474862a2477dc48/character_dnd.json" -def handler(bot, update): +def handler(bot, update, command, txt_args): username = update.message.text.strip().replace('/charsheet', '').strip() if username == '' or username == ' ': username = update.message.from_user.username diff --git a/dm.py b/handlers/dm.py similarity index 100% rename from dm.py rename to handlers/dm.py diff --git a/roll.py b/handlers/roll.py similarity index 91% rename from roll.py rename to handlers/roll.py index 73e515b..ea08a7c 100644 --- a/roll.py +++ b/handlers/roll.py @@ -4,11 +4,9 @@ DICE_ROLL_PATTERN = re.compile('(\d+?d\d{1,3}|\d+?d%)([+-])*(\d+)*') # Method to be invoked by telegram -def handler(bot, update, **args): - print(update) +def handler(bot, update, command, expression): username = f"@{update.message.from_user.username}" if update.message.from_user.username else update.message.from_user.first_name - expression = update.message.text.strip().replace('/roll ', '') try: results = roll(expression) resp = response(username, results) @@ -73,5 +71,3 @@ def response(username, results): return f"{username} rolled:{rolls}" -if __name__ == "__main__": - print(response('wil', roll('1d20,1d6'))) diff --git a/turns.py b/handlers/turns.py similarity index 100% rename from turns.py rename to handlers/turns.py diff --git a/help.py b/help.py index 4a2ff39..d766997 100644 --- a/help.py +++ b/help.py @@ -54,9 +54,9 @@ def escape(cmd): def help_handler(bot, update): help_message = "{}\n\n*General commands:*\n{}\n\n*Campaign commands:*\n{}\n\n*Character commands:*\n{}".format( HELP_SUMMARY, - '\n'.join([concat_command(c, True, '-', escape) for c in GENERAL_COMMANDS]), - '\n'.join([concat_command(c, True, '-', escape) for c in CAMPAIGN_COMMANDS]), - '\n'.join([concat_command(c, True, '-', escape) for c in CHARACTER_COMMANDS]) + '\n'.join([formatting_command(cmd, info, True, '-', escape) for cmd, info in GENERAL_COMMANDS.items()]), + '\n'.join([formatting_command(cmd, info, True, '-', escape) for cmd, info in CAMPAIGN_COMMANDS.items()]), + '\n'.join([formatting_command(cmd, info, True, '-', escape) for cmd, info in CHARACTER_COMMANDS.items()]) ) bot.send_message(chat_id=update.message.chat_id, text=help_message, parse_mode="Markdown", disable_web_page_preview=True) diff --git a/main.py b/main.py index 89e50b5..dd253d3 100644 --- a/main.py +++ b/main.py @@ -52,16 +52,19 @@ def webhook(event, context): if not is_command(update): return ERROR_RESPONSE + username = update.message.from_user.username if update.message.from_user.username else update.message.from_user.first_name command = parse_command(update.message.text) + txt_args = update.message.text.split(' ')[1:] try: - handler = command_handler(command) + command_handler(command)(bot, update, command, txt_args) + return OK_RESPONSE except CommandNotFound: default_handler(bot, update, f'Command {command} not found') - return OK_RESPONSE - - handler(bot, update, command) - return OK_RESPONSE + return ERROR_RESPONSE + except CharacterNotFound: + default_handler(bot, update, f'Character not found. Cannot execute {update.message.text}') + return ERROR_RESPONSE return ERROR_RESPONSE @@ -83,4 +86,3 @@ def set_webhook(event, context): return OK_RESPONSE return ERROR_RESPONSE - diff --git a/serverless.yml b/serverless.yml index 8dea55d..e98f04f 100644 --- a/serverless.yml +++ b/serverless.yml @@ -25,6 +25,7 @@ provider: environment: TELEGRAM_TOKEN: ${file(./serverless.env.yml):TELEGRAM_TOKEN, ''} FIREBASE_API_SECRET: ${file(./serverless.env.yml):FIREBASE_API_SECRET, ''} + FIREBASE_DB_URL: ${file(./serverless.env.yml):FIREBASE_DB_URL, ''} functions: webhook: diff --git a/tests/test_character.py b/tests/test_character.py index de9def1..6168bc8 100644 --- a/tests/test_character.py +++ b/tests/test_character.py @@ -1,7 +1,7 @@ import unittest from unittest.mock import patch, Mock, PropertyMock -from character import talk, chat,import_character +from handlers.character import talk, chat,import_character CHARACTER_JSON = { 'character': { diff --git a/tests/test_roll.py b/tests/test_roll.py index 12fd8b6..e7c4310 100644 --- a/tests/test_roll.py +++ b/tests/test_roll.py @@ -1,6 +1,6 @@ import unittest -from roll import roll, process_notation, roll_one, response +from handlers.roll import roll, process_notation, roll_one, response class TestRoll(unittest.TestCase):