parent
fb73220438
commit
1d37ed2217
42 changed files with 155 additions and 143 deletions
|
@ -2,7 +2,7 @@
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
import packaged_helloworld
|
import packaged_helloworld
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
__version__ = packaged_helloworld.__version__
|
__version__ = packaged_helloworld.__version__
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ class HelloWorldHandler:
|
||||||
sophisticated, bots that can be installed separately.
|
sophisticated, bots that can be installed separately.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, Any], bot_handler: AbstractBotHandler) -> None:
|
||||||
content = "beep boop"
|
content = "beep boop"
|
||||||
bot_handler.send_reply(message, content)
|
bot_handler.send_reply(message, content)
|
||||||
|
|
||||||
|
|
|
@ -4,11 +4,11 @@ from typing import Any, Dict, List
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class BaremetricsHandler:
|
class BaremetricsHandler:
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.config_info = bot_handler.get_config_info("baremetrics")
|
self.config_info = bot_handler.get_config_info("baremetrics")
|
||||||
self.api_key = self.config_info["api_key"]
|
self.api_key = self.config_info["api_key"]
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ class BaremetricsHandler:
|
||||||
|
|
||||||
self.check_api_key(bot_handler)
|
self.check_api_key(bot_handler)
|
||||||
|
|
||||||
def check_api_key(self, bot_handler: BotHandler) -> None:
|
def check_api_key(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
url = "https://api.baremetrics.com/v1/account"
|
url = "https://api.baremetrics.com/v1/account"
|
||||||
test_query_response = requests.get(url, headers=self.auth_header)
|
test_query_response = requests.get(url, headers=self.auth_header)
|
||||||
test_query_data = test_query_response.json()
|
test_query_data = test_query_response.json()
|
||||||
|
@ -57,7 +57,7 @@ class BaremetricsHandler:
|
||||||
Version 1.0
|
Version 1.0
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, Any], bot_handler: AbstractBotHandler) -> None:
|
||||||
content = message["content"].strip().split()
|
content = message["content"].strip().split()
|
||||||
|
|
||||||
if content == []:
|
if content == []:
|
||||||
|
|
|
@ -4,7 +4,7 @@ from typing import Dict
|
||||||
import requests
|
import requests
|
||||||
from requests.exceptions import ConnectionError
|
from requests.exceptions import ConnectionError
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
help_message = """
|
help_message = """
|
||||||
You can add datapoints towards your beeminder goals \
|
You can add datapoints towards your beeminder goals \
|
||||||
|
@ -80,7 +80,7 @@ class BeeminderHandler:
|
||||||
towards their beeminder goals via zulip
|
towards their beeminder goals via zulip
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.config_info = bot_handler.get_config_info("beeminder")
|
self.config_info = bot_handler.get_config_info("beeminder")
|
||||||
# Check for valid auth_token
|
# Check for valid auth_token
|
||||||
auth_token = self.config_info["auth_token"]
|
auth_token = self.config_info["auth_token"]
|
||||||
|
@ -96,7 +96,7 @@ class BeeminderHandler:
|
||||||
def usage(self) -> str:
|
def usage(self) -> str:
|
||||||
return "This plugin allows users to add datapoints towards their Beeminder goals"
|
return "This plugin allows users to add datapoints towards their Beeminder goals"
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
response = get_beeminder_response(message["content"], self.config_info)
|
response = get_beeminder_response(message["content"], self.config_info)
|
||||||
bot_handler.send_reply(message, response)
|
bot_handler.send_reply(message, response)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ from typing import Dict, Optional
|
||||||
import chess
|
import chess
|
||||||
import chess.engine
|
import chess.engine
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
START_REGEX = re.compile("start with other user$")
|
START_REGEX = re.compile("start with other user$")
|
||||||
START_COMPUTER_REGEX = re.compile("start as (?P<user_color>white|black) with computer")
|
START_COMPUTER_REGEX = re.compile("start as (?P<user_color>white|black) with computer")
|
||||||
|
@ -24,7 +24,7 @@ class ChessHandler:
|
||||||
"Stockfish program on this computer."
|
"Stockfish program on this computer."
|
||||||
)
|
)
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.config_info = bot_handler.get_config_info("chess")
|
self.config_info = bot_handler.get_config_info("chess")
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -36,7 +36,7 @@ class ChessHandler:
|
||||||
# runner is testing or knows they won't be using an engine.
|
# runner is testing or knows they won't be using an engine.
|
||||||
print("That Stockfish doesn't exist. Continuing.")
|
print("That Stockfish doesn't exist. Continuing.")
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
content = message["content"]
|
content = message["content"]
|
||||||
|
|
||||||
if content == "":
|
if content == "":
|
||||||
|
@ -76,7 +76,7 @@ class ChessHandler:
|
||||||
elif resign_regex_match:
|
elif resign_regex_match:
|
||||||
self.resign(message, bot_handler, last_fen)
|
self.resign(message, bot_handler, last_fen)
|
||||||
|
|
||||||
def start(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def start(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
"""Starts a game with another user, with the current user as white.
|
"""Starts a game with another user, with the current user as white.
|
||||||
Replies to the bot handler.
|
Replies to the bot handler.
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@ class ChessHandler:
|
||||||
bot_handler.storage.put("last_fen", new_board.fen())
|
bot_handler.storage.put("last_fen", new_board.fen())
|
||||||
|
|
||||||
def start_computer(
|
def start_computer(
|
||||||
self, message: Dict[str, str], bot_handler: BotHandler, is_white_user: bool
|
self, message: Dict[str, str], bot_handler: AbstractBotHandler, is_white_user: bool
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Starts a game with the computer. Replies to the bot handler.
|
"""Starts a game with the computer. Replies to the bot handler.
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ class ChessHandler:
|
||||||
)
|
)
|
||||||
|
|
||||||
def validate_board(
|
def validate_board(
|
||||||
self, message: Dict[str, str], bot_handler: BotHandler, fen: str
|
self, message: Dict[str, str], bot_handler: AbstractBotHandler, fen: str
|
||||||
) -> Optional[chess.Board]:
|
) -> Optional[chess.Board]:
|
||||||
"""Validates a board based on its FEN string. Replies to the bot
|
"""Validates a board based on its FEN string. Replies to the bot
|
||||||
handler if there is an error with the board.
|
handler if there is an error with the board.
|
||||||
|
@ -147,7 +147,7 @@ class ChessHandler:
|
||||||
def validate_move(
|
def validate_move(
|
||||||
self,
|
self,
|
||||||
message: Dict[str, str],
|
message: Dict[str, str],
|
||||||
bot_handler: BotHandler,
|
bot_handler: AbstractBotHandler,
|
||||||
last_board: chess.Board,
|
last_board: chess.Board,
|
||||||
move_san: str,
|
move_san: str,
|
||||||
is_computer: object,
|
is_computer: object,
|
||||||
|
@ -180,7 +180,7 @@ class ChessHandler:
|
||||||
return move
|
return move
|
||||||
|
|
||||||
def check_game_over(
|
def check_game_over(
|
||||||
self, message: Dict[str, str], bot_handler: BotHandler, new_board: chess.Board
|
self, message: Dict[str, str], bot_handler: AbstractBotHandler, new_board: chess.Board
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""Checks if a game is over due to
|
"""Checks if a game is over due to
|
||||||
- checkmate,
|
- checkmate,
|
||||||
|
@ -224,7 +224,7 @@ class ChessHandler:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def move(
|
def move(
|
||||||
self, message: Dict[str, str], bot_handler: BotHandler, last_fen: str, move_san: str
|
self, message: Dict[str, str], bot_handler: AbstractBotHandler, last_fen: str, move_san: str
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Makes a move for a user in a game with another user. Replies to
|
"""Makes a move for a user in a game with another user. Replies to
|
||||||
the bot handler.
|
the bot handler.
|
||||||
|
@ -256,7 +256,7 @@ class ChessHandler:
|
||||||
bot_handler.storage.put("last_fen", new_board.fen())
|
bot_handler.storage.put("last_fen", new_board.fen())
|
||||||
|
|
||||||
def move_computer(
|
def move_computer(
|
||||||
self, message: Dict[str, str], bot_handler: BotHandler, last_fen: str, move_san: str
|
self, message: Dict[str, str], bot_handler: AbstractBotHandler, last_fen: str, move_san: str
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Preforms a move for a user in a game with the computer and then
|
"""Preforms a move for a user in a game with the computer and then
|
||||||
makes the computer's move. Replies to the bot handler. Unlike `move`,
|
makes the computer's move. Replies to the bot handler. Unlike `move`,
|
||||||
|
@ -306,7 +306,7 @@ class ChessHandler:
|
||||||
bot_handler.storage.put("last_fen", new_board_after_computer_move.fen())
|
bot_handler.storage.put("last_fen", new_board_after_computer_move.fen())
|
||||||
|
|
||||||
def move_computer_first(
|
def move_computer_first(
|
||||||
self, message: Dict[str, str], bot_handler: BotHandler, last_fen: str
|
self, message: Dict[str, str], bot_handler: AbstractBotHandler, last_fen: str
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Preforms a move for the computer without having the user go first in
|
"""Preforms a move for the computer without having the user go first in
|
||||||
a game with the computer. Replies to the bot handler. Like
|
a game with the computer. Replies to the bot handler. Like
|
||||||
|
@ -345,7 +345,9 @@ class ChessHandler:
|
||||||
# `bot_handler`'s `storage` only accepts `str` values.
|
# `bot_handler`'s `storage` only accepts `str` values.
|
||||||
bot_handler.storage.put("is_with_computer", str(True))
|
bot_handler.storage.put("is_with_computer", str(True))
|
||||||
|
|
||||||
def resign(self, message: Dict[str, str], bot_handler: BotHandler, last_fen: str) -> None:
|
def resign(
|
||||||
|
self, message: Dict[str, str], bot_handler: AbstractBotHandler, last_fen: str
|
||||||
|
) -> None:
|
||||||
"""Resigns the game for the current player.
|
"""Resigns the game for the current player.
|
||||||
|
|
||||||
Parameters:
|
Parameters:
|
||||||
|
|
|
@ -5,7 +5,7 @@ from math import floor, log10
|
||||||
from typing import Any, Dict, List
|
from typing import Any, Dict, List
|
||||||
|
|
||||||
from zulip_bots.bots.converter import utils
|
from zulip_bots.bots.converter import utils
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
def is_float(value: Any) -> bool:
|
def is_float(value: Any) -> bool:
|
||||||
|
@ -49,12 +49,12 @@ class ConverterHandler:
|
||||||
all supported units.
|
all supported units.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
bot_response = get_bot_converter_response(message, bot_handler)
|
bot_response = get_bot_converter_response(message, bot_handler)
|
||||||
bot_handler.send_reply(message, bot_response)
|
bot_handler.send_reply(message, bot_response)
|
||||||
|
|
||||||
|
|
||||||
def get_bot_converter_response(message: Dict[str, str], bot_handler: BotHandler) -> str:
|
def get_bot_converter_response(message: Dict[str, str], bot_handler: AbstractBotHandler) -> str:
|
||||||
content = message["content"]
|
content = message["content"]
|
||||||
|
|
||||||
words = content.lower().split()
|
words = content.lower().split()
|
||||||
|
|
|
@ -6,7 +6,7 @@ from typing import Dict
|
||||||
import html2text
|
import html2text
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class DefineHandler:
|
class DefineHandler:
|
||||||
|
@ -27,7 +27,7 @@ class DefineHandler:
|
||||||
messages with @mention-bot.
|
messages with @mention-bot.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
original_content = message["content"].strip()
|
original_content = message["content"].strip()
|
||||||
bot_response = self.get_bot_define_response(original_content)
|
bot_response = self.get_bot_define_response(original_content)
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ from typing import Dict
|
||||||
|
|
||||||
import apiai
|
import apiai
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
help_message = """DialogFlow bot
|
help_message = """DialogFlow bot
|
||||||
This bot will interact with dialogflow bots.
|
This bot will interact with dialogflow bots.
|
||||||
|
@ -47,7 +47,7 @@ class DialogFlowHandler:
|
||||||
DialogFlow bots to zulip
|
DialogFlow bots to zulip
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.config_info = bot_handler.get_config_info("dialogflow")
|
self.config_info = bot_handler.get_config_info("dialogflow")
|
||||||
|
|
||||||
def usage(self) -> str:
|
def usage(self) -> str:
|
||||||
|
@ -56,7 +56,7 @@ class DialogFlowHandler:
|
||||||
DialogFlow bots to zulip
|
DialogFlow bots to zulip
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
result = get_bot_result(message["content"], self.config_info, message["sender_id"])
|
result = get_bot_result(message["content"], self.config_info, message["sender_id"])
|
||||||
bot_handler.send_reply(message, result)
|
bot_handler.send_reply(message, result)
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ from typing import Any, Dict, List, Tuple
|
||||||
|
|
||||||
from dropbox import Dropbox
|
from dropbox import Dropbox
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
URL = "[{name}](https://www.dropbox.com/home{path})"
|
URL = "[{name}](https://www.dropbox.com/home{path})"
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@ class DropboxHandler:
|
||||||
between zulip and your dropbox account.
|
between zulip and your dropbox account.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.config_info = bot_handler.get_config_info("dropbox_share")
|
self.config_info = bot_handler.get_config_info("dropbox_share")
|
||||||
self.ACCESS_TOKEN = self.config_info.get("access_token")
|
self.ACCESS_TOKEN = self.config_info.get("access_token")
|
||||||
self.client = Dropbox(self.ACCESS_TOKEN)
|
self.client = Dropbox(self.ACCESS_TOKEN)
|
||||||
|
@ -22,7 +22,7 @@ class DropboxHandler:
|
||||||
def usage(self) -> str:
|
def usage(self) -> str:
|
||||||
return get_help()
|
return get_help()
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
command = message["content"]
|
command = message["content"]
|
||||||
if command == "":
|
if command == "":
|
||||||
command = "help"
|
command = "help"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
def encrypt(text: str) -> str:
|
def encrypt(text: str) -> str:
|
||||||
|
@ -34,7 +34,7 @@ class EncryptHandler:
|
||||||
Feeding encrypted messages into the bot decrypts them.
|
Feeding encrypted messages into the bot decrypts them.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
bot_response = self.get_bot_encrypt_response(message)
|
bot_response = self.get_bot_encrypt_response(message)
|
||||||
bot_handler.send_reply(message, bot_response)
|
bot_handler.send_reply(message, bot_response)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class FileUploaderHandler:
|
class FileUploaderHandler:
|
||||||
|
@ -13,7 +13,7 @@ class FileUploaderHandler:
|
||||||
"\n- @uploader help : Display help message"
|
"\n- @uploader help : Display help message"
|
||||||
)
|
)
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
help_str = (
|
help_str = (
|
||||||
"Use this bot with any of the following commands:"
|
"Use this bot with any of the following commands:"
|
||||||
"\n* `@uploader <local_file_path>` : Upload a file, where `<local_file_path>` is the path to the file"
|
"\n* `@uploader <local_file_path>` : Upload a file, where `<local_file_path>` is the path to the file"
|
||||||
|
|
|
@ -4,7 +4,7 @@ from typing import Any, Dict, List, Optional, Tuple
|
||||||
import requests
|
import requests
|
||||||
from requests.exceptions import ConnectionError
|
from requests.exceptions import ConnectionError
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
USERS_LIST_URL = "https://api.flock.co/v1/roster.listContacts"
|
USERS_LIST_URL = "https://api.flock.co/v1/roster.listContacts"
|
||||||
SEND_MESSAGE_URL = "https://api.flock.co/v1/chat.sendMessage"
|
SEND_MESSAGE_URL = "https://api.flock.co/v1/chat.sendMessage"
|
||||||
|
@ -97,14 +97,14 @@ class FlockHandler:
|
||||||
flock user without having to leave Zulip.
|
flock user without having to leave Zulip.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.config_info = bot_handler.get_config_info("flock")
|
self.config_info = bot_handler.get_config_info("flock")
|
||||||
|
|
||||||
def usage(self) -> str:
|
def usage(self) -> str:
|
||||||
return """Hello from Flock Bot. You can send messages to any Flock user
|
return """Hello from Flock Bot. You can send messages to any Flock user
|
||||||
right from Zulip."""
|
right from Zulip."""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
response = get_flock_bot_response(message["content"], self.config_info)
|
response = get_flock_bot_response(message["content"], self.config_info)
|
||||||
bot_handler.send_reply(message, response)
|
bot_handler.send_reply(message, response)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# See readme.md for instructions on running this code.
|
# See readme.md for instructions on running this code.
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class FollowupHandler:
|
class FollowupHandler:
|
||||||
|
@ -26,11 +26,11 @@ class FollowupHandler:
|
||||||
called "followup" that your API user can send to.
|
called "followup" that your API user can send to.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.config_info = bot_handler.get_config_info("followup", optional=False)
|
self.config_info = bot_handler.get_config_info("followup", optional=False)
|
||||||
self.stream = self.config_info.get("stream", "followup")
|
self.stream = self.config_info.get("stream", "followup")
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
if message["content"] == "":
|
if message["content"] == "":
|
||||||
bot_response = (
|
bot_response = (
|
||||||
"Please specify the message you want to send to followup stream after @mention-bot"
|
"Please specify the message you want to send to followup stream after @mention-bot"
|
||||||
|
|
|
@ -3,7 +3,7 @@ from typing import Any, Dict
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class FrontHandler:
|
class FrontHandler:
|
||||||
|
@ -24,7 +24,7 @@ class FrontHandler:
|
||||||
Front Bot, `front.conf` must be set up. See `doc.md` for more details.
|
Front Bot, `front.conf` must be set up. See `doc.md` for more details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
config = bot_handler.get_config_info("front")
|
config = bot_handler.get_config_info("front")
|
||||||
api_key = config.get("api_key")
|
api_key = config.get("api_key")
|
||||||
if not api_key:
|
if not api_key:
|
||||||
|
@ -32,14 +32,14 @@ class FrontHandler:
|
||||||
|
|
||||||
self.auth = "Bearer " + api_key
|
self.auth = "Bearer " + api_key
|
||||||
|
|
||||||
def help(self, bot_handler: BotHandler) -> str:
|
def help(self, bot_handler: AbstractBotHandler) -> str:
|
||||||
response = ""
|
response = ""
|
||||||
for command, description in self.COMMANDS:
|
for command, description in self.COMMANDS:
|
||||||
response += f"`{command}` {description}\n"
|
response += f"`{command}` {description}\n"
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def archive(self, bot_handler: BotHandler) -> str:
|
def archive(self, bot_handler: AbstractBotHandler) -> str:
|
||||||
response = requests.patch(
|
response = requests.patch(
|
||||||
self.FRONT_API.format(self.conversation_id),
|
self.FRONT_API.format(self.conversation_id),
|
||||||
headers={"Authorization": self.auth},
|
headers={"Authorization": self.auth},
|
||||||
|
@ -51,7 +51,7 @@ class FrontHandler:
|
||||||
|
|
||||||
return "Conversation was archived."
|
return "Conversation was archived."
|
||||||
|
|
||||||
def delete(self, bot_handler: BotHandler) -> str:
|
def delete(self, bot_handler: AbstractBotHandler) -> str:
|
||||||
response = requests.patch(
|
response = requests.patch(
|
||||||
self.FRONT_API.format(self.conversation_id),
|
self.FRONT_API.format(self.conversation_id),
|
||||||
headers={"Authorization": self.auth},
|
headers={"Authorization": self.auth},
|
||||||
|
@ -63,7 +63,7 @@ class FrontHandler:
|
||||||
|
|
||||||
return "Conversation was deleted."
|
return "Conversation was deleted."
|
||||||
|
|
||||||
def spam(self, bot_handler: BotHandler) -> str:
|
def spam(self, bot_handler: AbstractBotHandler) -> str:
|
||||||
response = requests.patch(
|
response = requests.patch(
|
||||||
self.FRONT_API.format(self.conversation_id),
|
self.FRONT_API.format(self.conversation_id),
|
||||||
headers={"Authorization": self.auth},
|
headers={"Authorization": self.auth},
|
||||||
|
@ -75,7 +75,7 @@ class FrontHandler:
|
||||||
|
|
||||||
return "Conversation was marked as spam."
|
return "Conversation was marked as spam."
|
||||||
|
|
||||||
def restore(self, bot_handler: BotHandler) -> str:
|
def restore(self, bot_handler: AbstractBotHandler) -> str:
|
||||||
response = requests.patch(
|
response = requests.patch(
|
||||||
self.FRONT_API.format(self.conversation_id),
|
self.FRONT_API.format(self.conversation_id),
|
||||||
headers={"Authorization": self.auth},
|
headers={"Authorization": self.auth},
|
||||||
|
@ -87,7 +87,7 @@ class FrontHandler:
|
||||||
|
|
||||||
return "Conversation was restored."
|
return "Conversation was restored."
|
||||||
|
|
||||||
def comment(self, bot_handler: BotHandler, **kwargs: Any) -> str:
|
def comment(self, bot_handler: AbstractBotHandler, **kwargs: Any) -> str:
|
||||||
response = requests.post(
|
response = requests.post(
|
||||||
self.FRONT_API.format(self.conversation_id) + "/comments",
|
self.FRONT_API.format(self.conversation_id) + "/comments",
|
||||||
headers={"Authorization": self.auth},
|
headers={"Authorization": self.auth},
|
||||||
|
@ -99,7 +99,7 @@ class FrontHandler:
|
||||||
|
|
||||||
return "Comment was sent."
|
return "Comment was sent."
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
command = message["content"]
|
command = message["content"]
|
||||||
|
|
||||||
result = re.search(self.CNV_ID_REGEXP, message["subject"])
|
result = re.search(self.CNV_ID_REGEXP, message["subject"])
|
||||||
|
|
|
@ -5,7 +5,7 @@ import requests
|
||||||
from requests.exceptions import ConnectionError, HTTPError
|
from requests.exceptions import ConnectionError, HTTPError
|
||||||
|
|
||||||
from zulip_bots.custom_exceptions import ConfigValidationError
|
from zulip_bots.custom_exceptions import ConfigValidationError
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
GIPHY_TRANSLATE_API = "http://api.giphy.com/v1/gifs/translate"
|
GIPHY_TRANSLATE_API = "http://api.giphy.com/v1/gifs/translate"
|
||||||
GIPHY_RANDOM_API = "http://api.giphy.com/v1/gifs/random"
|
GIPHY_RANDOM_API = "http://api.giphy.com/v1/gifs/random"
|
||||||
|
@ -44,10 +44,10 @@ class GiphyHandler:
|
||||||
)
|
)
|
||||||
raise ConfigValidationError(error_message) from e
|
raise ConfigValidationError(error_message) from e
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.config_info = bot_handler.get_config_info("giphy")
|
self.config_info = bot_handler.get_config_info("giphy")
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
bot_response = get_bot_giphy_response(message, bot_handler, self.config_info)
|
bot_response = get_bot_giphy_response(message, bot_handler, self.config_info)
|
||||||
bot_handler.send_reply(message, bot_response)
|
bot_handler.send_reply(message, bot_response)
|
||||||
|
|
||||||
|
@ -82,7 +82,7 @@ def get_url_gif_giphy(keyword: str, api_key: str) -> Union[int, str]:
|
||||||
|
|
||||||
|
|
||||||
def get_bot_giphy_response(
|
def get_bot_giphy_response(
|
||||||
message: Dict[str, str], bot_handler: BotHandler, config_info: Dict[str, str]
|
message: Dict[str, str], bot_handler: AbstractBotHandler, config_info: Dict[str, str]
|
||||||
) -> str:
|
) -> str:
|
||||||
# Each exception has a specific reply should "gif_url" return a number.
|
# Each exception has a specific reply should "gif_url" return a number.
|
||||||
# The bot will post the appropriate message for the error.
|
# The bot will post the appropriate message for the error.
|
||||||
|
|
|
@ -4,7 +4,7 @@ from typing import Any, Dict, Tuple, Union
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class GithubHandler:
|
class GithubHandler:
|
||||||
|
@ -16,7 +16,7 @@ class GithubHandler:
|
||||||
GITHUB_ISSUE_URL_TEMPLATE = "https://api.github.com/repos/{owner}/{repo}/issues/{id}"
|
GITHUB_ISSUE_URL_TEMPLATE = "https://api.github.com/repos/{owner}/{repo}/issues/{id}"
|
||||||
HANDLE_MESSAGE_REGEX = re.compile(r"(?:([\w-]+)\/)?([\w-]+)?#(\d+)")
|
HANDLE_MESSAGE_REGEX = re.compile(r"(?:([\w-]+)\/)?([\w-]+)?#(\d+)")
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.config_info = bot_handler.get_config_info("github_detail", optional=True)
|
self.config_info = bot_handler.get_config_info("github_detail", optional=True)
|
||||||
self.owner = self.config_info.get("owner", False)
|
self.owner = self.config_info.get("owner", False)
|
||||||
self.repo = self.config_info.get("repo", False)
|
self.repo = self.config_info.get("repo", False)
|
||||||
|
@ -73,7 +73,7 @@ class GithubHandler:
|
||||||
repo = self.repo
|
repo = self.repo
|
||||||
return (owner, repo)
|
return (owner, repo)
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
# Send help message
|
# Send help message
|
||||||
if message["content"] == "help":
|
if message["content"] == "help":
|
||||||
bot_handler.send_reply(message, self.usage())
|
bot_handler.send_reply(message, self.usage())
|
||||||
|
|
|
@ -5,7 +5,7 @@ from typing import Dict, List
|
||||||
import requests
|
import requests
|
||||||
from bs4 import BeautifulSoup, Tag
|
from bs4 import BeautifulSoup, Tag
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
def google_search(keywords: str) -> List[Dict[str, str]]:
|
def google_search(keywords: str) -> List[Dict[str, str]]:
|
||||||
|
@ -83,7 +83,7 @@ class GoogleSearchHandler:
|
||||||
@mentioned-bot.
|
@mentioned-bot.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
original_content = message["content"]
|
original_content = message["content"]
|
||||||
result = get_google_result(original_content)
|
result = get_google_result(original_content)
|
||||||
bot_handler.send_reply(message, result)
|
bot_handler.send_reply(message, result)
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class HelloWorldHandler:
|
class HelloWorldHandler:
|
||||||
|
@ -15,7 +15,7 @@ class HelloWorldHandler:
|
||||||
sophisticated, bots.
|
sophisticated, bots.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, Any], bot_handler: AbstractBotHandler) -> None:
|
||||||
content = "beep boop"
|
content = "beep boop"
|
||||||
bot_handler.send_reply(message, content)
|
bot_handler.send_reply(message, content)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
# See readme.md for instructions on running this code.
|
# See readme.md for instructions on running this code.
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class HelpHandler:
|
class HelpHandler:
|
||||||
|
@ -15,7 +15,7 @@ class HelpHandler:
|
||||||
your Zulip instance.
|
your Zulip instance.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
help_content = "Info on Zulip can be found here:\nhttps://github.com/zulip/zulip"
|
help_content = "Info on Zulip can be found here:\nhttps://github.com/zulip/zulip"
|
||||||
bot_handler.send_reply(message, help_content)
|
bot_handler.send_reply(message, help_content)
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ from typing import Any, Dict, List, Optional
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
API_BASE_URL = "https://beta.idonethis.com/api/v2"
|
API_BASE_URL = "https://beta.idonethis.com/api/v2"
|
||||||
|
|
||||||
|
@ -147,7 +147,7 @@ More information in my help"""
|
||||||
|
|
||||||
|
|
||||||
class IDoneThisHandler:
|
class IDoneThisHandler:
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
global api_key, default_team # noqa: PLW0603
|
global api_key, default_team # noqa: PLW0603
|
||||||
self.config_info = bot_handler.get_config_info("idonethis")
|
self.config_info = bot_handler.get_config_info("idonethis")
|
||||||
if "api_key" in self.config_info:
|
if "api_key" in self.config_info:
|
||||||
|
@ -207,7 +207,7 @@ Below are some of the commands you can use, and what they do.
|
||||||
+ default_team_message
|
+ default_team_message
|
||||||
)
|
)
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, Any], bot_handler: AbstractBotHandler) -> None:
|
||||||
bot_handler.send_reply(message, self.get_response(message))
|
bot_handler.send_reply(message, self.get_response(message))
|
||||||
|
|
||||||
def get_response(self, message: Dict[str, Any]) -> str:
|
def get_response(self, message: Dict[str, Any]) -> str:
|
||||||
|
|
|
@ -2,7 +2,7 @@ import json
|
||||||
import re
|
import re
|
||||||
from typing import Any, Dict, Tuple
|
from typing import Any, Dict, Tuple
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
QUESTION = "How should we handle this?"
|
QUESTION = "How should we handle this?"
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ class IncidentHandler:
|
||||||
glue code here should be pretty portable.
|
glue code here should be pretty portable.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, Any], bot_handler: AbstractBotHandler) -> None:
|
||||||
query = message["content"]
|
query = message["content"]
|
||||||
if query.startswith("new "):
|
if query.startswith("new "):
|
||||||
start_new_incident(query, message, bot_handler)
|
start_new_incident(query, message, bot_handler)
|
||||||
|
@ -46,7 +46,9 @@ class IncidentHandler:
|
||||||
bot_handler.send_reply(message, bot_response)
|
bot_handler.send_reply(message, bot_response)
|
||||||
|
|
||||||
|
|
||||||
def start_new_incident(query: str, message: Dict[str, Any], bot_handler: BotHandler) -> None:
|
def start_new_incident(
|
||||||
|
query: str, message: Dict[str, Any], bot_handler: AbstractBotHandler
|
||||||
|
) -> None:
|
||||||
# Here is where we would enter the incident in some sort of backend
|
# Here is where we would enter the incident in some sort of backend
|
||||||
# system. We just simulate everything by having an incident id that
|
# system. We just simulate everything by having an incident id that
|
||||||
# we generate here.
|
# we generate here.
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
from typing import Dict, Final
|
from typing import Dict, Final
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler, use_storage
|
from zulip_bots.lib import AbstractBotHandler, use_storage
|
||||||
|
|
||||||
|
|
||||||
class IncrementorHandler:
|
class IncrementorHandler:
|
||||||
|
@ -19,13 +19,13 @@ class IncrementorHandler:
|
||||||
is @-mentioned, this number will be incremented in the same message.
|
is @-mentioned, this number will be incremented in the same message.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
storage = bot_handler.storage
|
storage = bot_handler.storage
|
||||||
if not storage.contains("number") or not storage.contains("message_id"):
|
if not storage.contains("number") or not storage.contains("message_id"):
|
||||||
storage.put("number", 0)
|
storage.put("number", 0)
|
||||||
storage.put("message_id", None)
|
storage.put("message_id", None)
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
with use_storage(bot_handler.storage, ["number"]) as storage:
|
with use_storage(bot_handler.storage, ["number"]) as storage:
|
||||||
num = storage.get("number")
|
num = storage.get("number")
|
||||||
|
|
||||||
|
|
|
@ -4,7 +4,7 @@ from typing import Any, Dict, Optional
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
GET_REGEX = re.compile('get "(?P<issue_key>.+)"$')
|
GET_REGEX = re.compile('get "(?P<issue_key>.+)"$')
|
||||||
CREATE_REGEX = re.compile(
|
CREATE_REGEX = re.compile(
|
||||||
|
@ -153,7 +153,7 @@ class JiraHandler:
|
||||||
Jira Bot, `jira.conf` must be set up. See `doc.md` for more details.
|
Jira Bot, `jira.conf` must be set up. See `doc.md` for more details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
config = bot_handler.get_config_info("jira")
|
config = bot_handler.get_config_info("jira")
|
||||||
|
|
||||||
username = config.get("username")
|
username = config.get("username")
|
||||||
|
@ -205,7 +205,7 @@ class JiraHandler:
|
||||||
|
|
||||||
return response
|
return response
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
content = message.get("content")
|
content = message.get("content")
|
||||||
response = ""
|
response = ""
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ from typing import Any, Dict
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class LinkShortenerHandler:
|
class LinkShortenerHandler:
|
||||||
|
@ -18,11 +18,11 @@ class LinkShortenerHandler:
|
||||||
"`key` must be set in `link_shortener.conf`."
|
"`key` must be set in `link_shortener.conf`."
|
||||||
)
|
)
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.config_info = bot_handler.get_config_info("link_shortener")
|
self.config_info = bot_handler.get_config_info("link_shortener")
|
||||||
self.check_api_key(bot_handler)
|
self.check_api_key(bot_handler)
|
||||||
|
|
||||||
def check_api_key(self, bot_handler: BotHandler) -> None:
|
def check_api_key(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
test_request_data: Any = self.call_link_shorten_service("www.youtube.com/watch")
|
test_request_data: Any = self.call_link_shorten_service("www.youtube.com/watch")
|
||||||
try:
|
try:
|
||||||
if self.is_invalid_token_error(test_request_data):
|
if self.is_invalid_token_error(test_request_data):
|
||||||
|
@ -38,7 +38,7 @@ class LinkShortenerHandler:
|
||||||
and response_json["status_txt"] == "INVALID_ARG_ACCESS_TOKEN"
|
and response_json["status_txt"] == "INVALID_ARG_ACCESS_TOKEN"
|
||||||
)
|
)
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
regex_str = (
|
regex_str = (
|
||||||
r"("
|
r"("
|
||||||
r"(?:http|https):\/\/" # This allows for the HTTP or HTTPS
|
r"(?:http|https):\/\/" # This allows for the HTTP or HTTPS
|
||||||
|
|
|
@ -4,18 +4,18 @@ from typing import Any, Dict, List
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class MentionHandler:
|
class MentionHandler:
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.config_info = bot_handler.get_config_info("mention")
|
self.config_info = bot_handler.get_config_info("mention")
|
||||||
self.access_token = self.config_info["access_token"]
|
self.access_token = self.config_info["access_token"]
|
||||||
self.account_id = ""
|
self.account_id = ""
|
||||||
|
|
||||||
self.check_access_token(bot_handler)
|
self.check_access_token(bot_handler)
|
||||||
|
|
||||||
def check_access_token(self, bot_handler: BotHandler) -> None:
|
def check_access_token(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
test_query_header = {
|
test_query_header = {
|
||||||
"Authorization": "Bearer " + self.access_token,
|
"Authorization": "Bearer " + self.access_token,
|
||||||
"Accept-Version": "1.15",
|
"Accept-Version": "1.15",
|
||||||
|
@ -43,7 +43,7 @@ class MentionHandler:
|
||||||
Version 1.00
|
Version 1.00
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, Any], bot_handler: AbstractBotHandler) -> None:
|
||||||
message["content"] = message["content"].strip()
|
message["content"] = message["content"].strip()
|
||||||
|
|
||||||
if message["content"].lower() == "help":
|
if message["content"].lower() == "help":
|
||||||
|
|
|
@ -2,7 +2,7 @@ import logging
|
||||||
from typing import Dict
|
from typing import Dict
|
||||||
|
|
||||||
from zulip_bots.bots.monkeytestit.lib import parse
|
from zulip_bots.bots.monkeytestit.lib import parse
|
||||||
from zulip_bots.lib import BotHandler, NoBotConfigError
|
from zulip_bots.lib import AbstractBotHandler, NoBotConfigError
|
||||||
|
|
||||||
|
|
||||||
class MonkeyTestitBot:
|
class MonkeyTestitBot:
|
||||||
|
@ -17,7 +17,7 @@ class MonkeyTestitBot:
|
||||||
"Check doc.md for more options and setup instructions."
|
"Check doc.md for more options and setup instructions."
|
||||||
)
|
)
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
try:
|
try:
|
||||||
self.config = bot_handler.get_config_info("monkeytestit")
|
self.config = bot_handler.get_config_info("monkeytestit")
|
||||||
except NoBotConfigError:
|
except NoBotConfigError:
|
||||||
|
@ -47,7 +47,7 @@ class MonkeyTestitBot:
|
||||||
" your api_key value and try again."
|
" your api_key value and try again."
|
||||||
)
|
)
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
content = message["content"]
|
content = message["content"]
|
||||||
|
|
||||||
response = parse.execute(content, self.api_key)
|
response = parse.execute(content, self.api_key)
|
||||||
|
|
|
@ -10,7 +10,7 @@ from simple_salesforce import Salesforce # type: ignore[attr-defined]
|
||||||
from simple_salesforce.exceptions import SalesforceAuthenticationFailed
|
from simple_salesforce.exceptions import SalesforceAuthenticationFailed
|
||||||
|
|
||||||
from zulip_bots.bots.salesforce.utils import commands, default_query, link_query, object_types
|
from zulip_bots.bots.salesforce.utils import commands, default_query, link_query, object_types
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
base_help_text = """Salesforce bot
|
base_help_text = """Salesforce bot
|
||||||
This bot can do simple salesforce query requests
|
This bot can do simple salesforce query requests
|
||||||
|
@ -162,7 +162,7 @@ class SalesforceHandler:
|
||||||
return "Usage: {} [arguments]".format(command["template"])
|
return "Usage: {} [arguments]".format(command["template"])
|
||||||
return get_help_text()
|
return get_help_text()
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.config_info = bot_handler.get_config_info("salesforce")
|
self.config_info = bot_handler.get_config_info("salesforce")
|
||||||
try:
|
try:
|
||||||
self.sf = Salesforce(
|
self.sf = Salesforce(
|
||||||
|
@ -173,7 +173,7 @@ class SalesforceHandler:
|
||||||
except SalesforceAuthenticationFailed as err:
|
except SalesforceAuthenticationFailed as err:
|
||||||
bot_handler.quit(f"Failed to log in to Salesforce. {err.code} {err.message}")
|
bot_handler.quit(f"Failed to log in to Salesforce. {err.code} {err.message}")
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, Any], bot_handler: AbstractBotHandler) -> None:
|
||||||
try:
|
try:
|
||||||
bot_response = self.get_salesforce_response(message["content"])
|
bot_response = self.get_salesforce_response(message["content"])
|
||||||
bot_handler.send_reply(message, bot_response)
|
bot_handler.send_reply(message, bot_response)
|
||||||
|
|
|
@ -3,7 +3,7 @@ from typing import Dict, Final, Optional
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
# See readme.md for instructions on running this code.
|
# See readme.md for instructions on running this code.
|
||||||
|
|
||||||
|
@ -31,12 +31,12 @@ class StackOverflowHandler:
|
||||||
should preface query with "@mention-bot".
|
should preface query with "@mention-bot".
|
||||||
@mention-bot <search query>"""
|
@mention-bot <search query>"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
bot_response = self.get_bot_stackoverflow_response(message, bot_handler)
|
bot_response = self.get_bot_stackoverflow_response(message, bot_handler)
|
||||||
bot_handler.send_reply(message, bot_response)
|
bot_handler.send_reply(message, bot_response)
|
||||||
|
|
||||||
def get_bot_stackoverflow_response(
|
def get_bot_stackoverflow_response(
|
||||||
self, message: Dict[str, str], bot_handler: BotHandler
|
self, message: Dict[str, str], bot_handler: AbstractBotHandler
|
||||||
) -> Optional[str]:
|
) -> Optional[str]:
|
||||||
"""This function returns the URLs of the requested topic."""
|
"""This function returns the URLs of the requested topic."""
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ from typing import Dict
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class SusiHandler:
|
class SusiHandler:
|
||||||
|
@ -38,7 +38,7 @@ class SusiHandler:
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
msg = message["content"]
|
msg = message["content"]
|
||||||
if msg in ("help", ""):
|
if msg in ("help", ""):
|
||||||
bot_handler.send_reply(message, self.usage())
|
bot_handler.send_reply(message, self.usage())
|
||||||
|
|
|
@ -2,7 +2,7 @@ from typing import Any, Dict, List
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
supported_commands = [
|
supported_commands = [
|
||||||
("help", "Get the bot usage information."),
|
("help", "Get the bot usage information."),
|
||||||
|
@ -18,7 +18,7 @@ RESPONSE_ERROR_MESSAGE = "Invalid Response. Please check configuration and param
|
||||||
|
|
||||||
|
|
||||||
class TrelloHandler:
|
class TrelloHandler:
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.config_info = bot_handler.get_config_info("trello")
|
self.config_info = bot_handler.get_config_info("trello")
|
||||||
self.api_key = self.config_info["api_key"]
|
self.api_key = self.config_info["api_key"]
|
||||||
self.access_token = self.config_info["access_token"]
|
self.access_token = self.config_info["access_token"]
|
||||||
|
@ -28,7 +28,7 @@ class TrelloHandler:
|
||||||
|
|
||||||
self.check_access_token(bot_handler)
|
self.check_access_token(bot_handler)
|
||||||
|
|
||||||
def check_access_token(self, bot_handler: BotHandler) -> None:
|
def check_access_token(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
test_query_response = requests.get(
|
test_query_response = requests.get(
|
||||||
f"https://api.trello.com/1/members/{self.user_name}/", params=self.auth_params
|
f"https://api.trello.com/1/members/{self.user_name}/", params=self.auth_params
|
||||||
)
|
)
|
||||||
|
@ -43,7 +43,7 @@ class TrelloHandler:
|
||||||
Use `list-commands` to get information about the supported commands.
|
Use `list-commands` to get information about the supported commands.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, Any], bot_handler: AbstractBotHandler) -> None:
|
||||||
content = message["content"].strip().split()
|
content = message["content"].strip().split()
|
||||||
|
|
||||||
if content == []:
|
if content == []:
|
||||||
|
|
|
@ -6,7 +6,7 @@ from typing import Any, Dict, Tuple
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class NotAvailableError(Exception):
|
class NotAvailableError(Exception):
|
||||||
|
@ -23,7 +23,7 @@ class TriviaQuizHandler:
|
||||||
This plugin will give users a trivia question from
|
This plugin will give users a trivia question from
|
||||||
the open trivia database at opentdb.com."""
|
the open trivia database at opentdb.com."""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, Any], bot_handler: AbstractBotHandler) -> None:
|
||||||
query = message["content"]
|
query = message["content"]
|
||||||
if query == "new":
|
if query == "new":
|
||||||
try:
|
try:
|
||||||
|
@ -59,11 +59,11 @@ class TriviaQuizHandler:
|
||||||
bot_handler.send_reply(message, bot_response)
|
bot_handler.send_reply(message, bot_response)
|
||||||
|
|
||||||
|
|
||||||
def get_quiz_from_id(quiz_id: str, bot_handler: BotHandler) -> str:
|
def get_quiz_from_id(quiz_id: str, bot_handler: AbstractBotHandler) -> str:
|
||||||
return bot_handler.storage.get(quiz_id)
|
return bot_handler.storage.get(quiz_id)
|
||||||
|
|
||||||
|
|
||||||
def start_new_quiz(message: Dict[str, Any], bot_handler: BotHandler) -> None:
|
def start_new_quiz(message: Dict[str, Any], bot_handler: AbstractBotHandler) -> None:
|
||||||
quiz = get_trivia_quiz()
|
quiz = get_trivia_quiz()
|
||||||
quiz_id = generate_quiz_id(bot_handler.storage)
|
quiz_id = generate_quiz_id(bot_handler.storage)
|
||||||
bot_response = format_quiz_for_markdown(quiz_id, quiz)
|
bot_response = format_quiz_for_markdown(quiz_id, quiz)
|
||||||
|
@ -188,7 +188,7 @@ Q: {question}
|
||||||
return content
|
return content
|
||||||
|
|
||||||
|
|
||||||
def update_quiz(quiz: Dict[str, Any], quiz_id: str, bot_handler: BotHandler) -> None:
|
def update_quiz(quiz: Dict[str, Any], quiz_id: str, bot_handler: AbstractBotHandler) -> None:
|
||||||
bot_handler.storage.put(quiz_id, json.dumps(quiz))
|
bot_handler.storage.put(quiz_id, json.dumps(quiz))
|
||||||
|
|
||||||
|
|
||||||
|
@ -203,7 +203,11 @@ def build_response(is_correct: bool, num_answers: int) -> str:
|
||||||
|
|
||||||
|
|
||||||
def handle_answer(
|
def handle_answer(
|
||||||
quiz: Dict[str, Any], option: str, quiz_id: str, bot_handler: BotHandler, sender_name: str
|
quiz: Dict[str, Any],
|
||||||
|
option: str,
|
||||||
|
quiz_id: str,
|
||||||
|
bot_handler: AbstractBotHandler,
|
||||||
|
sender_name: str,
|
||||||
) -> Tuple[bool, str]:
|
) -> Tuple[bool, str]:
|
||||||
answer = quiz["answers"][quiz["correct_letter"]]
|
answer = quiz["answers"][quiz["correct_letter"]]
|
||||||
is_new_answer = option not in quiz["answered_options"]
|
is_new_answer = option not in quiz["answered_options"]
|
||||||
|
|
|
@ -2,7 +2,7 @@ from typing import Dict
|
||||||
|
|
||||||
import tweepy
|
import tweepy
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class TwitpostBot:
|
class TwitpostBot:
|
||||||
|
@ -21,7 +21,7 @@ class TwitpostBot:
|
||||||
" * @twitpost tweet hey batman\n"
|
" * @twitpost tweet hey batman\n"
|
||||||
)
|
)
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.config_info = bot_handler.get_config_info("twitter")
|
self.config_info = bot_handler.get_config_info("twitter")
|
||||||
auth = tweepy.OAuthHandler(
|
auth = tweepy.OAuthHandler(
|
||||||
self.config_info["consumer_key"], self.config_info["consumer_secret"]
|
self.config_info["consumer_key"], self.config_info["consumer_secret"]
|
||||||
|
@ -31,7 +31,7 @@ class TwitpostBot:
|
||||||
)
|
)
|
||||||
self.api = tweepy.API(auth, parser=tweepy.parsers.JSONParser())
|
self.api = tweepy.API(auth, parser=tweepy.parsers.JSONParser())
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
content = message["content"]
|
content = message["content"]
|
||||||
|
|
||||||
if content.strip() == "":
|
if content.strip() == "":
|
||||||
|
|
|
@ -4,7 +4,7 @@ import os
|
||||||
import re
|
import re
|
||||||
from typing import Any, Dict, Final, List, Set, Tuple, Union
|
from typing import Any, Dict, Final, List, Set, Tuple, Union
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class VirtualFsHandler:
|
class VirtualFsHandler:
|
||||||
|
@ -16,7 +16,7 @@ class VirtualFsHandler:
|
||||||
def usage(self) -> str:
|
def usage(self) -> str:
|
||||||
return get_help()
|
return get_help()
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, Any], bot_handler: AbstractBotHandler) -> None:
|
||||||
command = message["content"]
|
command = message["content"]
|
||||||
if command == "":
|
if command == "":
|
||||||
command = "help"
|
command = "help"
|
||||||
|
|
|
@ -3,18 +3,18 @@ from typing import Any, Dict
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
api_url = "http://api.openweathermap.org/data/2.5/weather"
|
api_url = "http://api.openweathermap.org/data/2.5/weather"
|
||||||
|
|
||||||
|
|
||||||
class WeatherHandler:
|
class WeatherHandler:
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.api_key = bot_handler.get_config_info("weather")["key"]
|
self.api_key = bot_handler.get_config_info("weather")["key"]
|
||||||
self.response_pattern = "Weather in {}, {}:\n{:.2f} F / {:.2f} C\n{}"
|
self.response_pattern = "Weather in {}, {}:\n{:.2f} F / {:.2f} C\n{}"
|
||||||
self.check_api_key(bot_handler)
|
self.check_api_key(bot_handler)
|
||||||
|
|
||||||
def check_api_key(self, bot_handler: BotHandler) -> None:
|
def check_api_key(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
api_params = dict(q="nyc", APPID=self.api_key)
|
api_params = dict(q="nyc", APPID=self.api_key)
|
||||||
test_response = requests.get(api_url, params=api_params)
|
test_response = requests.get(api_url, params=api_params)
|
||||||
try:
|
try:
|
||||||
|
@ -29,7 +29,7 @@ class WeatherHandler:
|
||||||
This plugin will give info about weather in a specified city
|
This plugin will give info about weather in a specified city
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
help_content = """
|
help_content = """
|
||||||
This bot returns weather info for specified city.
|
This bot returns weather info for specified city.
|
||||||
You specify city in the following format:
|
You specify city in the following format:
|
||||||
|
|
|
@ -3,7 +3,7 @@ from typing import Dict, Final
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
# See readme.md for instructions on running this code.
|
# See readme.md for instructions on running this code.
|
||||||
|
|
||||||
|
@ -33,11 +33,13 @@ class WikipediaHandler:
|
||||||
should preface searches with "@mention-bot".
|
should preface searches with "@mention-bot".
|
||||||
@mention-bot <name of article>"""
|
@mention-bot <name of article>"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
bot_response = self.get_bot_wiki_response(message, bot_handler)
|
bot_response = self.get_bot_wiki_response(message, bot_handler)
|
||||||
bot_handler.send_reply(message, bot_response)
|
bot_handler.send_reply(message, bot_response)
|
||||||
|
|
||||||
def get_bot_wiki_response(self, message: Dict[str, str], bot_handler: BotHandler) -> str:
|
def get_bot_wiki_response(
|
||||||
|
self, message: Dict[str, str], bot_handler: AbstractBotHandler
|
||||||
|
) -> str:
|
||||||
"""This function returns the URLs of the requested topic."""
|
"""This function returns the URLs of the requested topic."""
|
||||||
|
|
||||||
help_text = "Please enter your search term after {}"
|
help_text = "Please enter your search term after {}"
|
||||||
|
|
|
@ -6,7 +6,7 @@ from typing import Any, Callable, Dict, Optional
|
||||||
|
|
||||||
import wit
|
import wit
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class WitaiHandler:
|
class WitaiHandler:
|
||||||
|
@ -16,7 +16,7 @@ class WitaiHandler:
|
||||||
Wit.ai bot, `witai.conf` must be set up. See `doc.md` for more details.
|
Wit.ai bot, `witai.conf` must be set up. See `doc.md` for more details.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
config = bot_handler.get_config_info("witai")
|
config = bot_handler.get_config_info("witai")
|
||||||
|
|
||||||
token = config.get("token")
|
token = config.get("token")
|
||||||
|
@ -37,7 +37,7 @@ class WitaiHandler:
|
||||||
|
|
||||||
self.client = wit.Wit(token)
|
self.client = wit.Wit(token)
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
if message["content"] == "" or message["content"] == "help":
|
if message["content"] == "" or message["content"] == "help":
|
||||||
bot_handler.send_reply(message, self.help_message)
|
bot_handler.send_reply(message, self.help_message)
|
||||||
return
|
return
|
||||||
|
|
|
@ -4,7 +4,7 @@ from typing import Dict, Final, Optional
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
XKCD_TEMPLATE_URL = "https://xkcd.com/%s/info.0.json"
|
XKCD_TEMPLATE_URL = "https://xkcd.com/%s/info.0.json"
|
||||||
LATEST_XKCD_URL = "https://xkcd.com/info.0.json"
|
LATEST_XKCD_URL = "https://xkcd.com/info.0.json"
|
||||||
|
@ -36,7 +36,7 @@ class XkcdHandler:
|
||||||
`<comic_id>`, e.g `@mention-bot 1234`.
|
`<comic_id>`, e.g `@mention-bot 1234`.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
quoted_name = bot_handler.identity().mention
|
quoted_name = bot_handler.identity().mention
|
||||||
xkcd_bot_response = get_xkcd_bot_response(message, quoted_name)
|
xkcd_bot_response = get_xkcd_bot_response(message, quoted_name)
|
||||||
bot_handler.send_reply(message, xkcd_bot_response)
|
bot_handler.send_reply(message, xkcd_bot_response)
|
||||||
|
|
|
@ -5,7 +5,7 @@ from typing import Dict
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
HELP_MESSAGE = """
|
HELP_MESSAGE = """
|
||||||
This bot allows users to translate a sentence into
|
This bot allows users to translate a sentence into
|
||||||
|
@ -36,7 +36,7 @@ class YodaSpeakHandler:
|
||||||
It looks for messages starting with '@mention-bot'.
|
It looks for messages starting with '@mention-bot'.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.api_key = bot_handler.get_config_info("yoda")["api_key"]
|
self.api_key = bot_handler.get_config_info("yoda")["api_key"]
|
||||||
|
|
||||||
def usage(self) -> str:
|
def usage(self) -> str:
|
||||||
|
@ -53,7 +53,7 @@ class YodaSpeakHandler:
|
||||||
@mention-bot You will learn how to speak like me someday.
|
@mention-bot You will learn how to speak like me someday.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
self.handle_input(message, bot_handler)
|
self.handle_input(message, bot_handler)
|
||||||
|
|
||||||
def send_to_yoda_api(self, sentence: str) -> str:
|
def send_to_yoda_api(self, sentence: str) -> str:
|
||||||
|
@ -89,7 +89,7 @@ class YodaSpeakHandler:
|
||||||
sentence = message_content.replace(" ", "+")
|
sentence = message_content.replace(" ", "+")
|
||||||
return sentence
|
return sentence
|
||||||
|
|
||||||
def handle_input(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_input(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
original_content = message["content"]
|
original_content = message["content"]
|
||||||
|
|
||||||
if self.is_help(original_content) or original_content == "":
|
if self.is_help(original_content) or original_content == "":
|
||||||
|
@ -116,7 +116,7 @@ class YodaSpeakHandler:
|
||||||
bot_handler.send_reply(message, reply_message)
|
bot_handler.send_reply(message, reply_message)
|
||||||
|
|
||||||
def send_message(
|
def send_message(
|
||||||
self, bot_handler: BotHandler, message: str, stream: str, subject: str
|
self, bot_handler: AbstractBotHandler, message: str, stream: str, subject: str
|
||||||
) -> None:
|
) -> None:
|
||||||
# function for sending a message
|
# function for sending a message
|
||||||
bot_handler.send_message(dict(type="stream", to=stream, subject=subject, content=message))
|
bot_handler.send_message(dict(type="stream", to=stream, subject=subject, content=message))
|
||||||
|
|
|
@ -4,7 +4,7 @@ from typing import Dict, List, Optional, Tuple, Union
|
||||||
import requests
|
import requests
|
||||||
from requests.exceptions import ConnectionError, HTTPError
|
from requests.exceptions import ConnectionError, HTTPError
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
commands_list = ("list", "top", "help")
|
commands_list = ("list", "top", "help")
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ class YoutubeHandler:
|
||||||
" * @mention-bot list funny dogs"
|
" * @mention-bot list funny dogs"
|
||||||
)
|
)
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.config_info = bot_handler.get_config_info("youtube")
|
self.config_info = bot_handler.get_config_info("youtube")
|
||||||
# Check if API key is valid. If it is not valid, don't run the bot.
|
# Check if API key is valid. If it is not valid, don't run the bot.
|
||||||
try:
|
try:
|
||||||
|
@ -44,7 +44,7 @@ class YoutubeHandler:
|
||||||
except ConnectionError:
|
except ConnectionError:
|
||||||
logging.warning("Bad connection")
|
logging.warning("Bad connection")
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
if message["content"] == "" or message["content"] == "help":
|
if message["content"] == "" or message["content"] == "help":
|
||||||
bot_handler.send_reply(message, self.help_content)
|
bot_handler.send_reply(message, self.help_content)
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -8,7 +8,7 @@ from typing import Any, Dict, Iterable, List, Sequence, Tuple
|
||||||
|
|
||||||
from typing_extensions import override
|
from typing_extensions import override
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
|
|
||||||
|
|
||||||
class BadMoveError(Exception):
|
class BadMoveError(Exception):
|
||||||
|
@ -204,13 +204,13 @@ class GameAdapter:
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
|
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: AbstractBotHandler) -> None:
|
||||||
self.bot_handler = bot_handler
|
self.bot_handler = bot_handler
|
||||||
self.get_user_cache()
|
self.get_user_cache()
|
||||||
self.email = self.bot_handler.email
|
self.email = self.bot_handler.email
|
||||||
self.full_name = self.bot_handler.full_name
|
self.full_name = self.bot_handler.full_name
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, Any], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, Any], bot_handler: AbstractBotHandler) -> None:
|
||||||
try:
|
try:
|
||||||
self.bot_handler = bot_handler
|
self.bot_handler = bot_handler
|
||||||
content = message["content"].strip()
|
content = message["content"].strip()
|
||||||
|
|
|
@ -92,7 +92,7 @@ class BotStorage(Protocol):
|
||||||
|
|
||||||
class CachedStorage:
|
class CachedStorage:
|
||||||
def __init__(self, parent_storage: BotStorage, init_data: Dict[str, Any]) -> None:
|
def __init__(self, parent_storage: BotStorage, init_data: Dict[str, Any]) -> None:
|
||||||
# CachedStorage is implemented solely for the context manager of any BotHandler.
|
# CachedStorage is implemented solely for the context manager of any AbstractBotHandler.
|
||||||
# It has a parent_storage that is responsible of communicating with the database
|
# It has a parent_storage that is responsible of communicating with the database
|
||||||
# 1. when certain data is not cached;
|
# 1. when certain data is not cached;
|
||||||
# 2. when the data need to be flushed to the database.
|
# 2. when the data need to be flushed to the database.
|
||||||
|
@ -176,7 +176,7 @@ def use_storage(storage: BotStorage, keys: List[str]) -> Iterator[BotStorage]:
|
||||||
cache.flush()
|
cache.flush()
|
||||||
|
|
||||||
|
|
||||||
class BotHandler(Protocol):
|
class AbstractBotHandler(Protocol):
|
||||||
user_id: int
|
user_id: int
|
||||||
email: str
|
email: str
|
||||||
full_name: str
|
full_name: str
|
||||||
|
@ -378,7 +378,9 @@ class ExternalBotHandler:
|
||||||
sys.exit(message)
|
sys.exit(message)
|
||||||
|
|
||||||
|
|
||||||
def extract_query_without_mention(message: Dict[str, Any], client: BotHandler) -> Optional[str]:
|
def extract_query_without_mention(
|
||||||
|
message: Dict[str, Any], client: AbstractBotHandler
|
||||||
|
) -> Optional[str]:
|
||||||
"""
|
"""
|
||||||
If the bot is the first @mention in the message, then this function returns
|
If the bot is the first @mention in the message, then this function returns
|
||||||
the stripped message with the bot's @mention removed. Otherwise, it returns None.
|
the stripped message with the bot's @mention removed. Otherwise, it returns None.
|
||||||
|
@ -398,7 +400,7 @@ def extract_query_without_mention(message: Dict[str, Any], client: BotHandler) -
|
||||||
|
|
||||||
|
|
||||||
def is_private_message_but_not_group_pm(
|
def is_private_message_but_not_group_pm(
|
||||||
message_dict: Dict[str, Any], current_user: BotHandler
|
message_dict: Dict[str, Any], current_user: AbstractBotHandler
|
||||||
) -> bool:
|
) -> bool:
|
||||||
"""
|
"""
|
||||||
Checks whether a message dict represents a PM from another user.
|
Checks whether a message dict represents a PM from another user.
|
||||||
|
@ -422,7 +424,7 @@ def display_config_file_errors(error_msg: str, config_file: str) -> None:
|
||||||
print(f"\nMore details here:\n\n{error_msg}\n")
|
print(f"\nMore details here:\n\n{error_msg}\n")
|
||||||
|
|
||||||
|
|
||||||
def prepare_message_handler(bot: str, bot_handler: BotHandler, bot_lib_module: Any) -> Any:
|
def prepare_message_handler(bot: str, bot_handler: AbstractBotHandler, bot_lib_module: Any) -> Any:
|
||||||
message_handler = bot_lib_module.handler_class()
|
message_handler = bot_lib_module.handler_class()
|
||||||
if hasattr(message_handler, "validate_config"):
|
if hasattr(message_handler, "validate_config"):
|
||||||
config_data = bot_handler.get_config_info(bot)
|
config_data = bot_handler.get_config_info(bot)
|
||||||
|
|
|
@ -5,7 +5,7 @@ from unittest.mock import ANY, MagicMock, create_autospec, patch
|
||||||
|
|
||||||
from zulip import Client
|
from zulip import Client
|
||||||
from zulip_bots.lib import (
|
from zulip_bots.lib import (
|
||||||
BotHandler,
|
AbstractBotHandler,
|
||||||
ExternalBotHandler,
|
ExternalBotHandler,
|
||||||
StateHandler,
|
StateHandler,
|
||||||
extract_query_without_mention,
|
extract_query_without_mention,
|
||||||
|
@ -53,10 +53,10 @@ class FakeBotHandler:
|
||||||
def usage(self) -> str:
|
def usage(self) -> str:
|
||||||
return """
|
return """
|
||||||
This is a fake bot handler that is used
|
This is a fake bot handler that is used
|
||||||
to spec BotHandler mocks.
|
to spec AbstractBotHandler mocks.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ from unittest import mock
|
||||||
import importlib_metadata as metadata
|
import importlib_metadata as metadata
|
||||||
from typing_extensions import override
|
from typing_extensions import override
|
||||||
|
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import AbstractBotHandler
|
||||||
from zulip_botserver import server
|
from zulip_botserver import server
|
||||||
from zulip_botserver.input_parameters import parse_args
|
from zulip_botserver.input_parameters import parse_args
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ from .server_test_lib import BotServerTestCase
|
||||||
|
|
||||||
class BotServerTests(BotServerTestCase):
|
class BotServerTests(BotServerTestCase):
|
||||||
class MockMessageHandler:
|
class MockMessageHandler:
|
||||||
def handle_message(self, message: Dict[str, str], bot_handler: BotHandler) -> None:
|
def handle_message(self, message: Dict[str, str], bot_handler: AbstractBotHandler) -> None:
|
||||||
assert message == {"key": "test message"}
|
assert message == {"key": "test message"}
|
||||||
|
|
||||||
class MockLibModule:
|
class MockLibModule:
|
||||||
|
|
Loading…
Add table
Reference in a new issue