diff --git a/contrib_bots/bots/converter/converter.py b/contrib_bots/bots/converter/converter.py index 13829df..0de442d 100644 --- a/contrib_bots/bots/converter/converter.py +++ b/contrib_bots/bots/converter/converter.py @@ -10,6 +10,7 @@ import sys from math import log10, floor import utils +import re def is_float(value): try: @@ -48,84 +49,95 @@ class ConverterHandler(object): ''' def handle_message(self, message, client, state_handler): - content = message['content'] + bot_response = get_bot_converter_response(message, client) + if message['type'] == 'private': + client.send_message(dict( + type='private', + to=message['sender_email'], + content=bot_response, + )) + else: + client.send_message(dict( + type='stream', + to=message['display_recipient'], + subject=message['subject'], + content=bot_response, + )) - words = content.lower().split() - convert_indexes = [i for i, word in enumerate(words) if word == "@convert"] - convert_indexes = [-1] + convert_indexes - results = [] +def get_bot_converter_response(message, client): + content = message['content'] - for convert_index in convert_indexes: - if (convert_index + 1) < len(words) and words[convert_index + 1] == 'help': - results.append(utils.HELP_MESSAGE) + words = content.lower().split() + convert_indexes = [i for i, word in enumerate(words) if word == "@convert"] + convert_indexes = [-1] + convert_indexes + results = [] + + for convert_index in convert_indexes: + if (convert_index + 1) < len(words) and words[convert_index + 1] == 'help': + results.append(utils.HELP_MESSAGE) + continue + if (convert_index + 3) < len(words): + number = words[convert_index + 1] + unit_from = utils.ALIASES.get(words[convert_index + 2], words[convert_index + 2]) + unit_to = utils.ALIASES.get(words[convert_index + 3], words[convert_index + 3]) + exponent = 0 + + if not is_float(number): + results.append(number + ' is not a valid number. ' + utils.QUICK_HELP) continue - if (convert_index + 3) < len(words): - number = words[convert_index + 1] - unit_from = utils.ALIASES.get(words[convert_index + 2], words[convert_index + 2]) - unit_to = utils.ALIASES.get(words[convert_index + 3], words[convert_index + 3]) - exponent = 0 - if not is_float(number): - results.append(number + ' is not a valid number. ' + utils.QUICK_HELP) - continue + number = float(number) + number_res = copy.copy(number) - number = float(number) - number_res = copy.copy(number) + for key, exp in utils.PREFIXES.items(): + if unit_from.startswith(key): + exponent += exp + unit_from = unit_from[len(key):] + if unit_to.startswith(key): + exponent -= exp + unit_to = unit_to[len(key):] - for key, exp in utils.PREFIXES.items(): - if unit_from.startswith(key): - exponent += exp - unit_from = unit_from[len(key):] - if unit_to.startswith(key): - exponent -= exp - unit_to = unit_to[len(key):] + uf_to_std = utils.UNITS.get(unit_from, False) + ut_to_std = utils.UNITS.get(unit_to, False) - uf_to_std = utils.UNITS.get(unit_from, False) - ut_to_std = utils.UNITS.get(unit_to, False) + if uf_to_std is False: + results.append(unit_from + ' is not a valid unit. ' + utils.QUICK_HELP) + if ut_to_std is False: + results.append(unit_to + ' is not a valid unit.' + utils.QUICK_HELP) + if uf_to_std is False or ut_to_std is False: + continue - if uf_to_std is False: - results.append(unit_from + ' is not a valid unit. ' + utils.QUICK_HELP) - if ut_to_std is False: - results.append(unit_to + ' is not a valid unit.' + utils.QUICK_HELP) - if uf_to_std is False or ut_to_std is False: - continue + base_unit = uf_to_std[2] + if uf_to_std[2] != ut_to_std[2]: + unit_from = unit_from.capitalize() if uf_to_std[2] == 'kelvin' else unit_from + results.append(unit_to.capitalize() + ' and ' + unit_from + + ' are not from the same category. ' + utils.QUICK_HELP) + continue - base_unit = uf_to_std[2] - if uf_to_std[2] != ut_to_std[2]: - unit_from = unit_from.capitalize() if uf_to_std[2] == 'kelvin' else unit_from - results.append(unit_to.capitalize() + ' and ' + unit_from + - ' are not from the same category. ' + utils.QUICK_HELP) - continue - - # perform the conversion between the units - number_res *= uf_to_std[1] - number_res += uf_to_std[0] - number_res -= ut_to_std[0] - number_res /= ut_to_std[1] - - if base_unit == 'bit': - number_res *= 1024 ** (old_div(exponent, float(3))) - else: - number_res *= 10 ** exponent - number_res = round_to(number_res, 7) - - results.append('{} {} = {} {}'.format(number, - words[convert_index + 2], - number_res, - words[convert_index + 3])) + # perform the conversion between the units + number_res *= uf_to_std[1] + number_res += uf_to_std[0] + number_res -= ut_to_std[0] + number_res /= ut_to_std[1] + if base_unit == 'bit': + number_res *= 1024 ** (old_div(exponent, float(3))) else: - results.append('Too few arguments given. ' + utils.QUICK_HELP) + number_res *= 10 ** exponent + number_res = round_to(number_res, 7) - new_content = '' - for idx, result in enumerate(results, 1): - new_content += ((str(idx) + '. conversion: ') if len(results) > 1 else '') + result + '\n' + results.append('{} {} = {} {}'.format(number, + words[convert_index + 2], + number_res, + words[convert_index + 3])) - client.send_message(dict( - type='stream', - to=message['display_recipient'], - subject=message['subject'], - content=new_content, - )) + else: + results.append('Too few arguments given. ' + utils.QUICK_HELP) + + new_content = '' + for idx, result in enumerate(results, 1): + new_content += ((str(idx) + '. conversion: ') if len(results) > 1 else '') + result + '\n' + + return new_content handler_class = ConverterHandler diff --git a/contrib_bots/bots/define_bot/define_bot.py b/contrib_bots/bots/define/define.py similarity index 66% rename from contrib_bots/bots/define_bot/define_bot.py rename to contrib_bots/bots/define/define.py index 3dde8e0..4be78d9 100644 --- a/contrib_bots/bots/define_bot/define_bot.py +++ b/contrib_bots/bots/define/define.py @@ -15,17 +15,32 @@ class DefineHandler(object): EMPTY_WORD_REQUEST_ERROR_MESSAGE = 'Please enter a word to define.' PHRASE_ERROR_MESSAGE = 'Definitions for phrases are not available.' - def usage(DefineHandler): + def usage(self): return ''' This plugin will allow users to define a word. Users should preface messages with @mention-bot. ''' - def _handle_definition(DefineHandler, original_content): - # Remove '@define' from the message and extract the rest of the message, the - # word to define. - split_content = original_content.split(' ') + def handle_message(self, message, client, state_handler): + original_content = message['content'].strip() + bot_response = self.get_bot_define_response(original_content) + if message['type'] == 'private': + client.send_message(dict( + type='private', + to=message['sender_email'], + content=bot_response, + )) + else: + client.send_message(dict( + type='stream', + to=message['display_recipient'], + subject=message['subject'], + content=bot_response, + )) + + def get_bot_define_response(self, original_content): + split_content = original_content.split(' ') # If there are more than one word (a phrase) if len(split_content) > 1: return DefineHandler.PHRASE_ERROR_MESSAGE @@ -35,19 +50,19 @@ class DefineHandler(object): # No word was entered. if not to_define_lower: - return DefineHandler.EMPTY_WORD_REQUEST_ERROR_MESSAGE + return self.EMPTY_WORD_REQUEST_ERROR_MESSAGE else: response = '**{}**:\n'.format(to_define) try: # Use OwlBot API to fetch definition. - api_result = requests.get(DefineHandler.DEFINITION_API_URL.format(to_define_lower)) + api_result = requests.get(self.DEFINITION_API_URL.format(to_define_lower)) # Convert API result from string to JSON format. definitions = api_result.json() # Could not fetch definitions for the given word. if not definitions: - response += DefineHandler.REQUEST_ERROR_MESSAGE + response += self.REQUEST_ERROR_MESSAGE else: # Definitions available. # Show definitions line by line. for d in definitions: @@ -55,21 +70,9 @@ class DefineHandler(object): response += '\n' + '* (**{}**) {}\n  {}'.format(d['type'], d['defenition'], html2text.html2text(example)) except Exception as e: - response += DefineHandler.REQUEST_ERROR_MESSAGE + response += self.REQUEST_ERROR_MESSAGE logging.exception(e) return response - def handle_message(DefineHandler, message, client, state_handler): - original_content = message['content'] - - response = DefineHandler._handle_definition(original_content) - - client.send_message(dict( - type='stream', - to=message['display_recipient'], - subject=message['sender_email'], - content=response - )) - handler_class = DefineHandler diff --git a/contrib_bots/bots/encrypt_bot/encrypt_bot.py b/contrib_bots/bots/encrypt/encrypt.py similarity index 69% rename from contrib_bots/bots/encrypt_bot/encrypt_bot.py rename to contrib_bots/bots/encrypt/encrypt.py index 176866e..9ab9b48 100755 --- a/contrib_bots/bots/encrypt_bot/encrypt_bot.py +++ b/contrib_bots/bots/encrypt/encrypt.py @@ -29,16 +29,27 @@ class EncryptHandler(object): ''' def handle_message(self, message, client, state_handler): + bot_response = self.get_bot_encrypt_response(message) + + if message['type'] == 'private': + client.send_message(dict( + type='private', + to=message['sender_email'], + content=bot_response, + )) + else: + client.send_message(dict( + type='stream', + to=message['display_recipient'], + subject=message['subject'], + content=bot_response, + )) + + def get_bot_encrypt_response(self, message): original_content = message['content'] temp_content = encrypt(original_content) send_content = "Encrypted/Decrypted text: " + temp_content - - client.send_message(dict( - type='stream', - to=message['display_recipient'], - subject=message['subject'], - content = send_content - )) + return send_content handler_class = EncryptHandler diff --git a/contrib_bots/bots/followup/followup.py b/contrib_bots/bots/followup/followup.py index 2939e8d..38fef50 100644 --- a/contrib_bots/bots/followup/followup.py +++ b/contrib_bots/bots/followup/followup.py @@ -23,16 +23,20 @@ class FollowupHandler(object): ''' def handle_message(self, message, client, state_handler): + bot_response = self.get_bot_followup_response(message) + client.send_message(dict( + type='stream', + to='followup', + subject=message['sender_email'], + content=bot_response, + )) + + def get_bot_followup_response(self, message): original_content = message['content'] original_sender = message['sender_email'] temp_content = 'from %s:' % (original_sender,) new_content = temp_content + original_content - client.send_message(dict( - type='stream', - to='followup', - subject=message['sender_email'], - content=new_content, - )) + return new_content handler_class = FollowupHandler diff --git a/contrib_bots/bots/wikipedia/wikipedia.py b/contrib_bots/bots/wikipedia/wikipedia.py index 87fdfec..02eb300 100644 --- a/contrib_bots/bots/wikipedia/wikipedia.py +++ b/contrib_bots/bots/wikipedia/wikipedia.py @@ -2,6 +2,7 @@ from __future__ import absolute_import from __future__ import print_function import requests import logging +import re # See readme.md for instructions on running this code. @@ -26,8 +27,23 @@ class WikipediaHandler(object): ''' def handle_message(self, message, client, state_handler): - query = message['content'] + bot_response = self.get_bot_wiki_response(message, client) + if message['type'] == 'private': + client.send_message(dict( + type='private', + to=message['sender_email'], + content=bot_response, + )) + else: + client.send_message(dict( + type='stream', + to=message['display_recipient'], + subject=message['subject'], + content=bot_response, + )) + def get_bot_wiki_response(self, message, client): + query = message['content'] query_wiki_link = ('https://en.wikipedia.org/w/api.php?action=query&' 'list=search&srsearch=%s&format=json' % (query,)) try: @@ -47,12 +63,7 @@ class WikipediaHandler(object): search_string = data.json()['query']['search'][0]['title'].replace(' ', '_') url = 'https://en.wikipedia.org/wiki/' + search_string new_content = new_content + '", ' + url + return new_content - client.send_message(dict( - type=message['type'], - to=message['display_recipient'], - subject=message['subject'], - content=new_content, - )) handler_class = WikipediaHandler