1
Fork 0
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:
Steffo 2019-11-20 01:55:04 +01:00
parent a5ff59779a
commit 3feca93486
8 changed files with 121 additions and 28 deletions

View file

@ -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,

View file

@ -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]!")

View file

@ -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__

View 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,
}
}

View file

@ -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")

View file

@ -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)

View file

@ -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:

View file

@ -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