a3a26f2ba4
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.
118 lines
4.6 KiB
Python
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])
|