diff --git a/zulip_bots/zulip_bots/bots/commute/commute.py b/zulip_bots/zulip_bots/bots/commute/commute.py index 23cef4e..5b8a8ab 100644 --- a/zulip_bots/zulip_bots/bots/commute/commute.py +++ b/zulip_bots/zulip_bots/bots/commute/commute.py @@ -180,7 +180,7 @@ class CommuteHandler(object): result = validate_requests(r) return result - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): original_content = message['content'] query = original_content.split() diff --git a/zulip_bots/zulip_bots/bots/converter/converter.py b/zulip_bots/zulip_bots/bots/converter/converter.py index 86ee71f..cba7dbe 100644 --- a/zulip_bots/zulip_bots/bots/converter/converter.py +++ b/zulip_bots/zulip_bots/bots/converter/converter.py @@ -46,7 +46,7 @@ class ConverterHandler(object): all supported units. ''' - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): bot_response = get_bot_converter_response(message, bot_handler) bot_handler.send_reply(message, bot_response) diff --git a/zulip_bots/zulip_bots/bots/define/define.py b/zulip_bots/zulip_bots/bots/define/define.py index 6f0ea83..47d5b1f 100644 --- a/zulip_bots/zulip_bots/bots/define/define.py +++ b/zulip_bots/zulip_bots/bots/define/define.py @@ -23,7 +23,7 @@ class DefineHandler(object): messages with @mention-bot. ''' - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): original_content = message['content'].strip() bot_response = self.get_bot_define_response(original_content) diff --git a/zulip_bots/zulip_bots/bots/encrypt/encrypt.py b/zulip_bots/zulip_bots/bots/encrypt/encrypt.py index 13dad29..c951954 100755 --- a/zulip_bots/zulip_bots/bots/encrypt/encrypt.py +++ b/zulip_bots/zulip_bots/bots/encrypt/encrypt.py @@ -28,7 +28,7 @@ class EncryptHandler(object): Feeding encrypted messages into the bot decrypts them. ''' - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): bot_response = self.get_bot_encrypt_response(message) bot_handler.send_reply(message, bot_response) diff --git a/zulip_bots/zulip_bots/bots/followup/followup.py b/zulip_bots/zulip_bots/bots/followup/followup.py index dcf76c3..dac5223 100644 --- a/zulip_bots/zulip_bots/bots/followup/followup.py +++ b/zulip_bots/zulip_bots/bots/followup/followup.py @@ -22,7 +22,7 @@ class FollowupHandler(object): called "followup" that your API user can send to. ''' - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): if message['content'] == '': bot_response = "Please specify the message you want to send to followup stream after @mention-bot" bot_handler.send_reply(message, bot_response) diff --git a/zulip_bots/zulip_bots/bots/foursquare/foursquare.py b/zulip_bots/zulip_bots/bots/foursquare/foursquare.py index 0e776eb..ae8ba96 100644 --- a/zulip_bots/zulip_bots/bots/foursquare/foursquare.py +++ b/zulip_bots/zulip_bots/bots/foursquare/foursquare.py @@ -47,7 +47,7 @@ Example Inputs: def send_info(self, message, letter, bot_handler): bot_handler.send_reply(message, letter) - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): words = message['content'].split() if "/help" in words: self.send_info(message, self.help_info, bot_handler) diff --git a/zulip_bots/zulip_bots/bots/giphy/giphy.py b/zulip_bots/zulip_bots/bots/giphy/giphy.py index d57da23..20ba073 100644 --- a/zulip_bots/zulip_bots/bots/giphy/giphy.py +++ b/zulip_bots/zulip_bots/bots/giphy/giphy.py @@ -31,7 +31,7 @@ class GiphyHandler(object): global config_info config_info = bot_handler.get_config_info('giphy') - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): bot_response = get_bot_giphy_response(message, bot_handler) bot_handler.send_reply(message, bot_response) diff --git a/zulip_bots/zulip_bots/bots/git_hub_comment/git_hub_comment.py b/zulip_bots/zulip_bots/bots/git_hub_comment/git_hub_comment.py index 7437320..06f16c9 100644 --- a/zulip_bots/zulip_bots/bots/git_hub_comment/git_hub_comment.py +++ b/zulip_bots/zulip_bots/bots/git_hub_comment/git_hub_comment.py @@ -39,7 +39,7 @@ class GitHubHandler(object): '///'. ''' - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): original_content = message['content'] original_sender = message['sender_email'] diff --git a/zulip_bots/zulip_bots/bots/github_detail/github_detail.py b/zulip_bots/zulip_bots/bots/github_detail/github_detail.py index b9fe3c6..9f885dd 100644 --- a/zulip_bots/zulip_bots/bots/github_detail/github_detail.py +++ b/zulip_bots/zulip_bots/bots/github_detail/github_detail.py @@ -69,7 +69,7 @@ class GithubHandler(object): repo = self.repo return (owner, repo) - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): # type: () -> None # Send help message if message['content'] == 'help': diff --git a/zulip_bots/zulip_bots/bots/github_issues/github_issues.py b/zulip_bots/zulip_bots/bots/github_issues/github_issues.py index 3f4368c..c174050 100644 --- a/zulip_bots/zulip_bots/bots/github_issues/github_issues.py +++ b/zulip_bots/zulip_bots/bots/github_issues/github_issues.py @@ -47,7 +47,7 @@ class IssueHandler(object): github_token = (The personal access token for the GitHub bot) ''' - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): original_content = message['content'] original_sender = message['sender_email'] diff --git a/zulip_bots/zulip_bots/bots/googlesearch/googlesearch.py b/zulip_bots/zulip_bots/bots/googlesearch/googlesearch.py index 0f43172..e28d384 100644 --- a/zulip_bots/zulip_bots/bots/googlesearch/googlesearch.py +++ b/zulip_bots/zulip_bots/bots/googlesearch/googlesearch.py @@ -72,7 +72,7 @@ class GoogleSearchHandler(object): @mentioned-bot. ''' - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): original_content = message['content'] result = get_google_result(original_content) bot_handler.send_reply(message, result) diff --git a/zulip_bots/zulip_bots/bots/helloworld/helloworld.py b/zulip_bots/zulip_bots/bots/helloworld/helloworld.py index ca99ae4..bf3da9c 100644 --- a/zulip_bots/zulip_bots/bots/helloworld/helloworld.py +++ b/zulip_bots/zulip_bots/bots/helloworld/helloworld.py @@ -11,7 +11,7 @@ class HelloWorldHandler(object): sophisticated, bots. ''' - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): content = 'beep boop' bot_handler.send_reply(message, content) diff --git a/zulip_bots/zulip_bots/bots/help/help.py b/zulip_bots/zulip_bots/bots/help/help.py index d51a428..8bdd910 100644 --- a/zulip_bots/zulip_bots/bots/help/help.py +++ b/zulip_bots/zulip_bots/bots/help/help.py @@ -11,7 +11,7 @@ class HelpHandler(object): your Zulip instance. ''' - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): help_content = "Info on Zulip can be found here:\nhttps://github.com/zulip/zulip" bot_handler.send_reply(message, help_content) diff --git a/zulip_bots/zulip_bots/bots/howdoi/howdoi.py b/zulip_bots/zulip_bots/bots/howdoi/howdoi.py index 6acf331..ab3c5e7 100644 --- a/zulip_bots/zulip_bots/bots/howdoi/howdoi.py +++ b/zulip_bots/zulip_bots/bots/howdoi/howdoi.py @@ -81,7 +81,7 @@ class HowdoiHandler(object): return answer - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): question = message['content'].strip() if question.startswith('howdowe!'): diff --git a/zulip_bots/zulip_bots/bots/incrementor/incrementor.py b/zulip_bots/zulip_bots/bots/incrementor/incrementor.py index 0b35896..399bf28 100644 --- a/zulip_bots/zulip_bots/bots/incrementor/incrementor.py +++ b/zulip_bots/zulip_bots/bots/incrementor/incrementor.py @@ -11,8 +11,8 @@ class IncrementorHandler(object): is @-mentioned, this number will be incremented in the same message. ''' - def handle_message(self, message, bot_handler, state_handler): - with state_handler.state({'number': 0, 'message_id': None}) as state: + def handle_message(self, message, bot_handler): + with bot_handler.state_handler.state({'number': 0, 'message_id': None}) as state: state['number'] += 1 if state['message_id'] is None: result = bot_handler.send_reply(message, str(state['number'])) diff --git a/zulip_bots/zulip_bots/bots/john/john.py b/zulip_bots/zulip_bots/bots/john/john.py index 4b73811..dbf6af3 100644 --- a/zulip_bots/zulip_bots/bots/john/john.py +++ b/zulip_bots/zulip_bots/bots/john/john.py @@ -103,7 +103,7 @@ class JohnHandler(object): ) self.chatterbot = create_chat_bot(True) - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): original_content = message['content'] bot_response = str(self.chatterbot.get_response(original_content)) bot_handler.send_reply(message, bot_response) diff --git a/zulip_bots/zulip_bots/bots/tictactoe/tictactoe.py b/zulip_bots/zulip_bots/bots/tictactoe/tictactoe.py index 0364656..f03a092 100644 --- a/zulip_bots/zulip_bots/bots/tictactoe/tictactoe.py +++ b/zulip_bots/zulip_bots/bots/tictactoe/tictactoe.py @@ -274,14 +274,14 @@ class ticTacToeHandler(object): message starts with @mention-bot. ''' - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): command_list = message['content'] command = "" for val in command_list: command += val original_sender = message['sender_email'] - with state_handler.state({}) as mydict: + with bot_handler.state_handler.state({}) as mydict: user_game = mydict.get(original_sender) if (not user_game) and command == "new": user_game = TicTacToeGame(copy.deepcopy(initial_board)) diff --git a/zulip_bots/zulip_bots/bots/virtual_fs/virtual_fs.py b/zulip_bots/zulip_bots/bots/virtual_fs/virtual_fs.py index f85cbd2..f3852d9 100644 --- a/zulip_bots/zulip_bots/bots/virtual_fs/virtual_fs.py +++ b/zulip_bots/zulip_bots/bots/virtual_fs/virtual_fs.py @@ -7,7 +7,7 @@ class VirtualFsHandler(object): def usage(self): return get_help() - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): command = message['content'] if command == "": command = "help" @@ -18,7 +18,7 @@ class VirtualFsHandler(object): if isinstance(recipient, list): # If not a stream, then hash on list of emails recipient = " ".join([x['email'] for x in recipient]) - with state_handler.state({}) as state: + with bot_handler.state_handler.state({}) as state: if recipient not in state: state[recipient] = fs_new() fs = state[recipient] diff --git a/zulip_bots/zulip_bots/bots/weather/weather.py b/zulip_bots/zulip_bots/bots/weather/weather.py index 08a815b..2c921f9 100644 --- a/zulip_bots/zulip_bots/bots/weather/weather.py +++ b/zulip_bots/zulip_bots/bots/weather/weather.py @@ -13,7 +13,7 @@ class WeatherHandler(object): This plugin will give info about weather in a specified city ''' - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): help_content = ''' This bot returns weather info for specified city. You specify city in the following format: diff --git a/zulip_bots/zulip_bots/bots/wikipedia/wikipedia.py b/zulip_bots/zulip_bots/bots/wikipedia/wikipedia.py index 0fa5ad3..a921833 100644 --- a/zulip_bots/zulip_bots/bots/wikipedia/wikipedia.py +++ b/zulip_bots/zulip_bots/bots/wikipedia/wikipedia.py @@ -32,7 +32,7 @@ class WikipediaHandler(object): should preface searches with "@mention-bot". ''' - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): bot_response = self.get_bot_wiki_response(message, bot_handler) bot_handler.send_reply(message, bot_response) diff --git a/zulip_bots/zulip_bots/bots/xkcd/xkcd.py b/zulip_bots/zulip_bots/bots/xkcd/xkcd.py index c1baca4..3d057be 100644 --- a/zulip_bots/zulip_bots/bots/xkcd/xkcd.py +++ b/zulip_bots/zulip_bots/bots/xkcd/xkcd.py @@ -32,7 +32,7 @@ class XkcdHandler(object): ``, e.g `@mention-bot 1234`. ''' - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): xkcd_bot_response = get_xkcd_bot_response(message) bot_handler.send_reply(message, xkcd_bot_response) diff --git a/zulip_bots/zulip_bots/bots/yoda/yoda.py b/zulip_bots/zulip_bots/bots/yoda/yoda.py index e217f71..843052e 100644 --- a/zulip_bots/zulip_bots/bots/yoda/yoda.py +++ b/zulip_bots/zulip_bots/bots/yoda/yoda.py @@ -54,7 +54,7 @@ class YodaSpeakHandler(object): @mention-bot You will learn how to speak like me someday. ''' - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): self.handle_input(message, bot_handler) def send_to_yoda_api(self, sentence): diff --git a/zulip_bots/zulip_bots/bots/youtube/youtube.py b/zulip_bots/zulip_bots/bots/youtube/youtube.py index 69dfcb6..5a78ad4 100644 --- a/zulip_bots/zulip_bots/bots/youtube/youtube.py +++ b/zulip_bots/zulip_bots/bots/youtube/youtube.py @@ -8,7 +8,7 @@ class YoutubeHandler(object): This bot will return the first Youtube search result for the give query. ''' - def handle_message(self, message, bot_handler, state_handler): + def handle_message(self, message, bot_handler): help_content = ''' To use the, Youtube Bot send `@mention-bot search terms` Example: diff --git a/zulip_bots/zulip_bots/lib.py b/zulip_bots/zulip_bots/lib.py index ef316ed..c5d16f1 100644 --- a/zulip_bots/zulip_bots/lib.py +++ b/zulip_bots/zulip_bots/lib.py @@ -51,6 +51,26 @@ class RateLimit(object): logging.error(self.error_message) sys.exit(1) +class StateHandler(object): + def __init__(self): + # type: () -> None + self.state_ = None # type: Any + + def set_state(self, state): + # type: (Any) -> None + self.state_ = state + + def get_state(self): + # type: () -> Any + return self.state_ + + @contextmanager + def state(self, default): + # type: (Any) -> Any + new_state = self.get_state() or default + yield new_state + self.set_state(new_state) + class ExternalBotHandler(object): def __init__(self, client, root_dir): # type: (Client, string) -> None @@ -59,6 +79,7 @@ class ExternalBotHandler(object): self._rate_limit = RateLimit(20, 5) self._client = client self._root_dir = root_dir + self.state_handler = StateHandler() try: self.user_id = user_profile['user_id'] self.full_name = user_profile['full_name'] @@ -122,26 +143,6 @@ class ExternalBotHandler(object): raise PermissionError("Cannot open file \"{}\". Bots may only access " "files in their local directory.".format(abs_filepath)) -class StateHandler(object): - def __init__(self): - # type: () -> None - self.state_ = None # type: Any - - def set_state(self, state): - # type: (Any) -> None - self.state_ = state - - def get_state(self): - # type: () -> Any - return self.state_ - - @contextmanager - def state(self, default): - # type: (Any) -> Any - new_state = self.get_state() or default - yield new_state - self.set_state(new_state) - def extract_query_without_mention(message, client): # type: (Dict[str, Any], ExternalBotHandler) -> str """ @@ -185,8 +186,6 @@ def run_message_handler_for_bot(lib_module, quiet, config_file, bot_name): if hasattr(message_handler, 'initialize'): message_handler.initialize(bot_handler=restricted_client) - state_handler = StateHandler() - # Set default bot_details, then override from class, if provided bot_details = { 'name': bot_name.capitalize(), @@ -220,8 +219,7 @@ def run_message_handler_for_bot(lib_module, quiet, config_file, bot_name): if is_private_message or is_mentioned: message_handler.handle_message( message=message, - bot_handler=restricted_client, - state_handler=state_handler + bot_handler=restricted_client ) signal.signal(signal.SIGINT, exit_gracefully) diff --git a/zulip_bots/zulip_bots/test_lib.py b/zulip_bots/zulip_bots/test_lib.py index c6cce11..25e9b74 100755 --- a/zulip_bots/zulip_bots/test_lib.py +++ b/zulip_bots/zulip_bots/test_lib.py @@ -104,7 +104,9 @@ class BotTestCase(TestCase): if state_handler is None: state_handler = StateHandler() # Send message to the concerned bot - self.message_handler.handle_message(message, self.MockClass(None, None), state_handler) + mock_bot_handler = self.MockClass(None, None) + mock_bot_handler.state_handler = state_handler + self.message_handler.handle_message(message, mock_bot_handler) # Check if the bot is sending a message via `send_message` function. # Where response is a dictionary here.