mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 11:34:18 +00:00
it... works? surprisingly?
This commit is contained in:
parent
a5ff59779a
commit
3feca93486
8 changed files with 121 additions and 28 deletions
|
@ -47,8 +47,9 @@ def run(telegram: typing.Optional[bool],
|
|||
royalnet_log: Logger = getLogger("royalnet")
|
||||
royalnet_log.setLevel(log_level)
|
||||
stream_handler = StreamHandler()
|
||||
stream_handler.formatter = Formatter("{asctime}\t| {processName}\t| {levelname}\t| {message}", style="{")
|
||||
stream_handler.formatter = Formatter("{asctime}\t| {processName}\t| {levelname}\t| {name}\t| {message}", style="{")
|
||||
royalnet_log.addHandler(stream_handler)
|
||||
royalnet_log.debug("Logging: ready")
|
||||
|
||||
def get_secret(username: str):
|
||||
return keyring.get_password(f"Royalnet/{secrets_name}", username)
|
||||
|
@ -141,7 +142,8 @@ def run(telegram: typing.Optional[bool],
|
|||
'commands': enabled_commands,
|
||||
'events': enabled_events,
|
||||
'herald_config': herald_config.copy(name="telegram"),
|
||||
'secrets_name': secrets_name
|
||||
'secrets_name': secrets_name,
|
||||
'log_level': log_level,
|
||||
}
|
||||
telegram_process = multiprocessing.Process(name="Telegram Serf",
|
||||
target=r.serf.telegram.TelegramSerf.run_process,
|
||||
|
@ -163,7 +165,8 @@ def run(telegram: typing.Optional[bool],
|
|||
'commands': enabled_commands,
|
||||
'events': enabled_events,
|
||||
'herald_config': herald_config.copy(name="discord"),
|
||||
'secrets_name': secrets_name
|
||||
'secrets_name': secrets_name,
|
||||
'log_level': log_level,
|
||||
}
|
||||
discord_process = multiprocessing.Process(name="Discord Serf",
|
||||
target=r.serf.discord.DiscordSerf.run_process,
|
||||
|
@ -181,6 +184,7 @@ def run(telegram: typing.Optional[bool],
|
|||
'database_uri': alchemy_url,
|
||||
'page_stars': enabled_page_stars,
|
||||
'exc_stars': enabled_exception_stars,
|
||||
'log_level': log_level,
|
||||
}
|
||||
constellation_process = multiprocessing.Process(name="Constellation",
|
||||
target=r.constellation.Constellation.run_process,
|
||||
|
|
|
@ -28,9 +28,11 @@ class SummonCommand(Command):
|
|||
else:
|
||||
member = None
|
||||
guild = None
|
||||
try:
|
||||
# TODO: do something!
|
||||
pass
|
||||
except Exception as e:
|
||||
breakpoint()
|
||||
await data.reply(f"✅ Connesso alla chat vocale.")
|
||||
name = args.joined()
|
||||
response: dict = await self.interface.call_herald_event("discord", "summon", {
|
||||
"channel_name": name,
|
||||
"guild_id": guild.id if guild is not None else None,
|
||||
"user_id": member.id if member is not None else None,
|
||||
})
|
||||
await data.reply(f"✅ Connected to [b]#{response['channel']['name']}[/b]"
|
||||
f" in [i]{response['channel']['guild']['name']}[/i]!")
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
# Imports go here!
|
||||
|
||||
from .summon import SummonEvent
|
||||
|
||||
# Enter the commands of your Pack here!
|
||||
available_events = [
|
||||
|
||||
SummonEvent,
|
||||
]
|
||||
|
||||
# Don't change this, it should automatically generate __all__
|
||||
|
|
59
royalnet/backpack/events/summon.py
Normal file
59
royalnet/backpack/events/summon.py
Normal file
|
@ -0,0 +1,59 @@
|
|||
from typing import Optional
|
||||
from royalnet.commands import *
|
||||
from royalnet.serf.discord import DiscordSerf
|
||||
|
||||
try:
|
||||
import discord
|
||||
except ImportError:
|
||||
discord = None
|
||||
|
||||
|
||||
class SummonEvent(Event):
|
||||
name = "summon"
|
||||
|
||||
async def run(self, *, channel_name: str, guild_id: Optional[int], user_id: Optional[int], **kwargs):
|
||||
if not isinstance(self.serf, DiscordSerf):
|
||||
raise UnsupportedError("Summon can't be called on interfaces other than Discord.")
|
||||
if discord is None:
|
||||
raise UnsupportedError("'discord' extra is not installed.")
|
||||
# Find the guild
|
||||
if guild_id is not None:
|
||||
guild: Optional["discord.Guild"] = self.serf.client.get_guild(guild_id)
|
||||
else:
|
||||
guild = None
|
||||
# Find the member
|
||||
if user_id is not None and guild is not None:
|
||||
member = guild.get_member(user_id=user_id)
|
||||
else:
|
||||
member = None
|
||||
# Find accessible_to
|
||||
accessible_to = [self.serf.client.user]
|
||||
if member is not None:
|
||||
accessible_to.append(member)
|
||||
# Find the channel
|
||||
channel: Optional["discord.VoiceChannel"] = self.serf.find_channel(channel_type=discord.VoiceChannel,
|
||||
name=channel_name,
|
||||
guild=guild,
|
||||
accessible_to=accessible_to,
|
||||
required_permissions=["connect", "speak"])
|
||||
if channel is None:
|
||||
raise InvalidInputError("No channels found with the specified name.")
|
||||
# Connect to the channel
|
||||
await self.serf.voice_connect(channel)
|
||||
# Find the created bard
|
||||
bard = self.serf.bards[channel.guild]
|
||||
bard_peek = await bard.peek()
|
||||
# Reply to the request
|
||||
return {
|
||||
"channel": {
|
||||
"id": channel.id,
|
||||
"name": channel.name,
|
||||
"guild": {
|
||||
"name": channel.guild.name,
|
||||
},
|
||||
},
|
||||
"bard": {
|
||||
"type": bard.__class__.__qualname__,
|
||||
"peek": bard_peek,
|
||||
}
|
||||
}
|
|
@ -116,6 +116,7 @@ class Constellation:
|
|||
database_uri: str,
|
||||
page_stars: typing.List[typing.Type[PageStar]] = None,
|
||||
exc_stars: typing.List[typing.Type[ExceptionStar]] = None,
|
||||
log_level: str = "WARNING",
|
||||
*,
|
||||
debug: bool = __debug__,):
|
||||
"""Blockingly create and run the Constellation.
|
||||
|
@ -131,6 +132,16 @@ class Constellation:
|
|||
exc_stars=exc_stars,
|
||||
debug=debug)
|
||||
|
||||
# Initialize logging, as Windows doesn't have fork
|
||||
royalnet_log: logging.Logger = logging.getLogger("royalnet")
|
||||
royalnet_log.setLevel(log_level)
|
||||
stream_handler = logging.StreamHandler()
|
||||
stream_handler.formatter = logging.Formatter("{asctime}\t| {processName}\t| {levelname}\t| {name}\t| {message}",
|
||||
style="{")
|
||||
if len(royalnet_log.handlers) < 1:
|
||||
royalnet_log.addHandler(stream_handler)
|
||||
royalnet_log.debug("Logging: ready")
|
||||
|
||||
# Initialize Sentry on the process
|
||||
if sentry_sdk is None:
|
||||
log.info("Sentry: not installed")
|
||||
|
|
|
@ -160,12 +160,12 @@ class DiscordSerf(Serf):
|
|||
await self.client.login(token)
|
||||
await self.client.connect()
|
||||
|
||||
async def find_channel(self,
|
||||
channel_type: Optional[Type["discord.abc.GuildChannel"]] = None,
|
||||
name: Optional[str] = None,
|
||||
guild: Optional["discord.Guild"] = None,
|
||||
accessible_to: List["discord.User"] = None,
|
||||
required_permissions: List[str] = None) -> Optional["discord.abc.GuildChannel"]:
|
||||
def find_channel(self,
|
||||
channel_type: Optional[Type["discord.abc.GuildChannel"]] = None,
|
||||
name: Optional[str] = None,
|
||||
guild: Optional["discord.Guild"] = None,
|
||||
accessible_to: List["discord.User"] = None,
|
||||
required_permissions: List[str] = None) -> Optional["discord.abc.GuildChannel"]:
|
||||
"""Find the best channel matching all requests.
|
||||
|
||||
In case multiple channels match all requests, return the one with the most members connected.
|
||||
|
@ -201,11 +201,11 @@ class DiscordSerf(Serf):
|
|||
pass
|
||||
|
||||
ch_guild: "discord.Guild" = ch.guild
|
||||
if ch.guild == ch_guild:
|
||||
if ch.guild != ch_guild:
|
||||
continue
|
||||
|
||||
for user in accessible_to:
|
||||
member: "discord.Member" = guild.get_member(user.id)
|
||||
member: "discord.Member" = ch.guild.get_member(user.id)
|
||||
if member is None:
|
||||
continue
|
||||
permissions: "discord.Permissions" = ch.permissions_for(member)
|
||||
|
|
|
@ -156,11 +156,22 @@ class Serf:
|
|||
request: Request = Request(handler=event_name, data=args)
|
||||
response: Response = await self.herald.request(destination=destination, request=request)
|
||||
if isinstance(response, ResponseFailure):
|
||||
# TODO: pretty sure there's a better way to do this
|
||||
if response.extra_info["type"] == "CommandError":
|
||||
raise CommandError(response.extra_info["message"])
|
||||
# TODO: change exception type
|
||||
raise Exception(f"Herald action call failed:\n"
|
||||
f"[p]{response}[/p]")
|
||||
elif response.extra_info["type"] == "UserError":
|
||||
raise UserError(response.extra_info["message"])
|
||||
elif response.extra_info["type"] == "InvalidInputError":
|
||||
raise InvalidInputError(response.extra_info["message"])
|
||||
elif response.extra_info["type"] == "UnsupportedError":
|
||||
raise UnsupportedError(response.extra_info["message"])
|
||||
elif response.extra_info["type"] == "ConfigurationError":
|
||||
raise ConfigurationError(response.extra_info["message"])
|
||||
elif response.extra_info["type"] == "ExternalError":
|
||||
raise ExternalError(response.extra_info["message"])
|
||||
else:
|
||||
raise TypeError(f"Herald action call returned invalid error:\n"
|
||||
f"[p]{response}[/p]")
|
||||
elif isinstance(response, ResponseSuccess):
|
||||
return response.data
|
||||
else:
|
||||
|
@ -233,8 +244,6 @@ class Serf:
|
|||
response_data = await event.run(**message.data)
|
||||
return ResponseSuccess(data=response_data)
|
||||
except Exception as e:
|
||||
sentry_sdk.capture_exception(e)
|
||||
log.error(f"Event error: {e.__class__.__qualname__} in {event.name}")
|
||||
return ResponseFailure("exception_in_event",
|
||||
f"An exception was raised in the event for '{message.handler}'.",
|
||||
extra_info={
|
||||
|
@ -290,8 +299,7 @@ class Serf:
|
|||
await data.reply(f"⚠️ {e.message}")
|
||||
except Exception as e:
|
||||
self.sentry_exc(e)
|
||||
error_message = f"⛔ [b]{e.__class__.__name__}[/b]\n" \
|
||||
'\n'.join(e.args)
|
||||
error_message = f"⛔️ [b]{e.__class__.__name__}[/b]\n" + '\n'.join(e.args)
|
||||
await data.reply(error_message)
|
||||
|
||||
async def run(self):
|
||||
|
@ -300,12 +308,21 @@ class Serf:
|
|||
# OVERRIDE THIS METHOD!
|
||||
|
||||
@classmethod
|
||||
def run_process(cls, *args, **kwargs):
|
||||
def run_process(cls, *args, log_level: str = "WARNING", **kwargs):
|
||||
"""Blockingly create and run the Serf.
|
||||
|
||||
This should be used as the target of a :class:`multiprocessing.Process`."""
|
||||
serf = cls(*args, **kwargs)
|
||||
|
||||
royalnet_log: logging.Logger = logging.getLogger("royalnet")
|
||||
royalnet_log.setLevel(log_level)
|
||||
stream_handler = logging.StreamHandler()
|
||||
stream_handler.formatter = logging.Formatter("{asctime}\t| {processName}\t| {levelname}\t| {name}\t| {message}",
|
||||
style="{")
|
||||
if len(royalnet_log.handlers) < 1:
|
||||
royalnet_log.addHandler(stream_handler)
|
||||
royalnet_log.debug("Logging: ready")
|
||||
|
||||
if sentry_sdk is None:
|
||||
log.info("Sentry: not installed")
|
||||
else:
|
||||
|
|
|
@ -196,7 +196,7 @@ class TelegramSerf(Serf):
|
|||
else:
|
||||
session = None
|
||||
# Prepare data
|
||||
data = self.Data(interface=command.interface, session=session, loop=self.loop, message=message)
|
||||
data = self.Data(interface=command.interface, session=session, loop=self.loop, update=update)
|
||||
# Call the command
|
||||
await self.call(command, data, parameters)
|
||||
# Close the alchemy session
|
||||
|
|
Loading…
Reference in a new issue