1
Fork 0
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:
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: 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,

View file

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

View file

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

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

View file

@ -160,7 +160,7 @@ 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,
@ -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)

View file

@ -156,10 +156,21 @@ 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"])
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]") f"[p]{response}[/p]")
elif isinstance(response, ResponseSuccess): elif isinstance(response, ResponseSuccess):
return response.data return response.data
@ -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:

View file

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