zulip_bots: Make StateHandler optional.
This has the convenient side-effect of making the bot_handler.storage attribute read-only.
This commit is contained in:
parent
f41030b515
commit
2a74ad11c5
|
@ -2,6 +2,11 @@
|
||||||
|
|
||||||
|
|
||||||
class IncrementorHandler(object):
|
class IncrementorHandler(object):
|
||||||
|
META = {
|
||||||
|
'name': 'Incrementor',
|
||||||
|
'description': 'Example bot to test the update_message() function.',
|
||||||
|
'uses_storage': True,
|
||||||
|
}
|
||||||
|
|
||||||
def usage(self):
|
def usage(self):
|
||||||
return '''
|
return '''
|
||||||
|
|
|
@ -267,6 +267,11 @@ class ticTacToeHandler(object):
|
||||||
tic-tac-toe bot! Make sure your message starts with
|
tic-tac-toe bot! Make sure your message starts with
|
||||||
"@mention-bot".
|
"@mention-bot".
|
||||||
'''
|
'''
|
||||||
|
META = {
|
||||||
|
'name': 'TicTacToe',
|
||||||
|
'description': 'Lets you play Tic-tac-toe against a computer.',
|
||||||
|
'uses_storage': True,
|
||||||
|
}
|
||||||
|
|
||||||
def usage(self):
|
def usage(self):
|
||||||
return '''
|
return '''
|
||||||
|
|
|
@ -4,6 +4,12 @@ import re
|
||||||
import os
|
import os
|
||||||
|
|
||||||
class VirtualFsHandler(object):
|
class VirtualFsHandler(object):
|
||||||
|
META = {
|
||||||
|
'name': 'VirtualFs',
|
||||||
|
'description': 'Provides a simple, permanent file system to store and retrieve strings.',
|
||||||
|
'uses_storage': True,
|
||||||
|
}
|
||||||
|
|
||||||
def usage(self):
|
def usage(self):
|
||||||
return get_help()
|
return get_help()
|
||||||
|
|
||||||
|
|
|
@ -92,14 +92,15 @@ class StateHandler(object):
|
||||||
raise StateHandlerError("Error updating state: {}".format(str(response)))
|
raise StateHandlerError("Error updating state: {}".format(str(response)))
|
||||||
|
|
||||||
class ExternalBotHandler(object):
|
class ExternalBotHandler(object):
|
||||||
def __init__(self, client, root_dir):
|
def __init__(self, client, root_dir, bot_details={}):
|
||||||
# type: (Client, str) -> None
|
# type: (Client, str, Dict[str, Any]) -> None
|
||||||
# Only expose a subset of our Client's functionality
|
# Only expose a subset of our Client's functionality
|
||||||
user_profile = client.get_profile()
|
user_profile = client.get_profile()
|
||||||
self._rate_limit = RateLimit(20, 5)
|
self._rate_limit = RateLimit(20, 5)
|
||||||
self._client = client
|
self._client = client
|
||||||
self._root_dir = root_dir
|
self._root_dir = root_dir
|
||||||
self.storage = StateHandler(client)
|
self.bot_details = bot_details
|
||||||
|
self._storage = StateHandler(client) if self.bot_details.get('uses_storage', False) else None
|
||||||
try:
|
try:
|
||||||
self.user_id = user_profile['user_id']
|
self.user_id = user_profile['user_id']
|
||||||
self.full_name = user_profile['full_name']
|
self.full_name = user_profile['full_name']
|
||||||
|
@ -109,6 +110,20 @@ class ExternalBotHandler(object):
|
||||||
' up the zuliprc file correctly.')
|
' up the zuliprc file correctly.')
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def storage(self):
|
||||||
|
# type: () -> StateHandler
|
||||||
|
if not self._storage:
|
||||||
|
raise AttributeError("""Bot tried to access storage, but has not enabled
|
||||||
|
storage access. To enable storage access, add
|
||||||
|
META = {
|
||||||
|
'uses_storage': True,
|
||||||
|
}
|
||||||
|
to your bot handler class. Check out the incrementor
|
||||||
|
bot for an example on how to do this.
|
||||||
|
""")
|
||||||
|
return self._storage
|
||||||
|
|
||||||
def send_message(self, message):
|
def send_message(self, message):
|
||||||
# type: (Dict[str, Any]) -> Dict[str, Any]
|
# type: (Dict[str, Any]) -> Dict[str, Any]
|
||||||
if self._rate_limit.is_legal():
|
if self._rate_limit.is_legal():
|
||||||
|
@ -194,21 +209,20 @@ def run_message_handler_for_bot(lib_module, quiet, config_file, bot_name):
|
||||||
# inherit from a common prototype specifying the handle_message
|
# inherit from a common prototype specifying the handle_message
|
||||||
# function.
|
# function.
|
||||||
#
|
#
|
||||||
# Make sure you set up your ~/.zuliprc
|
|
||||||
client = Client(config_file=config_file, client="Zulip{}Bot".format(bot_name.capitalize()))
|
|
||||||
bot_dir = os.path.dirname(lib_module.__file__)
|
|
||||||
restricted_client = ExternalBotHandler(client, bot_dir)
|
|
||||||
|
|
||||||
message_handler = lib_module.handler_class()
|
|
||||||
if hasattr(message_handler, 'initialize'):
|
|
||||||
message_handler.initialize(bot_handler=restricted_client)
|
|
||||||
|
|
||||||
# Set default bot_details, then override from class, if provided
|
# Set default bot_details, then override from class, if provided
|
||||||
bot_details = {
|
bot_details = {
|
||||||
'name': bot_name.capitalize(),
|
'name': bot_name.capitalize(),
|
||||||
'description': "",
|
'description': "",
|
||||||
}
|
}
|
||||||
bot_details.update(getattr(lib_module.handler_class, 'META', {}))
|
bot_details.update(getattr(lib_module.handler_class, 'META', {}))
|
||||||
|
# Make sure you set up your ~/.zuliprc
|
||||||
|
client = Client(config_file=config_file, client="Zulip{}Bot".format(bot_name.capitalize()))
|
||||||
|
bot_dir = os.path.dirname(lib_module.__file__)
|
||||||
|
restricted_client = ExternalBotHandler(client, bot_dir, bot_details)
|
||||||
|
|
||||||
|
message_handler = lib_module.handler_class()
|
||||||
|
if hasattr(message_handler, 'initialize'):
|
||||||
|
message_handler.initialize(bot_handler=restricted_client)
|
||||||
|
|
||||||
if not quiet:
|
if not quiet:
|
||||||
print("Running {} Bot:".format(bot_details['name']))
|
print("Running {} Bot:".format(bot_details['name']))
|
||||||
|
|
Loading…
Reference in a new issue