From 3c41033d8c769a5f431d93af9602de89ae112975 Mon Sep 17 00:00:00 2001 From: Abhijeet Kaur Date: Mon, 19 Jun 2017 00:12:28 +0530 Subject: [PATCH] bots: Add a separate class "EmbeddedHandlerBots" in bot_lib.py. Add another class for bot type as embedded bot, for bots that run directly on Zulip server. This class uses internal 'internal_send_messages' from actions.py instead of using the 'send_message' function from Zulip Client class. We haven't gone ahead with creating an abstract superclass right away. We just have two versions for now, it would be easier to iterate a little more on the interfaces, and then only add the superclass when we're ready to lock down the interface. --- bots_api/bot_lib.py | 70 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 14 deletions(-) diff --git a/bots_api/bot_lib.py b/bots_api/bot_lib.py index 6b124b0..955afcc 100644 --- a/bots_api/bot_lib.py +++ b/bots_api/bot_lib.py @@ -6,6 +6,8 @@ import signal import sys import time import re +from zerver.lib.actions import internal_send_message +from zerver.models import UserProfile from six.moves import configparser @@ -50,6 +52,22 @@ class RateLimit(object): logging.error(self.error_message) sys.exit(1) +def send_reply(message, response, email, send_message): + # type: (Dict[str, Any], str, str, Any) -> Dict[str, Any] + if message['type'] == 'private': + return send_message(dict( + type='private', + to=[x['email'] for x in message['display_recipient'] if email != x['email']], + content=response, + )) + else: + return send_message(dict( + type='stream', + to=message['display_recipient'], + subject=message['subject'], + content=response, + )) + class ExternalBotHandler(object): def __init__(self, client): @@ -73,6 +91,10 @@ class ExternalBotHandler(object): else: self._rate_limit.show_error_and_exit() + def send_reply(self, message, response): + # type: (Dict[str, Any], str) -> Dict[str, Any] + return send_reply(message, response, self.email, self.send_message) + def update_message(self, message): # type: (Dict[str, Any]) -> Dict[str, Any] if self._rate_limit.is_legal(): @@ -80,21 +102,41 @@ class ExternalBotHandler(object): else: self._rate_limit.show_error_and_exit() - def send_reply(self, message, response): - # type: (Dict[str, Any], str) -> Dict[str, Any] - if message['type'] == 'private': - return self.send_message(dict( - type='private', - to=[x['email'] for x in message['display_recipient'] if self.email != x['email']], - content=response, - )) + def get_config_info(self, bot_name, section=None): + # type: (str, Optional[str]) -> Dict[str, Any] + conf_file_path = os.path.realpath(os.path.join( + our_dir, '..', 'bots', bot_name, bot_name + '.conf')) + section = section or bot_name + config = configparser.ConfigParser() + config.readfp(open(conf_file_path)) # type: ignore + return dict(config.items(section)) + +class EmbeddedBotHandler(object): + def __init__(self, user_profile): + # type: (UserProfile) -> None + # Only expose a subset of our UserProfile's functionality + self.user_profile = user_profile + self._rate_limit = RateLimit(20, 5) + try: + self.full_name = user_profile['full_name'] + self.email = user_profile['email'] + except KeyError: + logging.error('Cannot fetch user profile, make sure you have set' + ' up the zuliprc file correctly.') + sys.exit(1) + + def send_message(self, message): + # type: (Dict[str, Any]) -> None + if self._rate_limit.is_legal(): + internal_send_message(realm=self.user_profile.realm, sender_email=message['sender'], + recipient_type_name=message['type'], recipients=message['to'], + subject=message['subject'], content=message['content']) else: - return self.send_message(dict( - type='stream', - to=message['display_recipient'], - subject=message['subject'], - content=response, - )) + self._rate_limit.show_error_and_exit() + + def send_reply(self, message, response): + # type: (Dict[str, Any], str) -> None + send_reply(message, response, self.email, self.send_message) def get_config_info(self, bot_name, section=None): # type: (str, Optional[str]) -> Dict[str, Any]