ruff: Fix N818 Exception name should be named with an Error suffix.
Signed-off-by: Anders Kaseorg <anders@zulip.com>
This commit is contained in:
parent
a8aec780d2
commit
54263e5d52
30 changed files with 124 additions and 124 deletions
|
@ -35,15 +35,15 @@ ZULIP_MESSAGE_TEMPLATE: str = "**{username}** [{uid}]: {message}"
|
||||||
MATRIX_MESSAGE_TEMPLATE: str = "<{username} ({uid})> {message}"
|
MATRIX_MESSAGE_TEMPLATE: str = "<{username} ({uid})> {message}"
|
||||||
|
|
||||||
|
|
||||||
class BridgeConfigException(Exception):
|
class BridgeConfigError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BridgeFatalMatrixException(Exception):
|
class BridgeFatalMatrixError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class BridgeFatalZulipException(Exception):
|
class BridgeFatalZulipError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ class MatrixToZulip:
|
||||||
# the new messages and not with all the old ones.
|
# the new messages and not with all the old ones.
|
||||||
sync_response: Union[SyncResponse, SyncError] = await matrix_client.sync()
|
sync_response: Union[SyncResponse, SyncError] = await matrix_client.sync()
|
||||||
if isinstance(sync_response, nio.SyncError):
|
if isinstance(sync_response, nio.SyncError):
|
||||||
raise BridgeFatalMatrixException(sync_response.message)
|
raise BridgeFatalMatrixError(sync_response.message)
|
||||||
|
|
||||||
return matrix_to_zulip
|
return matrix_to_zulip
|
||||||
|
|
||||||
|
@ -117,10 +117,10 @@ class MatrixToZulip:
|
||||||
)
|
)
|
||||||
except Exception as exception:
|
except Exception as exception:
|
||||||
# Generally raised when user is forbidden
|
# Generally raised when user is forbidden
|
||||||
raise BridgeFatalZulipException(exception)
|
raise BridgeFatalZulipError(exception)
|
||||||
if result["result"] != "success":
|
if result["result"] != "success":
|
||||||
# Generally raised when API key is invalid
|
# Generally raised when API key is invalid
|
||||||
raise BridgeFatalZulipException(result["msg"])
|
raise BridgeFatalZulipError(result["msg"])
|
||||||
|
|
||||||
# Update the bot's read marker in order to show the other users which
|
# Update the bot's read marker in order to show the other users which
|
||||||
# messages are already processed by the bot.
|
# messages are already processed by the bot.
|
||||||
|
@ -194,14 +194,14 @@ class MatrixToZulip:
|
||||||
for room_id in self.matrix_config["bridges"]:
|
for room_id in self.matrix_config["bridges"]:
|
||||||
result: Union[JoinResponse, JoinError] = await self.matrix_client.join(room_id)
|
result: Union[JoinResponse, JoinError] = await self.matrix_client.join(room_id)
|
||||||
if isinstance(result, nio.JoinError):
|
if isinstance(result, nio.JoinError):
|
||||||
raise BridgeFatalMatrixException(str(result))
|
raise BridgeFatalMatrixError(str(result))
|
||||||
|
|
||||||
async def matrix_login(self) -> None:
|
async def matrix_login(self) -> None:
|
||||||
result: Union[LoginResponse, LoginError] = await self.matrix_client.login(
|
result: Union[LoginResponse, LoginError] = await self.matrix_client.login(
|
||||||
self.matrix_config["password"]
|
self.matrix_config["password"]
|
||||||
)
|
)
|
||||||
if isinstance(result, nio.LoginError):
|
if isinstance(result, nio.LoginError):
|
||||||
raise BridgeFatalMatrixException(str(result))
|
raise BridgeFatalMatrixError(str(result))
|
||||||
|
|
||||||
async def run(self) -> None:
|
async def run(self) -> None:
|
||||||
print("Starting message handler on Matrix client")
|
print("Starting message handler on Matrix client")
|
||||||
|
@ -230,7 +230,7 @@ class ZulipToMatrix:
|
||||||
# Precompute the url of the Zulip server, needed later.
|
# Precompute the url of the Zulip server, needed later.
|
||||||
result: Dict[str, Any] = self.zulip_client.get_server_settings()
|
result: Dict[str, Any] = self.zulip_client.get_server_settings()
|
||||||
if result["result"] != "success":
|
if result["result"] != "success":
|
||||||
raise BridgeFatalZulipException("cannot get server settings")
|
raise BridgeFatalZulipError("cannot get server settings")
|
||||||
self.server_url: str = result["realm_uri"]
|
self.server_url: str = result["realm_uri"]
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -250,7 +250,7 @@ class ZulipToMatrix:
|
||||||
self.matrix_client.room_send(**kwargs), self.loop
|
self.matrix_client.room_send(**kwargs), self.loop
|
||||||
).result()
|
).result()
|
||||||
if isinstance(result, nio.RoomSendError):
|
if isinstance(result, nio.RoomSendError):
|
||||||
raise BridgeFatalMatrixException(str(result))
|
raise BridgeFatalMatrixError(str(result))
|
||||||
|
|
||||||
def _zulip_to_matrix(self, msg: Dict[str, Any]) -> None:
|
def _zulip_to_matrix(self, msg: Dict[str, Any]) -> None:
|
||||||
logging.debug("_zulip_to_matrix; msg: %s", msg)
|
logging.debug("_zulip_to_matrix; msg: %s", msg)
|
||||||
|
@ -303,12 +303,12 @@ class ZulipToMatrix:
|
||||||
for stream, _ in self.zulip_config["bridges"]:
|
for stream, _ in self.zulip_config["bridges"]:
|
||||||
result: Dict[str, Any] = self.zulip_client.get_stream_id(stream)
|
result: Dict[str, Any] = self.zulip_client.get_stream_id(stream)
|
||||||
if result["result"] == "error":
|
if result["result"] == "error":
|
||||||
raise BridgeFatalZulipException(f"cannot access stream '{stream}': {result}")
|
raise BridgeFatalZulipError(f"cannot access stream '{stream}': {result}")
|
||||||
if result["result"] != "success":
|
if result["result"] != "success":
|
||||||
raise BridgeFatalZulipException(f"cannot checkout stream id for stream '{stream}'")
|
raise BridgeFatalZulipError(f"cannot checkout stream id for stream '{stream}'")
|
||||||
result = self.zulip_client.add_subscriptions(streams=[{"name": stream}])
|
result = self.zulip_client.add_subscriptions(streams=[{"name": stream}])
|
||||||
if result["result"] != "success":
|
if result["result"] != "success":
|
||||||
raise BridgeFatalZulipException(f"cannot subscribe to stream '{stream}': {result}")
|
raise BridgeFatalZulipError(f"cannot subscribe to stream '{stream}': {result}")
|
||||||
|
|
||||||
def get_matrix_room_for_zulip_message(self, msg: Dict[str, Any]) -> Optional[str]:
|
def get_matrix_room_for_zulip_message(self, msg: Dict[str, Any]) -> Optional[str]:
|
||||||
"""Check whether we want to process the given message.
|
"""Check whether we want to process the given message.
|
||||||
|
@ -459,10 +459,10 @@ def read_configuration(config_file: str) -> Dict[str, Dict[str, Any]]:
|
||||||
try:
|
try:
|
||||||
config.read(config_file)
|
config.read(config_file)
|
||||||
except configparser.Error as exception:
|
except configparser.Error as exception:
|
||||||
raise BridgeConfigException(str(exception))
|
raise BridgeConfigError(str(exception))
|
||||||
|
|
||||||
if set(config.sections()) < {"matrix", "zulip"}:
|
if set(config.sections()) < {"matrix", "zulip"}:
|
||||||
raise BridgeConfigException("Please ensure the configuration has zulip & matrix sections.")
|
raise BridgeConfigError("Please ensure the configuration has zulip & matrix sections.")
|
||||||
|
|
||||||
result: Dict[str, Dict[str, Any]] = {"matrix": {}, "zulip": {}}
|
result: Dict[str, Dict[str, Any]] = {"matrix": {}, "zulip": {}}
|
||||||
# For Matrix: create a mapping with the Matrix room_ids as keys and
|
# For Matrix: create a mapping with the Matrix room_ids as keys and
|
||||||
|
@ -484,7 +484,7 @@ def read_configuration(config_file: str) -> Dict[str, Dict[str, Any]]:
|
||||||
|
|
||||||
if section.startswith("additional_bridge"):
|
if section.startswith("additional_bridge"):
|
||||||
if section_keys != bridge_key_set:
|
if section_keys != bridge_key_set:
|
||||||
raise BridgeConfigException(
|
raise BridgeConfigError(
|
||||||
f"Please ensure the bridge configuration section {section} contain the following keys: {bridge_key_set}."
|
f"Please ensure the bridge configuration section {section} contain the following keys: {bridge_key_set}."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -493,7 +493,7 @@ def read_configuration(config_file: str) -> Dict[str, Dict[str, Any]]:
|
||||||
result["matrix"]["bridges"][section_config["room_id"]] = zulip_target
|
result["matrix"]["bridges"][section_config["room_id"]] = zulip_target
|
||||||
elif section == "matrix":
|
elif section == "matrix":
|
||||||
if section_keys != matrix_full_key_set:
|
if section_keys != matrix_full_key_set:
|
||||||
raise BridgeConfigException(
|
raise BridgeConfigError(
|
||||||
"Please ensure the matrix configuration section contains the following keys: %s."
|
"Please ensure the matrix configuration section contains the following keys: %s."
|
||||||
% str(matrix_full_key_set)
|
% str(matrix_full_key_set)
|
||||||
)
|
)
|
||||||
|
@ -505,10 +505,10 @@ def read_configuration(config_file: str) -> Dict[str, Dict[str, Any]]:
|
||||||
|
|
||||||
# Verify the format of the Matrix user ID.
|
# Verify the format of the Matrix user ID.
|
||||||
if re.fullmatch(r"@[^:]+:.+", result["matrix"]["mxid"]) is None:
|
if re.fullmatch(r"@[^:]+:.+", result["matrix"]["mxid"]) is None:
|
||||||
raise BridgeConfigException("Malformatted mxid.")
|
raise BridgeConfigError("Malformatted mxid.")
|
||||||
elif section == "zulip":
|
elif section == "zulip":
|
||||||
if section_keys != zulip_full_key_set:
|
if section_keys != zulip_full_key_set:
|
||||||
raise BridgeConfigException(
|
raise BridgeConfigError(
|
||||||
"Please ensure the zulip configuration section contains the following keys: %s."
|
"Please ensure the zulip configuration section contains the following keys: %s."
|
||||||
% str(zulip_full_key_set)
|
% str(zulip_full_key_set)
|
||||||
)
|
)
|
||||||
|
@ -555,9 +555,9 @@ async def run(zulip_config: Dict[str, Any], matrix_config: Dict[str, Any], no_no
|
||||||
|
|
||||||
await asyncio.gather(matrix_to_zulip.run(), zulip_to_matrix.run())
|
await asyncio.gather(matrix_to_zulip.run(), zulip_to_matrix.run())
|
||||||
|
|
||||||
except BridgeFatalMatrixException as exception:
|
except BridgeFatalMatrixError as exception:
|
||||||
sys.exit(f"Matrix bridge error: {exception}")
|
sys.exit(f"Matrix bridge error: {exception}")
|
||||||
except BridgeFatalZulipException as exception:
|
except BridgeFatalZulipError as exception:
|
||||||
sys.exit(f"Zulip bridge error: {exception}")
|
sys.exit(f"Zulip bridge error: {exception}")
|
||||||
except zulip.ZulipError as exception:
|
except zulip.ZulipError as exception:
|
||||||
sys.exit(f"Zulip error: {exception}")
|
sys.exit(f"Zulip error: {exception}")
|
||||||
|
@ -571,7 +571,7 @@ async def run(zulip_config: Dict[str, Any], matrix_config: Dict[str, Any], no_no
|
||||||
|
|
||||||
def write_sample_config(target_path: str, zuliprc: Optional[str]) -> None:
|
def write_sample_config(target_path: str, zuliprc: Optional[str]) -> None:
|
||||||
if os.path.exists(target_path):
|
if os.path.exists(target_path):
|
||||||
raise BridgeConfigException(f"Path '{target_path}' exists; not overwriting existing file.")
|
raise BridgeConfigError(f"Path '{target_path}' exists; not overwriting existing file.")
|
||||||
|
|
||||||
sample_dict: OrderedDict[str, OrderedDict[str, str]] = OrderedDict(
|
sample_dict: OrderedDict[str, OrderedDict[str, str]] = OrderedDict(
|
||||||
(
|
(
|
||||||
|
@ -613,20 +613,20 @@ def write_sample_config(target_path: str, zuliprc: Optional[str]) -> None:
|
||||||
|
|
||||||
if zuliprc is not None:
|
if zuliprc is not None:
|
||||||
if not os.path.exists(zuliprc):
|
if not os.path.exists(zuliprc):
|
||||||
raise BridgeConfigException(f"Zuliprc file '{zuliprc}' does not exist.")
|
raise BridgeConfigError(f"Zuliprc file '{zuliprc}' does not exist.")
|
||||||
|
|
||||||
zuliprc_config: configparser.ConfigParser = configparser.ConfigParser()
|
zuliprc_config: configparser.ConfigParser = configparser.ConfigParser()
|
||||||
try:
|
try:
|
||||||
zuliprc_config.read(zuliprc)
|
zuliprc_config.read(zuliprc)
|
||||||
except configparser.Error as exception:
|
except configparser.Error as exception:
|
||||||
raise BridgeConfigException(str(exception))
|
raise BridgeConfigError(str(exception))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
sample_dict["zulip"]["email"] = zuliprc_config["api"]["email"]
|
sample_dict["zulip"]["email"] = zuliprc_config["api"]["email"]
|
||||||
sample_dict["zulip"]["site"] = zuliprc_config["api"]["site"]
|
sample_dict["zulip"]["site"] = zuliprc_config["api"]["site"]
|
||||||
sample_dict["zulip"]["api_key"] = zuliprc_config["api"]["key"]
|
sample_dict["zulip"]["api_key"] = zuliprc_config["api"]["key"]
|
||||||
except KeyError as exception:
|
except KeyError as exception:
|
||||||
raise BridgeConfigException("You provided an invalid zuliprc file: " + str(exception))
|
raise BridgeConfigError("You provided an invalid zuliprc file: " + str(exception))
|
||||||
|
|
||||||
sample: configparser.ConfigParser = configparser.ConfigParser()
|
sample: configparser.ConfigParser = configparser.ConfigParser()
|
||||||
sample.read_dict(sample_dict)
|
sample.read_dict(sample_dict)
|
||||||
|
@ -648,7 +648,7 @@ def main() -> None:
|
||||||
if options.sample_config:
|
if options.sample_config:
|
||||||
try:
|
try:
|
||||||
write_sample_config(options.sample_config, options.zuliprc)
|
write_sample_config(options.sample_config, options.zuliprc)
|
||||||
except BridgeConfigException as exception:
|
except BridgeConfigError as exception:
|
||||||
print(f"Could not write sample config: {exception}")
|
print(f"Could not write sample config: {exception}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
if options.zuliprc is None:
|
if options.zuliprc is None:
|
||||||
|
@ -667,7 +667,7 @@ def main() -> None:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
config: Dict[str, Dict[str, Any]] = read_configuration(options.config)
|
config: Dict[str, Dict[str, Any]] = read_configuration(options.config)
|
||||||
except BridgeConfigException as exception:
|
except BridgeConfigError as exception:
|
||||||
print(f"Could not parse config file: {exception}")
|
print(f"Could not parse config file: {exception}")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
|
@ -98,7 +98,7 @@ class TestBaremetricsBot(BotTestCase, DefaultTests):
|
||||||
|
|
||||||
with self.mock_config_info({"api_key": "TEST"}):
|
with self.mock_config_info({"api_key": "TEST"}):
|
||||||
with self.mock_http_conversation("invalid_api_key"):
|
with self.mock_http_conversation("invalid_api_key"):
|
||||||
with self.assertRaises(StubBotHandler.BotQuitException):
|
with self.assertRaises(StubBotHandler.BotQuitError):
|
||||||
bot_test_instance.initialize(StubBotHandler())
|
bot_test_instance.initialize(StubBotHandler())
|
||||||
|
|
||||||
def test_invalid_command(self) -> None:
|
def test_invalid_command(self) -> None:
|
||||||
|
|
|
@ -97,7 +97,7 @@ right now.\nPlease try again later",
|
||||||
with self.mock_config_info(
|
with self.mock_config_info(
|
||||||
{"auth_token": "someInvalidKey", "username": "aaron", "goalname": "goal"}
|
{"auth_token": "someInvalidKey", "username": "aaron", "goalname": "goal"}
|
||||||
), self.mock_http_conversation("test_invalid_when_initialize"), self.assertRaises(
|
), self.mock_http_conversation("test_invalid_when_initialize"), self.assertRaises(
|
||||||
bot_handler.BotQuitException
|
bot_handler.BotQuitError
|
||||||
):
|
):
|
||||||
bot.initialize(bot_handler)
|
bot.initialize(bot_handler)
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ from copy import deepcopy
|
||||||
from functools import reduce
|
from functools import reduce
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
from zulip_bots.game_handler import BadMoveException
|
from zulip_bots.game_handler import BadMoveError
|
||||||
|
|
||||||
|
|
||||||
class ConnectFourModel:
|
class ConnectFourModel:
|
||||||
|
@ -61,7 +61,7 @@ class ConnectFourModel:
|
||||||
|
|
||||||
while finding_move:
|
while finding_move:
|
||||||
if row < 0:
|
if row < 0:
|
||||||
raise BadMoveException("Make sure your move is in a column with free space.")
|
raise BadMoveError("Make sure your move is in a column with free space.")
|
||||||
if self.current_board[row][column] == 0:
|
if self.current_board[row][column] == 0:
|
||||||
self.current_board[row][column] = token_number
|
self.current_board[row][column] = token_number
|
||||||
finding_move = False
|
finding_move = False
|
||||||
|
|
|
@ -3,7 +3,7 @@ from typing import Dict, List
|
||||||
from typing_extensions import override
|
from typing_extensions import override
|
||||||
|
|
||||||
from zulip_bots.bots.connect_four.controller import ConnectFourModel
|
from zulip_bots.bots.connect_four.controller import ConnectFourModel
|
||||||
from zulip_bots.game_handler import BadMoveException
|
from zulip_bots.game_handler import BadMoveError
|
||||||
from zulip_bots.test_lib import BotTestCase, DefaultTests
|
from zulip_bots.test_lib import BotTestCase, DefaultTests
|
||||||
|
|
||||||
|
|
||||||
|
@ -583,5 +583,5 @@ The first player to get 4 in a row wins!\n Good Luck!",
|
||||||
self.assertEqual(model.get_column(col), [0, -1, -1, -1, 1, 1])
|
self.assertEqual(model.get_column(col), [0, -1, -1, -1, 1, 1])
|
||||||
model.make_move(move, player_number=0)
|
model.make_move(move, player_number=0)
|
||||||
self.assertEqual(model.get_column(col), [1, -1, -1, -1, 1, 1])
|
self.assertEqual(model.get_column(col), [1, -1, -1, -1, 1, 1])
|
||||||
with self.assertRaises(BadMoveException):
|
with self.assertRaises(BadMoveError):
|
||||||
model.make_move(move, player_number=0)
|
model.make_move(move, player_number=0)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from typing import Any, List
|
from typing import Any, List
|
||||||
|
|
||||||
from zulip_bots.game_handler import BadMoveException, GameAdapter
|
from zulip_bots.game_handler import BadMoveError, GameAdapter
|
||||||
|
|
||||||
|
|
||||||
class GameHandlerBotMessageHandler:
|
class GameHandlerBotMessageHandler:
|
||||||
|
@ -31,7 +31,7 @@ class MockModel:
|
||||||
if int(move.replace("move ", "")) < 9:
|
if int(move.replace("move ", "")) < 9:
|
||||||
return "mock board"
|
return "mock board"
|
||||||
else:
|
else:
|
||||||
raise BadMoveException("Invalid Move.")
|
raise BadMoveError("Invalid Move.")
|
||||||
return "mock board"
|
return "mock board"
|
||||||
|
|
||||||
def determine_game_over(self, players: List[str]) -> None:
|
def determine_game_over(self, players: List[str]) -> None:
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import copy
|
import copy
|
||||||
from typing import Any, Dict, List, Tuple
|
from typing import Any, Dict, List, Tuple
|
||||||
|
|
||||||
from zulip_bots.game_handler import BadMoveException, GameAdapter
|
from zulip_bots.game_handler import BadMoveError, GameAdapter
|
||||||
|
|
||||||
|
|
||||||
class GameOfFifteenModel:
|
class GameOfFifteenModel:
|
||||||
|
@ -54,13 +54,13 @@ class GameOfFifteenModel:
|
||||||
move = move.split(" ")
|
move = move.split(" ")
|
||||||
|
|
||||||
if "" in move:
|
if "" in move:
|
||||||
raise BadMoveException("You should enter space separated digits.")
|
raise BadMoveError("You should enter space separated digits.")
|
||||||
moves = len(move)
|
moves = len(move)
|
||||||
for m in range(1, moves):
|
for m in range(1, moves):
|
||||||
tile = int(move[m])
|
tile = int(move[m])
|
||||||
coordinates = self.get_coordinates(board)
|
coordinates = self.get_coordinates(board)
|
||||||
if tile not in coordinates:
|
if tile not in coordinates:
|
||||||
raise BadMoveException("You can only move tiles which exist in the board.")
|
raise BadMoveError("You can only move tiles which exist in the board.")
|
||||||
i, j = coordinates[tile]
|
i, j = coordinates[tile]
|
||||||
if (j - 1) > -1 and board[i][j - 1] == 0:
|
if (j - 1) > -1 and board[i][j - 1] == 0:
|
||||||
board[i][j - 1] = tile
|
board[i][j - 1] = tile
|
||||||
|
@ -75,9 +75,7 @@ class GameOfFifteenModel:
|
||||||
board[i + 1][j] = tile
|
board[i + 1][j] = tile
|
||||||
board[i][j] = 0
|
board[i][j] = 0
|
||||||
else:
|
else:
|
||||||
raise BadMoveException(
|
raise BadMoveError("You can only move tiles which are adjacent to :grey_question:.")
|
||||||
"You can only move tiles which are adjacent to :grey_question:."
|
|
||||||
)
|
|
||||||
if m == moves - 1:
|
if m == moves - 1:
|
||||||
return board
|
return board
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from typing import Dict, List, Tuple
|
from typing import Dict, List, Tuple
|
||||||
|
|
||||||
from zulip_bots.bots.game_of_fifteen.game_of_fifteen import GameOfFifteenModel
|
from zulip_bots.bots.game_of_fifteen.game_of_fifteen import GameOfFifteenModel
|
||||||
from zulip_bots.game_handler import BadMoveException
|
from zulip_bots.game_handler import BadMoveError
|
||||||
from zulip_bots.test_lib import BotTestCase, DefaultTests
|
from zulip_bots.test_lib import BotTestCase, DefaultTests
|
||||||
|
|
||||||
|
|
||||||
|
@ -158,13 +158,13 @@ class TestGameOfFifteenBot(BotTestCase, DefaultTests):
|
||||||
initial_board = [[8, 7, 6], [5, 4, 3], [2, 1, 0]]
|
initial_board = [[8, 7, 6], [5, 4, 3], [2, 1, 0]]
|
||||||
|
|
||||||
model.update_board(initial_board)
|
model.update_board(initial_board)
|
||||||
with self.assertRaises(BadMoveException):
|
with self.assertRaises(BadMoveError):
|
||||||
model.make_move(move1, player_number=0)
|
model.make_move(move1, player_number=0)
|
||||||
with self.assertRaises(BadMoveException):
|
with self.assertRaises(BadMoveError):
|
||||||
model.make_move(move2, player_number=0)
|
model.make_move(move2, player_number=0)
|
||||||
with self.assertRaises(BadMoveException):
|
with self.assertRaises(BadMoveError):
|
||||||
model.make_move(move3, player_number=0)
|
model.make_move(move3, player_number=0)
|
||||||
with self.assertRaises(BadMoveException):
|
with self.assertRaises(BadMoveError):
|
||||||
model.make_move(move4, player_number=0)
|
model.make_move(move4, player_number=0)
|
||||||
with self.assertRaises(BadMoveException):
|
with self.assertRaises(BadMoveError):
|
||||||
model.make_move(move5, player_number=0)
|
model.make_move(move5, player_number=0)
|
||||||
|
|
|
@ -52,7 +52,7 @@ class GiphyHandler:
|
||||||
bot_handler.send_reply(message, bot_response)
|
bot_handler.send_reply(message, bot_response)
|
||||||
|
|
||||||
|
|
||||||
class GiphyNoResultException(Exception):
|
class GiphyNoResultError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -77,7 +77,7 @@ def get_url_gif_giphy(keyword: str, api_key: str) -> Union[int, str]:
|
||||||
try:
|
try:
|
||||||
gif_url = data.json()["data"]["images"]["original"]["url"]
|
gif_url = data.json()["data"]["images"]["original"]["url"]
|
||||||
except (TypeError, KeyError): # Usually triggered by no result in Giphy.
|
except (TypeError, KeyError): # Usually triggered by no result in Giphy.
|
||||||
raise GiphyNoResultException
|
raise GiphyNoResultError
|
||||||
return gif_url
|
return gif_url
|
||||||
|
|
||||||
|
|
||||||
|
@ -95,7 +95,7 @@ def get_bot_giphy_response(
|
||||||
"cannot process your request right now. But, "
|
"cannot process your request right now. But, "
|
||||||
"let's try again later! :grin:"
|
"let's try again later! :grin:"
|
||||||
)
|
)
|
||||||
except GiphyNoResultException:
|
except GiphyNoResultError:
|
||||||
return f'Sorry, I don\'t have a GIF for "{keyword}"! :astonished:'
|
return f'Sorry, I don\'t have a GIF for "{keyword}"! :astonished:'
|
||||||
return (
|
return (
|
||||||
f"[Click to enlarge]({gif_url})"
|
f"[Click to enlarge]({gif_url})"
|
||||||
|
|
|
@ -84,11 +84,11 @@ class TestGoogleTranslateBot(BotTestCase, DefaultTests):
|
||||||
self._test('"hello" de', "Error. .", "test_languages")
|
self._test('"hello" de', "Error. .", "test_languages")
|
||||||
|
|
||||||
def test_invalid_api_key(self):
|
def test_invalid_api_key(self):
|
||||||
with self.assertRaises(StubBotHandler.BotQuitException):
|
with self.assertRaises(StubBotHandler.BotQuitError):
|
||||||
self._test(None, None, "test_invalid_api_key")
|
self._test(None, None, "test_invalid_api_key")
|
||||||
|
|
||||||
def test_api_access_not_configured(self):
|
def test_api_access_not_configured(self):
|
||||||
with self.assertRaises(StubBotHandler.BotQuitException):
|
with self.assertRaises(StubBotHandler.BotQuitError):
|
||||||
self._test(None, None, "test_api_access_not_configured")
|
self._test(None, None, "test_api_access_not_configured")
|
||||||
|
|
||||||
def test_connection_error(self):
|
def test_connection_error(self):
|
||||||
|
|
|
@ -12,21 +12,21 @@ api_key = ""
|
||||||
default_team = ""
|
default_team = ""
|
||||||
|
|
||||||
|
|
||||||
class AuthenticationException(Exception):
|
class AuthenticationError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class TeamNotFoundException(Exception):
|
class TeamNotFoundError(Exception):
|
||||||
def __init__(self, team: str) -> None:
|
def __init__(self, team: str) -> None:
|
||||||
self.team = team
|
self.team = team
|
||||||
|
|
||||||
|
|
||||||
class UnknownCommandSyntax(Exception):
|
class UnknownCommandSyntaxError(Exception):
|
||||||
def __init__(self, detail: str) -> None:
|
def __init__(self, detail: str) -> None:
|
||||||
self.detail = detail
|
self.detail = detail
|
||||||
|
|
||||||
|
|
||||||
class UnspecifiedProblemException(Exception):
|
class UnspecifiedProblemError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -49,10 +49,10 @@ def make_api_request(
|
||||||
and r.json()["error"] == "Invalid API Authentication"
|
and r.json()["error"] == "Invalid API Authentication"
|
||||||
):
|
):
|
||||||
logging.error("Error authenticating, please check key %s", r.url)
|
logging.error("Error authenticating, please check key %s", r.url)
|
||||||
raise AuthenticationException
|
raise AuthenticationError
|
||||||
else:
|
else:
|
||||||
logging.error("Error make API request, code %s. json: %s", r.status_code, r.json())
|
logging.error("Error make API request, code %s. json: %s", r.status_code, r.json())
|
||||||
raise UnspecifiedProblemException
|
raise UnspecifiedProblemError
|
||||||
|
|
||||||
|
|
||||||
def api_noop() -> None:
|
def api_noop() -> None:
|
||||||
|
@ -92,7 +92,7 @@ def get_team_hash(team_name: str) -> str:
|
||||||
for team in api_list_team():
|
for team in api_list_team():
|
||||||
if team["name"].lower() == team_name.lower() or team["hash_id"] == team_name:
|
if team["name"].lower() == team_name.lower() or team["hash_id"] == team_name:
|
||||||
return team["hash_id"]
|
return team["hash_id"]
|
||||||
raise TeamNotFoundException(team_name)
|
raise TeamNotFoundError(team_name)
|
||||||
|
|
||||||
|
|
||||||
def team_info(team_name: str) -> str:
|
def team_info(team_name: str) -> str:
|
||||||
|
@ -133,7 +133,7 @@ def create_entry(message: str) -> str:
|
||||||
team = default_team
|
team = default_team
|
||||||
new_message = message
|
new_message = message
|
||||||
else:
|
else:
|
||||||
raise UnknownCommandSyntax(
|
raise UnknownCommandSyntaxError(
|
||||||
"""I don't know which team you meant for me to create an entry under.
|
"""I don't know which team you meant for me to create an entry under.
|
||||||
Either set a default team or pass the `--team` flag.
|
Either set a default team or pass the `--team` flag.
|
||||||
More information in my help"""
|
More information in my help"""
|
||||||
|
@ -166,12 +166,12 @@ class IDoneThisHandler:
|
||||||
|
|
||||||
try:
|
try:
|
||||||
api_noop()
|
api_noop()
|
||||||
except AuthenticationException:
|
except AuthenticationError:
|
||||||
logging.error(
|
logging.error(
|
||||||
"Authentication exception with idonethis. Can you check that your API keys are correct? "
|
"Authentication exception with idonethis. Can you check that your API keys are correct? "
|
||||||
)
|
)
|
||||||
bot_handler.quit()
|
bot_handler.quit()
|
||||||
except UnspecifiedProblemException:
|
except UnspecifiedProblemError:
|
||||||
logging.error("Problem connecting to idonethis. Please check connection")
|
logging.error("Problem connecting to idonethis. Please check connection")
|
||||||
bot_handler.quit()
|
bot_handler.quit()
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ Below are some of the commands you can use, and what they do.
|
||||||
if len(message_content) > 2:
|
if len(message_content) > 2:
|
||||||
reply = team_info(" ".join(message_content[2:]))
|
reply = team_info(" ".join(message_content[2:]))
|
||||||
else:
|
else:
|
||||||
raise UnknownCommandSyntax(
|
raise UnknownCommandSyntaxError(
|
||||||
"You must specify the team in which you request information from."
|
"You must specify the team in which you request information from."
|
||||||
)
|
)
|
||||||
elif command in ["entries list", "list entries"]:
|
elif command in ["entries list", "list entries"]:
|
||||||
|
@ -229,15 +229,17 @@ Below are some of the commands you can use, and what they do.
|
||||||
elif command in ["help"]:
|
elif command in ["help"]:
|
||||||
reply = self.usage()
|
reply = self.usage()
|
||||||
else:
|
else:
|
||||||
raise UnknownCommandSyntax("I can't understand the command you sent me :confused: ")
|
raise UnknownCommandSyntaxError(
|
||||||
except TeamNotFoundException as e:
|
"I can't understand the command you sent me :confused: "
|
||||||
|
)
|
||||||
|
except TeamNotFoundError as e:
|
||||||
reply = (
|
reply = (
|
||||||
"Sorry, it doesn't seem as if I can find a team named `" + e.team + "` :frowning:."
|
"Sorry, it doesn't seem as if I can find a team named `" + e.team + "` :frowning:."
|
||||||
)
|
)
|
||||||
except AuthenticationException:
|
except AuthenticationError:
|
||||||
reply = "I can't currently authenticate with idonethis. "
|
reply = "I can't currently authenticate with idonethis. "
|
||||||
reply += "Can you check that your API key is correct? For more information see my documentation."
|
reply += "Can you check that your API key is correct? For more information see my documentation."
|
||||||
except UnknownCommandSyntax as e:
|
except UnknownCommandSyntaxError as e:
|
||||||
reply = (
|
reply = (
|
||||||
"Sorry, I don't understand what your trying to say. Use `@mention help` to see my help. "
|
"Sorry, I don't understand what your trying to say. Use `@mention help` to see my help. "
|
||||||
+ e.detail
|
+ e.detail
|
||||||
|
|
|
@ -14,7 +14,7 @@ ANSWERS = {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
class InvalidAnswerException(Exception):
|
class InvalidAnswerError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ class IncidentHandler:
|
||||||
elif query.startswith("answer "):
|
elif query.startswith("answer "):
|
||||||
try:
|
try:
|
||||||
(ticket_id, answer) = parse_answer(query)
|
(ticket_id, answer) = parse_answer(query)
|
||||||
except InvalidAnswerException:
|
except InvalidAnswerError:
|
||||||
bot_response = "Invalid answer format"
|
bot_response = "Invalid answer format"
|
||||||
bot_handler.send_reply(message, bot_response)
|
bot_handler.send_reply(message, bot_response)
|
||||||
return
|
return
|
||||||
|
@ -63,7 +63,7 @@ def start_new_incident(query: str, message: Dict[str, Any], bot_handler: BotHand
|
||||||
def parse_answer(query: str) -> Tuple[str, str]:
|
def parse_answer(query: str) -> Tuple[str, str]:
|
||||||
m = re.match(r"answer\s+(TICKET....)\s+(.)", query)
|
m = re.match(r"answer\s+(TICKET....)\s+(.)", query)
|
||||||
if not m:
|
if not m:
|
||||||
raise InvalidAnswerException
|
raise InvalidAnswerError
|
||||||
|
|
||||||
ticket_id = m.group(1)
|
ticket_id = m.group(1)
|
||||||
|
|
||||||
|
@ -74,7 +74,7 @@ def parse_answer(query: str) -> Tuple[str, str]:
|
||||||
|
|
||||||
answer = m.group(2).upper()
|
answer = m.group(2).upper()
|
||||||
if answer not in "1234":
|
if answer not in "1234":
|
||||||
raise InvalidAnswerException
|
raise InvalidAnswerError
|
||||||
|
|
||||||
return (ticket_id, ANSWERS[answer])
|
return (ticket_id, ANSWERS[answer])
|
||||||
|
|
||||||
|
|
|
@ -65,5 +65,5 @@ class TestLinkShortenerBot(BotTestCase, DefaultTests):
|
||||||
bot_test_instance = LinkShortenerHandler()
|
bot_test_instance = LinkShortenerHandler()
|
||||||
with self.mock_config_info({"key": "qwertyuiopx"}):
|
with self.mock_config_info({"key": "qwertyuiopx"}):
|
||||||
with self.mock_http_conversation("test_invalid_access_token"):
|
with self.mock_http_conversation("test_invalid_access_token"):
|
||||||
with self.assertRaises(StubBotHandler.BotQuitException):
|
with self.assertRaises(StubBotHandler.BotQuitError):
|
||||||
bot_test_instance.initialize(StubBotHandler())
|
bot_test_instance.initialize(StubBotHandler())
|
||||||
|
|
|
@ -116,13 +116,13 @@ class MentionHandler:
|
||||||
alert_id = self.get_alert_id(keyword)
|
alert_id = self.get_alert_id(keyword)
|
||||||
except (TypeError, KeyError):
|
except (TypeError, KeyError):
|
||||||
# Usually triggered by invalid token or json parse error when account quote is finished.
|
# Usually triggered by invalid token or json parse error when account quote is finished.
|
||||||
raise MentionNoResponseException
|
raise MentionNoResponseError
|
||||||
|
|
||||||
try:
|
try:
|
||||||
mentions = self.get_mentions(alert_id)
|
mentions = self.get_mentions(alert_id)
|
||||||
except (TypeError, KeyError):
|
except (TypeError, KeyError):
|
||||||
# Usually triggered by no response or json parse error when account quota is finished.
|
# Usually triggered by no response or json parse error when account quota is finished.
|
||||||
raise MentionNoResponseException
|
raise MentionNoResponseError
|
||||||
|
|
||||||
reply = "The most recent mentions of `" + keyword + "` on the web are: \n"
|
reply = "The most recent mentions of `" + keyword + "` on the web are: \n"
|
||||||
for mention in mentions:
|
for mention in mentions:
|
||||||
|
@ -133,5 +133,5 @@ class MentionHandler:
|
||||||
handler_class = MentionHandler
|
handler_class = MentionHandler
|
||||||
|
|
||||||
|
|
||||||
class MentionNoResponseException(Exception):
|
class MentionNoResponseError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
|
@ -55,5 +55,5 @@ class TestMentionBot(BotTestCase, DefaultTests):
|
||||||
|
|
||||||
with self.mock_config_info({"access_token": "TEST"}):
|
with self.mock_config_info({"access_token": "TEST"}):
|
||||||
with self.mock_http_conversation("invalid_api_key"):
|
with self.mock_http_conversation("invalid_api_key"):
|
||||||
with self.assertRaises(StubBotHandler.BotQuitException):
|
with self.assertRaises(StubBotHandler.BotQuitError):
|
||||||
bot_test_instance.initialize(StubBotHandler())
|
bot_test_instance.initialize(StubBotHandler())
|
||||||
|
|
|
@ -7,7 +7,7 @@ freely import another modules.
|
||||||
|
|
||||||
import re
|
import re
|
||||||
|
|
||||||
from zulip_bots.game_handler import BadMoveException
|
from zulip_bots.game_handler import BadMoveError
|
||||||
|
|
||||||
from . import database, mechanics
|
from . import database, mechanics
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ def unknown_command():
|
||||||
:return: A string containing info about available commands
|
:return: A string containing info about available commands
|
||||||
"""
|
"""
|
||||||
message = "Unknown command. Available commands: put (v,h), take (v,h), move (v,h) -> (v,h)"
|
message = "Unknown command. Available commands: put (v,h), take (v,h), move (v,h) -> (v,h)"
|
||||||
raise BadMoveException(message)
|
raise BadMoveError(message)
|
||||||
|
|
||||||
|
|
||||||
def beat(message, topic_name, merels_storage):
|
def beat(message, topic_name, merels_storage):
|
||||||
|
@ -70,7 +70,7 @@ def beat(message, topic_name, merels_storage):
|
||||||
p2 = [int(x) for x in match.group(3).split(",")]
|
p2 = [int(x) for x in match.group(3).split(",")]
|
||||||
|
|
||||||
if mechanics.get_take_status(topic_name, merels_storage) == 1:
|
if mechanics.get_take_status(topic_name, merels_storage) == 1:
|
||||||
raise BadMoveException("Take is required to proceed. Please try again.\n")
|
raise BadMoveError("Take is required to proceed. Please try again.\n")
|
||||||
|
|
||||||
responses += mechanics.move_man(topic_name, p1, p2, merels_storage) + "\n"
|
responses += mechanics.move_man(topic_name, p1, p2, merels_storage) + "\n"
|
||||||
no_moves = after_event_checkup(responses, topic_name, merels_storage)
|
no_moves = after_event_checkup(responses, topic_name, merels_storage)
|
||||||
|
@ -98,7 +98,7 @@ def beat(message, topic_name, merels_storage):
|
||||||
responses = ""
|
responses = ""
|
||||||
|
|
||||||
if mechanics.get_take_status(topic_name, merels_storage) == 1:
|
if mechanics.get_take_status(topic_name, merels_storage) == 1:
|
||||||
raise BadMoveException("Take is required to proceed. Please try again.\n")
|
raise BadMoveError("Take is required to proceed. Please try again.\n")
|
||||||
responses += mechanics.put_man(topic_name, p1[0], p1[1], merels_storage) + "\n"
|
responses += mechanics.put_man(topic_name, p1[0], p1[1], merels_storage) + "\n"
|
||||||
no_moves = after_event_checkup(responses, topic_name, merels_storage)
|
no_moves = after_event_checkup(responses, topic_name, merels_storage)
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ def beat(message, topic_name, merels_storage):
|
||||||
if mechanics.get_take_status(topic_name, merels_storage) == 1:
|
if mechanics.get_take_status(topic_name, merels_storage) == 1:
|
||||||
responses += mechanics.take_man(topic_name, p1[0], p1[1], merels_storage) + "\n"
|
responses += mechanics.take_man(topic_name, p1[0], p1[1], merels_storage) + "\n"
|
||||||
if "Failed" in responses:
|
if "Failed" in responses:
|
||||||
raise BadMoveException(responses)
|
raise BadMoveError(responses)
|
||||||
mechanics.update_toggle_take_mode(topic_name, merels_storage)
|
mechanics.update_toggle_take_mode(topic_name, merels_storage)
|
||||||
no_moves = after_event_checkup(responses, topic_name, merels_storage)
|
no_moves = after_event_checkup(responses, topic_name, merels_storage)
|
||||||
|
|
||||||
|
@ -130,7 +130,7 @@ def beat(message, topic_name, merels_storage):
|
||||||
same_player_move = no_moves
|
same_player_move = no_moves
|
||||||
return responses, same_player_move
|
return responses, same_player_move
|
||||||
else:
|
else:
|
||||||
raise BadMoveException("Taking is not possible.")
|
raise BadMoveError("Taking is not possible.")
|
||||||
else:
|
else:
|
||||||
return unknown_command()
|
return unknown_command()
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,7 @@ mechanisms as well as some functions for accessing the database.
|
||||||
from collections import Counter
|
from collections import Counter
|
||||||
from math import sqrt
|
from math import sqrt
|
||||||
|
|
||||||
from zulip_bots.game_handler import BadMoveException
|
from zulip_bots.game_handler import BadMoveError
|
||||||
|
|
||||||
from . import constants, database, game_data, interface
|
from . import constants, database, game_data, interface
|
||||||
|
|
||||||
|
@ -361,7 +361,7 @@ def move_man(topic_name, p1, p2, merels_storage):
|
||||||
)
|
)
|
||||||
return f"Moved a man from ({p1[0]}, {p1[1]}) -> ({p2[0]}, {p2[1]}) for {data.turn}."
|
return f"Moved a man from ({p1[0]}, {p1[1]}) -> ({p2[0]}, {p2[1]}) for {data.turn}."
|
||||||
else:
|
else:
|
||||||
raise BadMoveException("Failed: That's not a legal move. Please try again.")
|
raise BadMoveError("Failed: That's not a legal move. Please try again.")
|
||||||
|
|
||||||
|
|
||||||
def put_man(topic_name, v, h, merels_storage):
|
def put_man(topic_name, v, h, merels_storage):
|
||||||
|
@ -399,7 +399,7 @@ def put_man(topic_name, v, h, merels_storage):
|
||||||
)
|
)
|
||||||
return f"Put a man to ({v}, {h}) for {data.turn}."
|
return f"Put a man to ({v}, {h}) for {data.turn}."
|
||||||
else:
|
else:
|
||||||
raise BadMoveException("Failed: That's not a legal put. Please try again.")
|
raise BadMoveError("Failed: That's not a legal put. Please try again.")
|
||||||
|
|
||||||
|
|
||||||
def take_man(topic_name, v, h, merels_storage):
|
def take_man(topic_name, v, h, merels_storage):
|
||||||
|
@ -443,7 +443,7 @@ def take_man(topic_name, v, h, merels_storage):
|
||||||
)
|
)
|
||||||
return f"Taken a man from ({v}, {h}) for {data.turn}."
|
return f"Taken a man from ({v}, {h}) for {data.turn}."
|
||||||
else:
|
else:
|
||||||
raise BadMoveException("Failed: That's not a legal take. Please try again.")
|
raise BadMoveError("Failed: That's not a legal take. Please try again.")
|
||||||
|
|
||||||
|
|
||||||
def update_hill_uid(topic_name, merels_storage):
|
def update_hill_uid(topic_name, merels_storage):
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
from typing import Any, List
|
from typing import Any, List
|
||||||
|
|
||||||
from zulip_bots.game_handler import GameAdapter, SamePlayerMove
|
from zulip_bots.game_handler import GameAdapter, SamePlayerMoveError
|
||||||
|
|
||||||
from .libraries import database, game, game_data, mechanics
|
from .libraries import database, game, game_data, mechanics
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ class MerelsModel:
|
||||||
)
|
)
|
||||||
self.current_board, same_player_move = game.beat(move, self.topic, self.storage)
|
self.current_board, same_player_move = game.beat(move, self.topic, self.storage)
|
||||||
if same_player_move != "":
|
if same_player_move != "":
|
||||||
raise SamePlayerMove(same_player_move)
|
raise SamePlayerMoveError(same_player_move)
|
||||||
return self.current_board
|
return self.current_board
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from zulip_bots.game_handler import BadMoveException
|
from zulip_bots.game_handler import BadMoveError
|
||||||
from zulip_bots.simple_lib import SimpleStorage
|
from zulip_bots.simple_lib import SimpleStorage
|
||||||
|
|
||||||
from ..libraries import database, game
|
from ..libraries import database, game
|
||||||
|
@ -26,7 +26,7 @@ class GameTest(unittest.TestCase):
|
||||||
def test_not_possible_put_piece_output(self):
|
def test_not_possible_put_piece_output(self):
|
||||||
merels = database.MerelsStorage(self.topic_name, self.storage)
|
merels = database.MerelsStorage(self.topic_name, self.storage)
|
||||||
merels.update_game(self.topic_name, "X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0)
|
merels.update_game(self.topic_name, "X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0)
|
||||||
with self.assertRaises(BadMoveException) as warning:
|
with self.assertRaises(BadMoveError) as warning:
|
||||||
game.beat("put 0,1", self.topic_name, self.storage)
|
game.beat("put 0,1", self.topic_name, self.storage)
|
||||||
self.assertTrue("Failed" in str(warning))
|
self.assertTrue("Failed" in str(warning))
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ class GameTest(unittest.TestCase):
|
||||||
merels = database.MerelsStorage(self.topic_name, self.storage)
|
merels = database.MerelsStorage(self.topic_name, self.storage)
|
||||||
merels.update_game(self.topic_name, "X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0)
|
merels.update_game(self.topic_name, "X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0)
|
||||||
merels.update_game(self.topic_name, "X", 0, 0, "XXXNNNOOOXXXNNNOOOXXXNNN", "", 1)
|
merels.update_game(self.topic_name, "X", 0, 0, "XXXNNNOOOXXXNNNOOOXXXNNN", "", 1)
|
||||||
with self.assertRaises(BadMoveException) as warning:
|
with self.assertRaises(BadMoveError) as warning:
|
||||||
game.beat("put 1,1", self.topic_name, self.storage)
|
game.beat("put 1,1", self.topic_name, self.storage)
|
||||||
self.assertTrue("Take is required" in str(warning))
|
self.assertTrue("Take is required" in str(warning))
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ class GameTest(unittest.TestCase):
|
||||||
merels = database.MerelsStorage(self.topic_name, self.storage)
|
merels = database.MerelsStorage(self.topic_name, self.storage)
|
||||||
merels.update_game(self.topic_name, "X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0)
|
merels.update_game(self.topic_name, "X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0)
|
||||||
merels.update_game(self.topic_name, "X", 0, 0, "XXXNNNOOOXXXNNNOOOXXXOOO", "", 0)
|
merels.update_game(self.topic_name, "X", 0, 0, "XXXNNNOOOXXXNNNOOOXXXOOO", "", 0)
|
||||||
with self.assertRaises(BadMoveException) as warning:
|
with self.assertRaises(BadMoveError) as warning:
|
||||||
game.beat("move 0,3 1,2", self.topic_name, self.storage)
|
game.beat("move 0,3 1,2", self.topic_name, self.storage)
|
||||||
self.assertTrue("Failed" in str(warning))
|
self.assertTrue("Failed" in str(warning))
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ class GameTest(unittest.TestCase):
|
||||||
merels = database.MerelsStorage(self.topic_name, self.storage)
|
merels = database.MerelsStorage(self.topic_name, self.storage)
|
||||||
merels.update_game(self.topic_name, "X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0)
|
merels.update_game(self.topic_name, "X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0)
|
||||||
merels.update_game(self.topic_name, "X", 6, 6, "XXXNNNOOONNNNNNNNNNNNNNN", "", 1)
|
merels.update_game(self.topic_name, "X", 6, 6, "XXXNNNOOONNNNNNNNNNNNNNN", "", 1)
|
||||||
with self.assertRaises(BadMoveException) as warning:
|
with self.assertRaises(BadMoveError) as warning:
|
||||||
game.beat("move 0,1 1,3", self.topic_name, self.storage)
|
game.beat("move 0,1 1,3", self.topic_name, self.storage)
|
||||||
self.assertTrue("Take is required" in str(warning))
|
self.assertTrue("Take is required" in str(warning))
|
||||||
|
|
||||||
|
@ -72,7 +72,7 @@ class GameTest(unittest.TestCase):
|
||||||
merels = database.MerelsStorage(self.topic_name, self.storage)
|
merels = database.MerelsStorage(self.topic_name, self.storage)
|
||||||
merels.update_game(self.topic_name, "X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0)
|
merels.update_game(self.topic_name, "X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0)
|
||||||
merels.update_game(self.topic_name, "X", 6, 6, "XXXNNNOOONNNNNNNNNNNNNNN", "", 1)
|
merels.update_game(self.topic_name, "X", 6, 6, "XXXNNNOOONNNNNNNNNNNNNNN", "", 1)
|
||||||
with self.assertRaises(BadMoveException) as warning:
|
with self.assertRaises(BadMoveError) as warning:
|
||||||
game.beat("magic 2,2", self.topic_name, self.storage)
|
game.beat("magic 2,2", self.topic_name, self.storage)
|
||||||
self.assertTrue("Unknown command" in str(warning))
|
self.assertTrue("Unknown command" in str(warning))
|
||||||
|
|
||||||
|
@ -87,7 +87,7 @@ class GameTest(unittest.TestCase):
|
||||||
merels = database.MerelsStorage(self.topic_name, self.storage)
|
merels = database.MerelsStorage(self.topic_name, self.storage)
|
||||||
merels.update_game(self.topic_name, "X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0)
|
merels.update_game(self.topic_name, "X", 0, 0, "NNNNNNNNNNNNNNNNNNNNNNNN", "", 0)
|
||||||
merels.update_game(self.topic_name, "X", 6, 6, "XXXNNNOOOXXXNNNOOOXXXOOO", "", 0)
|
merels.update_game(self.topic_name, "X", 6, 6, "XXXNNNOOOXXXNNNOOOXXXOOO", "", 0)
|
||||||
with self.assertRaises(BadMoveException) as warning:
|
with self.assertRaises(BadMoveError) as warning:
|
||||||
game.beat("take 2,2", self.topic_name, self.storage)
|
game.beat("take 2,2", self.topic_name, self.storage)
|
||||||
self.assertTrue("Taking is not possible" in str(warning))
|
self.assertTrue("Taking is not possible" in str(warning))
|
||||||
|
|
||||||
|
|
|
@ -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, NoBotConfigException
|
from zulip_bots.lib import BotHandler, NoBotConfigError
|
||||||
|
|
||||||
|
|
||||||
class MonkeyTestitBot:
|
class MonkeyTestitBot:
|
||||||
|
@ -20,7 +20,7 @@ class MonkeyTestitBot:
|
||||||
def initialize(self, bot_handler: BotHandler) -> None:
|
def initialize(self, bot_handler: BotHandler) -> None:
|
||||||
try:
|
try:
|
||||||
self.config = bot_handler.get_config_info("monkeytestit")
|
self.config = bot_handler.get_config_info("monkeytestit")
|
||||||
except NoBotConfigException:
|
except NoBotConfigError:
|
||||||
bot_handler.quit(
|
bot_handler.quit(
|
||||||
"Quitting because there's no config file "
|
"Quitting because there's no config file "
|
||||||
"supplied. See doc.md for a guide on setting up "
|
"supplied. See doc.md for a guide on setting up "
|
||||||
|
|
|
@ -163,7 +163,7 @@ class TestSalesforceBot(BotTestCase, DefaultTests):
|
||||||
self._test("test_one_result", "find contact", "Usage: find contact <name> [arguments]")
|
self._test("test_one_result", "find contact", "Usage: find contact <name> [arguments]")
|
||||||
|
|
||||||
def test_bad_auth(self) -> None:
|
def test_bad_auth(self) -> None:
|
||||||
with self.assertRaises(StubBotHandler.BotQuitException):
|
with self.assertRaises(StubBotHandler.BotQuitError):
|
||||||
self._test_initialize(auth_success=False)
|
self._test_initialize(auth_success=False)
|
||||||
|
|
||||||
def test_callback(self) -> None:
|
def test_callback(self) -> None:
|
||||||
|
|
|
@ -4,7 +4,7 @@ from typing import Any, List, Tuple
|
||||||
|
|
||||||
from typing_extensions import override
|
from typing_extensions import override
|
||||||
|
|
||||||
from zulip_bots.game_handler import BadMoveException, GameAdapter
|
from zulip_bots.game_handler import BadMoveError, GameAdapter
|
||||||
|
|
||||||
# -------------------------------------
|
# -------------------------------------
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ class TicTacToeModel:
|
||||||
return self.computer_move(self.current_board, player_number + 1)
|
return self.computer_move(self.current_board, player_number + 1)
|
||||||
move_coords_str = coords_from_command(move)
|
move_coords_str = coords_from_command(move)
|
||||||
if not self.is_valid_move(move_coords_str):
|
if not self.is_valid_move(move_coords_str):
|
||||||
raise BadMoveException("Make sure your move is from 0-9")
|
raise BadMoveError("Make sure your move is from 0-9")
|
||||||
board = self.current_board
|
board = self.current_board
|
||||||
move_coords = move_coords_str.split(",")
|
move_coords = move_coords_str.split(",")
|
||||||
# Subtraction must be done to convert to the right indices,
|
# Subtraction must be done to convert to the right indices,
|
||||||
|
@ -211,7 +211,7 @@ class TicTacToeModel:
|
||||||
row = (int(move_coords[1])) - 1
|
row = (int(move_coords[1])) - 1
|
||||||
column = (int(move_coords[0])) - 1
|
column = (int(move_coords[0])) - 1
|
||||||
if board[row][column] != 0:
|
if board[row][column] != 0:
|
||||||
raise BadMoveException("Make sure your space hasn't already been filled.")
|
raise BadMoveError("Make sure your space hasn't already been filled.")
|
||||||
board[row][column] = player_number + 1
|
board[row][column] = player_number + 1
|
||||||
return board
|
return board
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,7 @@ class TestTrelloBot(BotTestCase, DefaultTests):
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_bot_quit_with_invalid_config(self) -> None:
|
def test_bot_quit_with_invalid_config(self) -> None:
|
||||||
with self.mock_config_info(mock_config), self.assertRaises(StubBotHandler.BotQuitException):
|
with self.mock_config_info(mock_config), self.assertRaises(StubBotHandler.BotQuitError):
|
||||||
with self.mock_http_conversation("invalid_key"):
|
with self.mock_http_conversation("invalid_key"):
|
||||||
TrelloHandler().initialize(StubBotHandler())
|
TrelloHandler().initialize(StubBotHandler())
|
||||||
|
|
||||||
|
|
|
@ -9,11 +9,11 @@ import requests
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import BotHandler
|
||||||
|
|
||||||
|
|
||||||
class NotAvailableException(Exception):
|
class NotAvailableError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class InvalidAnswerException(Exception):
|
class InvalidAnswerError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -29,14 +29,14 @@ class TriviaQuizHandler:
|
||||||
try:
|
try:
|
||||||
start_new_quiz(message, bot_handler)
|
start_new_quiz(message, bot_handler)
|
||||||
return
|
return
|
||||||
except NotAvailableException:
|
except NotAvailableError:
|
||||||
bot_response = "Uh-Oh! Trivia service is down."
|
bot_response = "Uh-Oh! Trivia service is down."
|
||||||
bot_handler.send_reply(message, bot_response)
|
bot_handler.send_reply(message, bot_response)
|
||||||
return
|
return
|
||||||
elif query.startswith("answer"):
|
elif query.startswith("answer"):
|
||||||
try:
|
try:
|
||||||
(quiz_id, answer) = parse_answer(query)
|
(quiz_id, answer) = parse_answer(query)
|
||||||
except InvalidAnswerException:
|
except InvalidAnswerError:
|
||||||
bot_response = "Invalid answer format"
|
bot_response = "Invalid answer format"
|
||||||
bot_handler.send_reply(message, bot_response)
|
bot_handler.send_reply(message, bot_response)
|
||||||
return
|
return
|
||||||
|
@ -75,12 +75,12 @@ def start_new_quiz(message: Dict[str, Any], bot_handler: BotHandler) -> None:
|
||||||
def parse_answer(query: str) -> Tuple[str, str]:
|
def parse_answer(query: str) -> Tuple[str, str]:
|
||||||
m = re.match(r"answer\s+(Q...)\s+(.)", query)
|
m = re.match(r"answer\s+(Q...)\s+(.)", query)
|
||||||
if not m:
|
if not m:
|
||||||
raise InvalidAnswerException
|
raise InvalidAnswerError
|
||||||
|
|
||||||
quiz_id = m.group(1)
|
quiz_id = m.group(1)
|
||||||
answer = m.group(2).upper()
|
answer = m.group(2).upper()
|
||||||
if answer not in "ABCD":
|
if answer not in "ABCD":
|
||||||
raise InvalidAnswerException
|
raise InvalidAnswerError
|
||||||
|
|
||||||
return (quiz_id, answer)
|
return (quiz_id, answer)
|
||||||
|
|
||||||
|
@ -98,10 +98,10 @@ def get_trivia_payload() -> Dict[str, Any]:
|
||||||
data = requests.get(url)
|
data = requests.get(url)
|
||||||
|
|
||||||
except requests.exceptions.RequestException:
|
except requests.exceptions.RequestException:
|
||||||
raise NotAvailableException
|
raise NotAvailableError
|
||||||
|
|
||||||
if data.status_code != 200:
|
if data.status_code != 200:
|
||||||
raise NotAvailableException
|
raise NotAvailableError
|
||||||
|
|
||||||
payload = data.json()
|
payload = data.json()
|
||||||
return payload
|
return payload
|
||||||
|
|
|
@ -50,7 +50,7 @@ class TestYoutubeBot(BotTestCase, DefaultTests):
|
||||||
with self.mock_config_info(
|
with self.mock_config_info(
|
||||||
{"key": "somethinginvalid", "number_of_results": "5", "video_region": "US"}
|
{"key": "somethinginvalid", "number_of_results": "5", "video_region": "US"}
|
||||||
), self.mock_http_conversation("test_invalid_key"), self.assertRaises(
|
), self.mock_http_conversation("test_invalid_key"), self.assertRaises(
|
||||||
bot_handler.BotQuitException
|
bot_handler.BotQuitError
|
||||||
):
|
):
|
||||||
bot.initialize(bot_handler)
|
bot.initialize(bot_handler)
|
||||||
|
|
||||||
|
|
|
@ -30,7 +30,7 @@ def import_module_by_name(name: str) -> Any:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
class DuplicateRegisteredBotName(Exception):
|
class DuplicateRegisteredBotNameError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ def import_module_from_zulip_bot_registry(name: str) -> Tuple[str, Optional[Modu
|
||||||
return f"editable package: {bot_name}", bot_module
|
return f"editable package: {bot_name}", bot_module
|
||||||
|
|
||||||
if len(matching_bots) > 1:
|
if len(matching_bots) > 1:
|
||||||
raise DuplicateRegisteredBotName(name)
|
raise DuplicateRegisteredBotNameError(name)
|
||||||
|
|
||||||
return "", None # no matches in registry
|
return "", None # no matches in registry
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ from typing_extensions import override
|
||||||
from zulip_bots.lib import BotHandler
|
from zulip_bots.lib import BotHandler
|
||||||
|
|
||||||
|
|
||||||
class BadMoveException(Exception):
|
class BadMoveError(Exception):
|
||||||
def __init__(self, message: str) -> None:
|
def __init__(self, message: str) -> None:
|
||||||
self.message = message
|
self.message = message
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ class BadMoveException(Exception):
|
||||||
return self.message
|
return self.message
|
||||||
|
|
||||||
|
|
||||||
class SamePlayerMove(Exception):
|
class SamePlayerMoveError(Exception):
|
||||||
def __init__(self, message: str) -> None:
|
def __init__(self, message: str) -> None:
|
||||||
self.message = message
|
self.message = message
|
||||||
|
|
||||||
|
@ -925,10 +925,10 @@ class GameInstance:
|
||||||
try:
|
try:
|
||||||
self.model.make_move(content, self.turn, is_computer)
|
self.model.make_move(content, self.turn, is_computer)
|
||||||
# Keep the turn of the same player
|
# Keep the turn of the same player
|
||||||
except SamePlayerMove as smp:
|
except SamePlayerMoveError as smp:
|
||||||
self.same_player_turn(content, smp.message, is_computer)
|
self.same_player_turn(content, smp.message, is_computer)
|
||||||
return
|
return
|
||||||
except BadMoveException as e:
|
except BadMoveError as e:
|
||||||
self.broadcast(e.message)
|
self.broadcast(e.message)
|
||||||
self.broadcast(self.parse_current_board())
|
self.broadcast(self.parse_current_board())
|
||||||
return
|
return
|
||||||
|
|
|
@ -14,7 +14,7 @@ from typing_extensions import Protocol
|
||||||
from zulip import Client, ZulipError
|
from zulip import Client, ZulipError
|
||||||
|
|
||||||
|
|
||||||
class NoBotConfigException(Exception):
|
class NoBotConfigError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
@ -319,7 +319,7 @@ class ExternalBotHandler:
|
||||||
# on setting up the configuration specfic to this bot.
|
# on setting up the configuration specfic to this bot.
|
||||||
# And then `run.py` should also catch exceptions on how
|
# And then `run.py` should also catch exceptions on how
|
||||||
# to specify the file in the command line.
|
# to specify the file in the command line.
|
||||||
raise NoBotConfigException(bot_name)
|
raise NoBotConfigError(bot_name)
|
||||||
|
|
||||||
if bot_name not in self.bot_config_file:
|
if bot_name not in self.bot_config_file:
|
||||||
print(
|
print(
|
||||||
|
|
|
@ -8,7 +8,7 @@ from typing import Optional
|
||||||
|
|
||||||
from zulip_bots import finder
|
from zulip_bots import finder
|
||||||
from zulip_bots.lib import (
|
from zulip_bots.lib import (
|
||||||
NoBotConfigException,
|
NoBotConfigError,
|
||||||
run_message_handler_for_bot,
|
run_message_handler_for_bot,
|
||||||
zulip_env_vars_are_present,
|
zulip_env_vars_are_present,
|
||||||
)
|
)
|
||||||
|
@ -118,7 +118,7 @@ def main() -> None:
|
||||||
if args.registry:
|
if args.registry:
|
||||||
try:
|
try:
|
||||||
bot_source, lib_module = finder.import_module_from_zulip_bot_registry(args.bot)
|
bot_source, lib_module = finder.import_module_from_zulip_bot_registry(args.bot)
|
||||||
except finder.DuplicateRegisteredBotName as error:
|
except finder.DuplicateRegisteredBotNameError as error:
|
||||||
print(
|
print(
|
||||||
f'ERROR: Found duplicate entries for "{error}" in zulip bots registry.\n'
|
f'ERROR: Found duplicate entries for "{error}" in zulip bots registry.\n'
|
||||||
"Make sure that you don't install bots using the same entry point. Exiting now."
|
"Make sure that you don't install bots using the same entry point. Exiting now."
|
||||||
|
@ -182,7 +182,7 @@ def main() -> None:
|
||||||
bot_name=bot_name,
|
bot_name=bot_name,
|
||||||
bot_source=bot_source,
|
bot_source=bot_source,
|
||||||
)
|
)
|
||||||
except NoBotConfigException:
|
except NoBotConfigError:
|
||||||
print(
|
print(
|
||||||
"""
|
"""
|
||||||
ERROR: Your bot requires you to specify a third party
|
ERROR: Your bot requires you to specify a third party
|
||||||
|
|
|
@ -47,11 +47,11 @@ class StubBotHandler:
|
||||||
def upload_file(self, file: IO[Any]) -> Dict[str, Any]:
|
def upload_file(self, file: IO[Any]) -> Dict[str, Any]:
|
||||||
return self.message_server.upload_file(file)
|
return self.message_server.upload_file(file)
|
||||||
|
|
||||||
class BotQuitException(Exception):
|
class BotQuitError(Exception):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def quit(self, message: str = "") -> None:
|
def quit(self, message: str = "") -> None:
|
||||||
raise self.BotQuitException
|
raise self.BotQuitError
|
||||||
|
|
||||||
def get_config_info(self, bot_name: str, optional: bool = False) -> Dict[str, str]:
|
def get_config_info(self, bot_name: str, optional: bool = False) -> Dict[str, str]:
|
||||||
return {}
|
return {}
|
||||||
|
|
Loading…
Add table
Reference in a new issue