2021-01-10 17:37:18 +00:00
|
|
|
# Module docstring
|
|
|
|
"""
|
2021-03-31 03:01:40 +00:00
|
|
|
:class:`royalnet.engineer.proj.Bullet`\\ s for the :mod:`royalnet_console` frontend.
|
2021-01-10 17:37:18 +00:00
|
|
|
"""
|
|
|
|
|
|
|
|
# Special imports
|
|
|
|
from __future__ import annotations
|
|
|
|
import royalnet.royaltyping as t
|
|
|
|
|
|
|
|
# External imports
|
|
|
|
import logging
|
|
|
|
import datetime
|
|
|
|
import os
|
|
|
|
import getpass
|
|
|
|
import psutil
|
|
|
|
import royalnet.engineer as engi
|
2021-03-31 03:01:40 +00:00
|
|
|
import click
|
2021-03-31 14:13:21 +00:00
|
|
|
import async_property as ap
|
2021-01-10 17:37:18 +00:00
|
|
|
|
|
|
|
# Special global objects
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
# Code
|
2021-03-31 03:01:40 +00:00
|
|
|
async def console_message(*,
|
|
|
|
text: str = None,
|
|
|
|
files: t.List[t.BinaryIO] = None) -> engi.Message:
|
|
|
|
"""
|
|
|
|
Output a message to the console and return the resulting proj.
|
|
|
|
|
|
|
|
:param text: The text of the message.
|
|
|
|
:param files: A :class:`list` of files to attach to the message.
|
|
|
|
:return: The sent :class:`.engi.Message`.
|
|
|
|
"""
|
|
|
|
if files is None:
|
|
|
|
files = []
|
|
|
|
|
|
|
|
if len(files) > 0:
|
|
|
|
raise engi.NotSupportedError("Console does not allow sending files.")
|
|
|
|
|
|
|
|
log.debug("Sending message...")
|
|
|
|
click.echo(text)
|
2021-01-10 17:37:18 +00:00
|
|
|
|
2021-03-31 03:01:40 +00:00
|
|
|
log.debug("Creating proj...")
|
|
|
|
return ConsoleMessage(_text=text)
|
|
|
|
|
|
|
|
|
|
|
|
class ConsoleUser(engi.User):
|
2021-01-10 17:37:18 +00:00
|
|
|
def __hash__(self) -> int:
|
|
|
|
return os.getuid()
|
|
|
|
|
2021-03-31 14:13:21 +00:00
|
|
|
@ap.async_property
|
2021-01-10 17:37:18 +00:00
|
|
|
async def name(self) -> str:
|
|
|
|
return getpass.getuser()
|
|
|
|
|
2021-03-31 14:13:21 +00:00
|
|
|
async def slide(self) -> "engi.Channel":
|
|
|
|
return ConsoleChannel()
|
2021-01-10 17:37:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ConsoleChannel(engi.Channel):
|
|
|
|
def __hash__(self) -> int:
|
|
|
|
return os.getpid()
|
|
|
|
|
2021-03-31 14:13:21 +00:00
|
|
|
@ap.async_property
|
2021-01-10 17:37:18 +00:00
|
|
|
async def name(self) -> str:
|
|
|
|
return psutil.Process(os.getpid()).name()
|
|
|
|
|
2021-03-31 14:13:21 +00:00
|
|
|
@ap.async_property
|
2021-01-10 17:37:18 +00:00
|
|
|
async def users(self) -> t.List[engi.User]:
|
2021-03-31 03:01:40 +00:00
|
|
|
return [ConsoleUser()]
|
2021-01-10 17:37:18 +00:00
|
|
|
|
|
|
|
async def send_message(self, *,
|
|
|
|
text: str = None,
|
|
|
|
files: t.List[t.BinaryIO] = None) -> engi.Message:
|
2021-03-31 03:01:40 +00:00
|
|
|
return await console_message(text=text, files=files)
|
2021-01-10 17:37:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
class ConsoleMessage(engi.Message):
|
|
|
|
_instance_count: int = 0
|
|
|
|
|
2021-03-31 03:01:40 +00:00
|
|
|
def __init__(self, _text: str, _timestamp: datetime.datetime = None):
|
|
|
|
super().__init__()
|
2021-01-10 17:37:18 +00:00
|
|
|
self._text: str = _text
|
|
|
|
self._timestamp: datetime.datetime = _timestamp or datetime.datetime.now()
|
|
|
|
self._instance_number: int = self._instance_count
|
|
|
|
self._instance_count += 1
|
|
|
|
|
|
|
|
def __hash__(self) -> int:
|
|
|
|
return self._instance_number
|
|
|
|
|
2021-03-31 14:13:21 +00:00
|
|
|
@ap.async_property
|
2021-01-10 17:37:18 +00:00
|
|
|
async def text(self) -> str:
|
|
|
|
return self._text
|
|
|
|
|
2021-03-31 14:13:21 +00:00
|
|
|
@ap.async_property
|
2021-01-10 17:37:18 +00:00
|
|
|
async def timestamp(self) -> datetime.datetime:
|
|
|
|
return self._timestamp
|
|
|
|
|
2021-03-31 14:13:21 +00:00
|
|
|
@ap.async_property
|
2021-01-10 17:37:18 +00:00
|
|
|
async def channel(self) -> engi.Channel:
|
2021-03-31 03:01:40 +00:00
|
|
|
return ConsoleChannel()
|
2021-01-10 17:37:18 +00:00
|
|
|
|
2021-03-31 14:13:21 +00:00
|
|
|
async def reply(self, *,
|
|
|
|
text: str = None,
|
|
|
|
files: t.List[t.BinaryIO] = None) -> engi.Message:
|
2021-03-31 03:01:40 +00:00
|
|
|
return await console_message(text=text, files=files)
|
|
|
|
|
|
|
|
|
|
|
|
class ConsoleMessageReceived(engi.MessageReceived):
|
|
|
|
_instance_count: int = 0
|
|
|
|
|
|
|
|
def __init__(self, _text: str, _timestamp: datetime.datetime = None):
|
|
|
|
super().__init__()
|
|
|
|
self._msg: ConsoleMessage = ConsoleMessage(_text=_text, _timestamp=_timestamp)
|
|
|
|
self._instance_number: int = self._instance_count
|
|
|
|
self._instance_count += 1
|
|
|
|
|
|
|
|
def __hash__(self):
|
|
|
|
return
|
|
|
|
|
2021-03-31 14:13:21 +00:00
|
|
|
@ap.async_property
|
2021-03-31 03:01:40 +00:00
|
|
|
async def message(self) -> ConsoleMessage:
|
|
|
|
return self._msg
|
2021-01-10 17:37:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
# Objects exported by this module
|
|
|
|
__all__ = (
|
|
|
|
"ConsoleUser",
|
|
|
|
"ConsoleChannel",
|
|
|
|
"ConsoleMessage",
|
2021-03-31 03:01:40 +00:00
|
|
|
"ConsoleMessageReceived",
|
2021-01-10 17:37:18 +00:00
|
|
|
)
|