Removed async code

This commit is contained in:
Felipe M 2020-10-28 11:19:30 +01:00 committed by Felipe Martin Garcia
parent 62fb0ec8d4
commit 6d3ad14298
12 changed files with 296 additions and 487 deletions

View File

@ -1,7 +1,6 @@
import asyncio
import traceback import traceback
from quart import Quart, request from flask import Flask, request
import structlog import structlog
import butterrobot.logging # noqa import butterrobot.logging # noqa
@ -13,7 +12,7 @@ from butterrobot.platforms.base import Platform
logger = structlog.get_logger(__name__) logger = structlog.get_logger(__name__)
app = Quart(__name__) app = Flask(__name__)
available_platforms = {} available_platforms = {}
plugins = get_available_plugins() plugins = get_available_plugins()
enabled_plugins = [ enabled_plugins = [
@ -21,18 +20,18 @@ enabled_plugins = [
] ]
async def handle_message(platform: str, message: Message): def handle_message(platform: str, message: Message):
for plugin in enabled_plugins: for plugin in enabled_plugins:
async for response_message in plugin.on_message(message): for response_message in plugin.on_message(message):
asyncio.ensure_future(available_platforms[platform].methods.send_message(response_message)) available_platforms[platform].methods.send_message(response_message)
@app.before_serving @app.before_first_request
async def init_platforms(): def init_platforms():
for platform in PLATFORMS.values(): for platform in PLATFORMS.values():
logger.debug("Setting up", platform=platform.ID) logger.debug("Setting up", platform=platform.ID)
try: try:
await platform.init(app=app) platform.init(app=app)
available_platforms[platform.ID] = platform available_platforms[platform.ID] = platform
logger.info("platform setup completed", platform=platform.ID) logger.info("platform setup completed", platform=platform.ID)
except platform.PlatformInitError as error: except platform.PlatformInitError as error:
@ -41,12 +40,12 @@ async def init_platforms():
@app.route("/<platform>/incoming", methods=["POST"]) @app.route("/<platform>/incoming", methods=["POST"])
@app.route("/<platform>/incoming/<path:path>", methods=["POST"]) @app.route("/<platform>/incoming/<path:path>", methods=["POST"])
async def incoming_platform_message_view(platform, path=None): def incoming_platform_message_view(platform, path=None):
if platform not in available_platforms: if platform not in available_platforms:
return {"error": "Unknown platform"}, 400 return {"error": "Unknown platform"}, 400
try: try:
message = await available_platforms[platform].parse_incoming_message( message = available_platforms[platform].parse_incoming_message(
request=request request=request
) )
except Platform.PlatformAuthResponse as response: except Platform.PlatformAuthResponse as response:
@ -63,7 +62,8 @@ async def incoming_platform_message_view(platform, path=None):
if not message or message.from_bot: if not message or message.from_bot:
return {} return {}
asyncio.ensure_future(handle_message(platform, message)) # TODO: make with rq/dramatiq
handle_message(platform, message)
return {} return {}

View File

@ -1,6 +1,6 @@
from typing import Optional, Text from typing import Optional, Text
import aiohttp import requests
import structlog import structlog
from butterrobot.config import SLACK_BOT_OAUTH_ACCESS_TOKEN from butterrobot.config import SLACK_BOT_OAUTH_ACCESS_TOKEN
@ -19,7 +19,7 @@ class SlackAPI:
pass pass
@classmethod @classmethod
async def send_message(cls, channel, message, thread: Optional[Text] = None): def send_message(cls, channel, message, thread: Optional[Text] = None):
payload = { payload = {
"text": message, "text": message,
"channel": channel, "channel": channel,
@ -28,12 +28,11 @@ class SlackAPI:
if thread: if thread:
payload["thread_ts"] = thread payload["thread_ts"] = thread
async with aiohttp.ClientSession() as session: response = requestts.post(
async with session.post(
f"{cls.BASE_URL}/chat.postMessage", f"{cls.BASE_URL}/chat.postMessage",
data=payload, data=payload,
headers={"Authorization": f"Bearer {SLACK_BOT_OAUTH_ACCESS_TOKEN}"}, headers={"Authorization": f"Bearer {SLACK_BOT_OAUTH_ACCESS_TOKEN}"},
) as response: )
response = await response.json() response_json = response.json()
if not response["ok"]: if not response_json["ok"]:
raise cls.SlackClientError(response) raise cls.SlackClientError(response_json)

View File

@ -1,4 +1,4 @@
import aiohttp import requests
import structlog import structlog
from butterrobot.config import TELEGRAM_TOKEN from butterrobot.config import TELEGRAM_TOKEN
@ -19,7 +19,7 @@ class TelegramAPI:
pass pass
@classmethod @classmethod
async def set_webhook(cls, webhook_url, max_connections=40, allowed_updates=None): def set_webhook(cls, webhook_url, max_connections=40, allowed_updates=None):
allowed_updates = allowed_updates or cls.DEFAULT_ALLOWED_UPDATES allowed_updates = allowed_updates or cls.DEFAULT_ALLOWED_UPDATES
url = f"{cls.BASE_URL}/setWebhook" url = f"{cls.BASE_URL}/setWebhook"
payload = { payload = {
@ -27,14 +27,13 @@ class TelegramAPI:
"max_connections": max_connections, "max_connections": max_connections,
"allowed_updates": allowed_updates, "allowed_updates": allowed_updates,
} }
async with aiohttp.ClientSession() as session: response = requests.post(url, json=payload)
async with session.post(url, json=payload) as response: response_json = response.json()
response = await response.json() if not response_json["ok"]:
if not response["ok"]: raise cls.TelegramClientError(response_json)
raise cls.TelegramClientError(response)
@classmethod @classmethod
async def send_message( def send_message(
cls, cls,
chat_id, chat_id,
text, text,
@ -52,8 +51,8 @@ class TelegramAPI:
"disable_notification": disable_notification, "disable_notification": disable_notification,
"reply_to_message_id": reply_to_message_id, "reply_to_message_id": reply_to_message_id,
} }
async with aiohttp.ClientSession() as session:
async with session.post(url, json=payload) as response: response = requests.post(url, json=payload)
response = await response.json() response_json = response.json()
if not response["ok"]: if not response_json["ok"]:
raise cls.TelegramClientError(response) raise cls.TelegramClientError(response_json)

View File

@ -21,7 +21,7 @@ class Platform:
status_code: int = 200 status_code: int = 200
@classmethod @classmethod
async def init(cls, app): def init(cls, app):
pass pass

View File

@ -12,7 +12,7 @@ logger = structlog.get_logger(__name__)
class DebugMethods(PlatformMethods): class DebugMethods(PlatformMethods):
@classmethod @classmethod
async def send_message(self, message: Message): def send_message(self, message: Message):
logger.debug( logger.debug(
"Outgoing message", message=message.__dict__, platform=DebugPlatform.ID "Outgoing message", message=message.__dict__, platform=DebugPlatform.ID
) )
@ -24,8 +24,8 @@ class DebugPlatform(Platform):
methods = DebugMethods methods = DebugMethods
@classmethod @classmethod
async def parse_incoming_message(cls, request): def parse_incoming_message(cls, request):
request_data = await request.get_json() request_data = request.get_json()
logger.debug("Parsing message", data=request_data, platform=cls.ID) logger.debug("Parsing message", data=request_data, platform=cls.ID)
return Message( return Message(

View File

@ -13,12 +13,12 @@ logger = structlog.get_logger(__name__)
class SlackMethods(PlatformMethods): class SlackMethods(PlatformMethods):
@classmethod @classmethod
async def send_message(self, message: Message): def send_message(self, message: Message):
logger.debug( logger.debug(
"Outgoing message", message=message.__dict__, platform=SlackPlatform.ID "Outgoing message", message=message.__dict__, platform=SlackPlatform.ID
) )
try: try:
await SlackAPI.send_message( SlackAPI.send_message(
channel=message.chat, message=message.text, thread=message.reply_to channel=message.chat, message=message.text, thread=message.reply_to
) )
except SlackAPI.SlackClientError as error: except SlackAPI.SlackClientError as error:
@ -36,14 +36,14 @@ class SlackPlatform(Platform):
methods = SlackMethods methods = SlackMethods
@classmethod @classmethod
async def init(cls, app): def init(cls, app):
if not (SLACK_TOKEN and SLACK_BOT_OAUTH_ACCESS_TOKEN): if not (SLACK_TOKEN and SLACK_BOT_OAUTH_ACCESS_TOKEN):
logger.error("Missing token. platform not enabled.", platform=cls.ID) logger.error("Missing token. platform not enabled.", platform=cls.ID)
return return
@classmethod @classmethod
async def parse_incoming_message(cls, request): def parse_incoming_message(cls, request):
data = await request.get_json() data = request.get_json()
# Auth # Auth
if data.get("token") != SLACK_TOKEN: if data.get("token") != SLACK_TOKEN:

View File

@ -13,11 +13,11 @@ logger = structlog.get_logger(__name__)
class TelegramMethods(PlatformMethods): class TelegramMethods(PlatformMethods):
@classmethod @classmethod
async def send_message(self, message: Message): def send_message(self, message: Message):
logger.debug( logger.debug(
"Outgoing message", message=message.__dict__, platform=TelegramPlatform.ID "Outgoing message", message=message.__dict__, platform=TelegramPlatform.ID
) )
await TelegramAPI.send_message( TelegramAPI.send_message(
chat_id=message.chat, chat_id=message.chat,
text=message.text, text=message.text,
reply_to_message_id=message.reply_to, reply_to_message_id=message.reply_to,
@ -30,7 +30,7 @@ class TelegramPlatform(Platform):
methods = TelegramMethods methods = TelegramMethods
@classmethod @classmethod
async def init(cls, app): def init(cls, app):
""" """
Initializes the Telegram webhook endpoint to receive updates Initializes the Telegram webhook endpoint to receive updates
""" """
@ -41,18 +41,18 @@ class TelegramPlatform(Platform):
webhook_url = f"https://{HOSTNAME}/telegram/incoming/{TELEGRAM_TOKEN}" webhook_url = f"https://{HOSTNAME}/telegram/incoming/{TELEGRAM_TOKEN}"
try: try:
await TelegramAPI.set_webhook(webhook_url) TelegramAPI.set_webhook(webhook_url)
except TelegramAPI.TelegramError as error: except TelegramAPI.TelegramError as error:
logger.error(f"Error setting Telegram webhook: {error}", platform=cls.ID) logger.error(f"Error setting Telegram webhook: {error}", platform=cls.ID)
raise Platform.PlatformInitError() raise Platform.PlatformInitError()
@classmethod @classmethod
async def parse_incoming_message(cls, request): def parse_incoming_message(cls, request):
token = request.path.split("/")[-1] token = request.path.split("/")[-1]
if token != TELEGRAM_TOKEN: if token != TELEGRAM_TOKEN:
raise cls.PlatformAuthError("Authentication error") raise cls.PlatformAuthError("Authentication error")
request_data = await request.get_json() request_data = request.get_json()
logger.debug("Parsing message", data=request_data, platform=cls.ID) logger.debug("Parsing message", data=request_data, platform=cls.ID)
if "text" in request_data["message"]: if "text" in request_data["message"]:

View File

@ -11,7 +11,7 @@ logger = structlog.get_logger(__name__)
class Plugin: class Plugin:
@abstractclassmethod @abstractclassmethod
async def on_message(cls, message: Message): def on_message(cls, message: Message):
pass pass

View File

@ -8,7 +8,7 @@ class PingPlugin(Plugin):
id = "contrib/dev/ping" id = "contrib/dev/ping"
@classmethod @classmethod
async def on_message(cls, message): def on_message(cls, message):
if message.text == "!ping": if message.text == "!ping":
delta = datetime.now() - message.date delta = datetime.now() - message.date
delta_ms = delta.seconds * 1000 + delta.microseconds / 1000 delta_ms = delta.seconds * 1000 + delta.microseconds / 1000

View File

@ -8,7 +8,7 @@ class LoquitoPlugin(Plugin):
id = "contrib/fun/loquito" id = "contrib/fun/loquito"
@classmethod @classmethod
async def on_message(cls, message): def on_message(cls, message):
if "lo quito" in message.text.lower(): if "lo quito" in message.text.lower():
yield Message(chat=message.chat, reply_to=message.id, text="Loquito tu.",) yield Message(chat=message.chat, reply_to=message.id, text="Loquito tu.",)
@ -17,7 +17,7 @@ class DicePlugin(Plugin):
id = "contrib/fun/dice" id = "contrib/fun/dice"
@classmethod @classmethod
async def on_message(cls, message: Message): def on_message(cls, message: Message):
if message.text.startswith("!dice"): if message.text.startswith("!dice"):
roll = int(dice.roll(message.text.replace("!dice ", ""))) roll = int(dice.roll(message.text.replace("!dice ", "")))
yield Message(chat=message.chat, reply_to=message.id, text=roll) yield Message(chat=message.chat, reply_to=message.id, text=roll)

677
poetry.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -13,11 +13,11 @@ readme = "README.md"
[tool.poetry.dependencies] [tool.poetry.dependencies]
python = "^3.7" python = "^3.7"
quart = "^0.11.3"
aiohttp = "^3.6.2"
structlog = "^20.1.0" structlog = "^20.1.0"
colorama = "^0.4.3" colorama = "^0.4.3"
dice = "^3.1.0" dice = "^3.1.0"
flask = "^1.1.2"
requests = "^2.24.0"
[tool.poetry.dev-dependencies] [tool.poetry.dev-dependencies]
black = "^19.10b0" black = "^19.10b0"