mirror of
https://github.com/RYGhub/royalnet.git
synced 2024-11-23 19:44:20 +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: Logger = getLogger("royalnet")
|
||||||
royalnet_log.setLevel(log_level)
|
royalnet_log.setLevel(log_level)
|
||||||
stream_handler = StreamHandler()
|
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.addHandler(stream_handler)
|
||||||
|
royalnet_log.debug("Logging: ready")
|
||||||
|
|
||||||
def get_secret(username: str):
|
def get_secret(username: str):
|
||||||
return keyring.get_password(f"Royalnet/{secrets_name}", username)
|
return keyring.get_password(f"Royalnet/{secrets_name}", username)
|
||||||
|
@ -141,7 +142,8 @@ def run(telegram: typing.Optional[bool],
|
||||||
'commands': enabled_commands,
|
'commands': enabled_commands,
|
||||||
'events': enabled_events,
|
'events': enabled_events,
|
||||||
'herald_config': herald_config.copy(name="telegram"),
|
'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",
|
telegram_process = multiprocessing.Process(name="Telegram Serf",
|
||||||
target=r.serf.telegram.TelegramSerf.run_process,
|
target=r.serf.telegram.TelegramSerf.run_process,
|
||||||
|
@ -163,7 +165,8 @@ def run(telegram: typing.Optional[bool],
|
||||||
'commands': enabled_commands,
|
'commands': enabled_commands,
|
||||||
'events': enabled_events,
|
'events': enabled_events,
|
||||||
'herald_config': herald_config.copy(name="discord"),
|
'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",
|
discord_process = multiprocessing.Process(name="Discord Serf",
|
||||||
target=r.serf.discord.DiscordSerf.run_process,
|
target=r.serf.discord.DiscordSerf.run_process,
|
||||||
|
@ -181,6 +184,7 @@ def run(telegram: typing.Optional[bool],
|
||||||
'database_uri': alchemy_url,
|
'database_uri': alchemy_url,
|
||||||
'page_stars': enabled_page_stars,
|
'page_stars': enabled_page_stars,
|
||||||
'exc_stars': enabled_exception_stars,
|
'exc_stars': enabled_exception_stars,
|
||||||
|
'log_level': log_level,
|
||||||
}
|
}
|
||||||
constellation_process = multiprocessing.Process(name="Constellation",
|
constellation_process = multiprocessing.Process(name="Constellation",
|
||||||
target=r.constellation.Constellation.run_process,
|
target=r.constellation.Constellation.run_process,
|
||||||
|
|
|
@ -28,9 +28,11 @@ class SummonCommand(Command):
|
||||||
else:
|
else:
|
||||||
member = None
|
member = None
|
||||||
guild = None
|
guild = None
|
||||||
try:
|
name = args.joined()
|
||||||
# TODO: do something!
|
response: dict = await self.interface.call_herald_event("discord", "summon", {
|
||||||
pass
|
"channel_name": name,
|
||||||
except Exception as e:
|
"guild_id": guild.id if guild is not None else None,
|
||||||
breakpoint()
|
"user_id": member.id if member is not None else None,
|
||||||
await data.reply(f"✅ Connesso alla chat vocale.")
|
})
|
||||||
|
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!
|
# Imports go here!
|
||||||
|
from .summon import SummonEvent
|
||||||
|
|
||||||
# Enter the commands of your Pack here!
|
# Enter the commands of your Pack here!
|
||||||
available_events = [
|
available_events = [
|
||||||
|
SummonEvent,
|
||||||
]
|
]
|
||||||
|
|
||||||
# Don't change this, it should automatically generate __all__
|
# 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,
|
database_uri: str,
|
||||||
page_stars: typing.List[typing.Type[PageStar]] = None,
|
page_stars: typing.List[typing.Type[PageStar]] = None,
|
||||||
exc_stars: typing.List[typing.Type[ExceptionStar]] = None,
|
exc_stars: typing.List[typing.Type[ExceptionStar]] = None,
|
||||||
|
log_level: str = "WARNING",
|
||||||
*,
|
*,
|
||||||
debug: bool = __debug__,):
|
debug: bool = __debug__,):
|
||||||
"""Blockingly create and run the Constellation.
|
"""Blockingly create and run the Constellation.
|
||||||
|
@ -131,6 +132,16 @@ class Constellation:
|
||||||
exc_stars=exc_stars,
|
exc_stars=exc_stars,
|
||||||
debug=debug)
|
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
|
# Initialize Sentry on the process
|
||||||
if sentry_sdk is None:
|
if sentry_sdk is None:
|
||||||
log.info("Sentry: not installed")
|
log.info("Sentry: not installed")
|
||||||
|
|
|
@ -160,12 +160,12 @@ class DiscordSerf(Serf):
|
||||||
await self.client.login(token)
|
await self.client.login(token)
|
||||||
await self.client.connect()
|
await self.client.connect()
|
||||||
|
|
||||||
async def find_channel(self,
|
def find_channel(self,
|
||||||
channel_type: Optional[Type["discord.abc.GuildChannel"]] = None,
|
channel_type: Optional[Type["discord.abc.GuildChannel"]] = None,
|
||||||
name: Optional[str] = None,
|
name: Optional[str] = None,
|
||||||
guild: Optional["discord.Guild"] = None,
|
guild: Optional["discord.Guild"] = None,
|
||||||
accessible_to: List["discord.User"] = None,
|
accessible_to: List["discord.User"] = None,
|
||||||
required_permissions: List[str] = None) -> Optional["discord.abc.GuildChannel"]:
|
required_permissions: List[str] = None) -> Optional["discord.abc.GuildChannel"]:
|
||||||
"""Find the best channel matching all requests.
|
"""Find the best channel matching all requests.
|
||||||
|
|
||||||
In case multiple channels match all requests, return the one with the most members connected.
|
In case multiple channels match all requests, return the one with the most members connected.
|
||||||
|
@ -201,11 +201,11 @@ class DiscordSerf(Serf):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
ch_guild: "discord.Guild" = ch.guild
|
ch_guild: "discord.Guild" = ch.guild
|
||||||
if ch.guild == ch_guild:
|
if ch.guild != ch_guild:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
for user in accessible_to:
|
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:
|
if member is None:
|
||||||
continue
|
continue
|
||||||
permissions: "discord.Permissions" = ch.permissions_for(member)
|
permissions: "discord.Permissions" = ch.permissions_for(member)
|
||||||
|
|
|
@ -156,11 +156,22 @@ class Serf:
|
||||||
request: Request = Request(handler=event_name, data=args)
|
request: Request = Request(handler=event_name, data=args)
|
||||||
response: Response = await self.herald.request(destination=destination, request=request)
|
response: Response = await self.herald.request(destination=destination, request=request)
|
||||||
if isinstance(response, ResponseFailure):
|
if isinstance(response, ResponseFailure):
|
||||||
|
# TODO: pretty sure there's a better way to do this
|
||||||
if response.extra_info["type"] == "CommandError":
|
if response.extra_info["type"] == "CommandError":
|
||||||
raise CommandError(response.extra_info["message"])
|
raise CommandError(response.extra_info["message"])
|
||||||
# TODO: change exception type
|
elif response.extra_info["type"] == "UserError":
|
||||||
raise Exception(f"Herald action call failed:\n"
|
raise UserError(response.extra_info["message"])
|
||||||
f"[p]{response}[/p]")
|
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):
|
elif isinstance(response, ResponseSuccess):
|
||||||
return response.data
|
return response.data
|
||||||
else:
|
else:
|
||||||
|
@ -233,8 +244,6 @@ class Serf:
|
||||||
response_data = await event.run(**message.data)
|
response_data = await event.run(**message.data)
|
||||||
return ResponseSuccess(data=response_data)
|
return ResponseSuccess(data=response_data)
|
||||||
except Exception as e:
|
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",
|
return ResponseFailure("exception_in_event",
|
||||||
f"An exception was raised in the event for '{message.handler}'.",
|
f"An exception was raised in the event for '{message.handler}'.",
|
||||||
extra_info={
|
extra_info={
|
||||||
|
@ -290,8 +299,7 @@ class Serf:
|
||||||
await data.reply(f"⚠️ {e.message}")
|
await data.reply(f"⚠️ {e.message}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.sentry_exc(e)
|
self.sentry_exc(e)
|
||||||
error_message = f"⛔ [b]{e.__class__.__name__}[/b]\n" \
|
error_message = f"⛔️ [b]{e.__class__.__name__}[/b]\n" + '\n'.join(e.args)
|
||||||
'\n'.join(e.args)
|
|
||||||
await data.reply(error_message)
|
await data.reply(error_message)
|
||||||
|
|
||||||
async def run(self):
|
async def run(self):
|
||||||
|
@ -300,12 +308,21 @@ class Serf:
|
||||||
# OVERRIDE THIS METHOD!
|
# OVERRIDE THIS METHOD!
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def run_process(cls, *args, **kwargs):
|
def run_process(cls, *args, log_level: str = "WARNING", **kwargs):
|
||||||
"""Blockingly create and run the Serf.
|
"""Blockingly create and run the Serf.
|
||||||
|
|
||||||
This should be used as the target of a :class:`multiprocessing.Process`."""
|
This should be used as the target of a :class:`multiprocessing.Process`."""
|
||||||
serf = cls(*args, **kwargs)
|
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:
|
if sentry_sdk is None:
|
||||||
log.info("Sentry: not installed")
|
log.info("Sentry: not installed")
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -196,7 +196,7 @@ class TelegramSerf(Serf):
|
||||||
else:
|
else:
|
||||||
session = None
|
session = None
|
||||||
# Prepare data
|
# 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
|
# Call the command
|
||||||
await self.call(command, data, parameters)
|
await self.call(command, data, parameters)
|
||||||
# Close the alchemy session
|
# Close the alchemy session
|
||||||
|
|
Loading…
Reference in a new issue