Files
igncore/core/message_hub_service.py
Minidodo a3a26f2ba4 get rid of the MessageDistributor module... & update discord, to work with API v10
Added discord commands (issue: as they're running over the event hub, they're processed on the same track as other events. => activity ingame triggers the next run; otherwise there's some delay for responses)
relay is a standard module now.
2022-04-15 17:05:30 +02:00

118 lines
4.6 KiB
Python

import inspect
from core.decorators import instance
from core.dict_object import DictObject
from core.logger import Logger
from core.lookup.character_service import CharacterService
from core.text import Text
@instance()
class MessageHubService:
def __init__(self):
self.logger = Logger(__name__)
self.hub = {}
self.sources = []
def inject(self, registry):
self.bot = registry.get_instance("bot")
self.setting_service = registry.get_instance("setting_service")
self.character_service: CharacterService = registry.get_instance("character_service")
self.text: Text = registry.get_instance("text")
self.db = registry.get_instance("db")
def pre_start(self):
self.db.exec("CREATE TABLE IF NOT EXISTS message_hub_subscriptions ( "
"destination VARCHAR(50) NOT NULL,"
"source VARCHAR(50) NOT NULL"
")")
def register_message_source(self, source):
"""Call during pre_start"""
if source not in self.sources:
self.sources.append(source)
def register_message_destination(self, destination, callback, default_sources, invalid_sources=None):
"""
Call during start
Args:
destination: str
callback: (ctx) -> void
default_sources: [str...]
invalid_sources: [str...]
"""
if invalid_sources is None:
invalid_sources = []
if len(inspect.signature(callback).parameters) != 1:
raise Exception(
f"Incorrect number of arguments for handler '{callback.__module__}.{callback.__name__}()'")
if destination in self.hub:
self.logger.error(f"Message hub destination '{destination}' already subscribed")
return
# raise Exception(f"Message hub destination '{destination}' already subscribed")
for source in default_sources:
if source not in self.sources:
self.logger.warning(
f"Could not subscribe destination '{destination}' to source '{source}' because source does not exist")
self.hub[destination] = (DictObject({"name": destination,
"callback": callback,
"sources": default_sources,
"invalid_sources": invalid_sources}))
self.reload_mapping(destination)
def reload_mapping(self, destination):
data = self.db.query("SELECT source FROM message_hub_subscriptions WHERE destination = ?", [destination])
if data:
self.hub[destination].sources = list(map(lambda x: x.source, data))
def send_message(self, source, sender, message, formatted_message):
ctx = DictObject({"source": source,
"sender": sender,
"message": message,
"formatted_message": formatted_message})
for _, c in self.hub.items():
if source in c.sources:
try:
c.callback(ctx)
except Exception as e:
self.logger.error("", e)
def subscribe_to_source(self, destination, source):
if source not in self.sources:
raise Exception(f"Message hub source '{source}' does not exist")
obj = self.hub.get(destination, None)
if not obj:
raise Exception(f"Message hub destination '{destination}' does not exist")
if source not in obj.sources:
self.db.exec("DELETE FROM message_hub_subscriptions WHERE destination = ?", [destination])
obj.sources.append(source)
for source in obj.sources:
self.db.exec("INSERT INTO message_hub_subscriptions (destination, source)"
"VALUES (?, ?)", [destination, source])
def unsubscribe_from_source(self, destination, source):
# if source not in self.sources:
# raise Exception("Message hub source '%s' does not exist" % source)
obj = self.hub.get(destination, None)
if not obj:
raise Exception(f"Message hub destination '{destination}' does not exist")
if source in obj.sources:
self.db.exec("DELETE FROM message_hub_subscriptions WHERE destination = ?", [destination])
obj.sources.remove(source)
for source in obj.sources:
self.db.exec("INSERT INTO message_hub_subscriptions (destination, source)"
"VALUES (?, ?)", [destination, source])