From 5b7c2e83d19e511d11ccca595a05546886b5eb88 Mon Sep 17 00:00:00 2001 From: adator <85586985+adator85@users.noreply.github.com> Date: Thu, 20 Nov 2025 14:04:19 +0100 Subject: [PATCH] Adapt mod_jsonrpc to the new asyncio approach. --- mods/jsonrpc/mod_jsonrpc.py | 211 ++++++++++++++++++------------------ mods/jsonrpc/schemas.py | 5 + mods/jsonrpc/threads.py | 53 +++++---- 3 files changed, 143 insertions(+), 126 deletions(-) create mode 100644 mods/jsonrpc/schemas.py diff --git a/mods/jsonrpc/mod_jsonrpc.py b/mods/jsonrpc/mod_jsonrpc.py index bc8fd33..61787d3 100644 --- a/mods/jsonrpc/mod_jsonrpc.py +++ b/mods/jsonrpc/mod_jsonrpc.py @@ -1,19 +1,24 @@ import logging +from typing import TYPE_CHECKING, Any, Optional from unrealircd_rpc_py.objects.Definition import LiveRPCResult from core.classes.interfaces.imodule import IModule +import mods.jsonrpc.schemas as schemas import mods.jsonrpc.utils as utils import mods.jsonrpc.threads as thds from dataclasses import dataclass from unrealircd_rpc_py.ConnectionFactory import ConnectionFactory from unrealircd_rpc_py.LiveConnectionFactory import LiveConnectionFactory +if TYPE_CHECKING: + from core.loader import Loader + class Jsonrpc(IModule): @dataclass - class ModConfModel: + class ModConfModel(schemas.ModConfModel): """The Model containing the module parameters """ - jsonrpc: int = 0 + ... MOD_HEADER: dict[str, str] = { 'name':'JsonRPC', @@ -23,26 +28,34 @@ class Jsonrpc(IModule): 'core_version':'Defender-6' } - def callback_sent_to_irc(self, response: LiveRPCResult) -> None: + def __init__(self, context: 'Loader') -> None: + super().__init__(context) + self._mod_config: Optional[schemas.ModConfModel] = None - dnickname = self.Config.SERVICE_NICKNAME - dchanlog = self.Config.SERVICE_CHANLOG - green = self.Config.COLORS.green - nogc = self.Config.COLORS.nogc - bold = self.Config.COLORS.bold - red = self.Config.COLORS.red + @property + def mod_config(self) -> ModConfModel: + return self._mod_config + + async def callback_sent_to_irc(self, response: LiveRPCResult) -> None: + + dnickname = self.ctx.Config.SERVICE_NICKNAME + dchanlog = self.ctx.Config.SERVICE_CHANLOG + green = self.ctx.Config.COLORS.green + nogc = self.ctx.Config.COLORS.nogc + bold = self.ctx.Config.COLORS.bold + red = self.ctx.Config.COLORS.red if response.error.code != 0: - self.Protocol.send_priv_msg(nick_from=dnickname, + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=f"[{bold}{red}JSONRPC ERROR{nogc}{bold}] {response.error.message} ({response.error.code})", channel=dchanlog) return None if isinstance(response.result, bool): if response.result: - self.Protocol.send_priv_msg( - nick_from=self.Config.SERVICE_NICKNAME, - msg=f"[{bold}{green}JSONRPC{nogc}{bold}] JSONRPC Event activated on {self.Config.JSONRPC_URL}", + await self.ctx.Irc.Protocol.send_priv_msg( + nick_from=self.ctx.Config.SERVICE_NICKNAME, + msg=f"[{bold}{green}JSONRPC{nogc}{bold}] JSONRPC Event activated on {self.ctx.Config.JSONRPC_URL}", channel=dchanlog) return None @@ -53,99 +66,92 @@ class Jsonrpc(IModule): msg = response.result.msg if hasattr(response.result, 'msg') else '' build_msg = f"{green}{log_source}{nogc}: [{bold}{level}{bold}] {subsystem}.{event_id} - {msg}" - self.Protocol.send_priv_msg(nick_from=dnickname, msg=build_msg, channel=dchanlog) + await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg=build_msg, channel=dchanlog) return None def create_tables(self) -> None: return None - def load(self) -> None: + async def load(self) -> None: logging.getLogger('websockets').setLevel(logging.WARNING) logging.getLogger('unrealircd-rpc-py').setLevel(logging.CRITICAL) logging.getLogger('unrealircd-liverpc-py').setLevel(logging.CRITICAL) - self.ModConfig = self.ModConfModel(jsonrpc=0) + self._mod_config = self.ModConfModel(jsonrpc=0) - if self.Config.SERVEUR_PROTOCOL != 'unreal6': - self.Loader.ModuleUtils.unload_one_module(self.Irc, self.module_name, False) + await self.sync_db() + + if self.ctx.Config.SERVEUR_PROTOCOL.lower() != 'unreal6': + self.ctx.ModuleUtils.unload_one_module(self.module_name, False) return None # Is RPC Active? self.is_streaming = False - - # Module Utils - self.Utils = utils - - # Module threads - self.Threads = thds - - # Run Garbage collector. - self.Base.create_timer(10, self.MainUtils.run_python_garbage_collector) # Create module commands (Mandatory) - self.Irc.build_command(1, self.module_name, 'jsonrpc', 'Activate the JSON RPC Live connection [ON|OFF]') - self.Irc.build_command(1, self.module_name, 'jruser', 'Get Information about a user using JSON RPC') - self.Irc.build_command(1, self.module_name, 'jrinstances', 'Get number of instances') + self.ctx.Irc.build_command(1, self.module_name, 'jsonrpc', 'Activate the JSON RPC Live connection [ON|OFF]') + self.ctx.Irc.build_command(1, self.module_name, 'jruser', 'Get Information about a user using JSON RPC') + self.ctx.Irc.build_command(1, self.module_name, 'jrinstances', 'Get number of instances') try: - self.Rpc = ConnectionFactory(self.Config.DEBUG_LEVEL).get(self.Config.JSONRPC_METHOD) - self.LiveRpc = LiveConnectionFactory(self.Config.DEBUG_LEVEL).get(self.Config.JSONRPC_METHOD) + self.Rpc = ConnectionFactory(self.ctx.Config.DEBUG_LEVEL).get(self.ctx.Config.JSONRPC_METHOD) + self.LiveRpc = LiveConnectionFactory(self.ctx.Config.DEBUG_LEVEL).get(self.ctx.Config.JSONRPC_METHOD) - sync_unixsocket = {'path_to_socket_file': self.Config.JSONRPC_PATH_TO_SOCKET_FILE} - sync_http = {'url': self.Config.JSONRPC_URL, 'username': self.Config.JSONRPC_USER, 'password': self.Config.JSONRPC_PASSWORD} + sync_unixsocket = {'path_to_socket_file': self.ctx.Config.JSONRPC_PATH_TO_SOCKET_FILE} + sync_http = {'url': self.ctx.Config.JSONRPC_URL, 'username': self.ctx.Config.JSONRPC_USER, 'password': self.ctx.Config.JSONRPC_PASSWORD} - live_unixsocket = {'path_to_socket_file': self.Config.JSONRPC_PATH_TO_SOCKET_FILE, + live_unixsocket = {'path_to_socket_file': self.ctx.Config.JSONRPC_PATH_TO_SOCKET_FILE, 'callback_object_instance' : self, 'callback_method_or_function_name': 'callback_sent_to_irc'} - live_http = {'url': self.Config.JSONRPC_URL, 'username': self.Config.JSONRPC_USER, 'password': self.Config.JSONRPC_PASSWORD, + live_http = {'url': self.ctx.Config.JSONRPC_URL, 'username': self.ctx.Config.JSONRPC_USER, 'password': self.ctx.Config.JSONRPC_PASSWORD, 'callback_object_instance' : self, 'callback_method_or_function_name': 'callback_sent_to_irc'} - sync_param = sync_unixsocket if self.Config.JSONRPC_METHOD == 'unixsocket' else sync_http - live_param = live_unixsocket if self.Config.JSONRPC_METHOD == 'unixsocket' else live_http + sync_param = sync_unixsocket if self.ctx.Config.JSONRPC_METHOD == 'unixsocket' else sync_http + live_param = live_unixsocket if self.ctx.Config.JSONRPC_METHOD == 'unixsocket' else live_http self.Rpc.setup(sync_param) self.LiveRpc.setup(live_param) - if self.ModConfig.jsonrpc == 1: - self.Base.create_thread(func=self.Threads.thread_subscribe, func_args=(self, ), run_once=True) + if self.mod_config.jsonrpc == 1: + self.ctx.Base.create_asynctask(thds.thread_subscribe(self)) return None except Exception as err: - self.Protocol.send_priv_msg( - nick_from=self.Config.SERVICE_NICKNAME, - msg=f"[{self.Config.COLORS.red}JSONRPC ERROR{self.Config.COLORS.nogc}] {err.__str__()}", - channel=self.Config.SERVICE_CHANLOG + await self.ctx.Irc.Protocol.send_priv_msg( + nick_from=self.ctx.Config.SERVICE_NICKNAME, + msg=f"[{self.ctx.Config.COLORS.red}JSONRPC ERROR{self.ctx.Config.COLORS.nogc}] {err.__str__()}", + channel=self.ctx.Config.SERVICE_CHANLOG ) - self.Logs.error(f"JSONRPC ERROR: {err.__str__()}") + self.ctx.Logs.error(f"JSONRPC ERROR: {err.__str__()}") - def unload(self) -> None: + async def unload(self) -> None: - if self.Config.SERVEUR_PROTOCOL != 'unreal6': - self.Loader.ModuleUtils.unload_one_module(self.Irc, self.module_name, False) + if self.ctx.Config.SERVEUR_PROTOCOL != 'unreal6': + await self.ctx.ModuleUtils.unload_one_module(self.ctx.Irc, self.module_name, False) return None if self.is_streaming: - self.Protocol.send_priv_msg( - nick_from=self.Config.SERVICE_NICKNAME, - msg=f"[{self.Config.COLORS.green}JSONRPC INFO{self.Config.COLORS.nogc}] Shutting down RPC system!", - channel=self.Config.SERVICE_CHANLOG + await self.ctx.Irc.Protocol.send_priv_msg( + nick_from=self.ctx.Config.SERVICE_NICKNAME, + msg=f"[{self.ctx.Config.COLORS.green}JSONRPC INFO{self.ctx.Config.COLORS.nogc}] Shutting down RPC system!", + channel=self.ctx.Config.SERVICE_CHANLOG ) - self.Base.create_thread(func=self.Threads.thread_unsubscribe, func_args=(self, ), run_once=True) - self.update_configuration('jsonrpc', 0) - self.Irc.Commands.drop_command_by_module(self.module_name) - self.Logs.debug(f"Unloading {self.module_name}") + self.ctx.Base.create_asynctask(thds.thread_unsubscribe(self)) + # await self.update_configuration('jsonrpc', 0) + self.ctx.Commands.drop_command_by_module(self.module_name) + self.ctx.Logs.debug(f"Unloading {self.module_name}") return None - def cmd(self, data: list) -> None: + def cmd(self, data: list[str]) -> None: return None - def hcmds(self, user:str, channel: any, cmd: list, fullcmd: list = []) -> None: + async def hcmds(self, user: str, channel: Any, cmd: list[str], fullcmd: list[str] = []) -> None: command = str(cmd[0]).lower() - dnickname = self.Config.SERVICE_NICKNAME - dchannel = self.Config.SERVICE_CHANLOG + dnickname = self.ctx.Config.SERVICE_NICKNAME + dchannel = self.ctx.Config.SERVICE_CHANLOG fromuser = user fromchannel = str(channel) if not channel is None else None @@ -154,39 +160,30 @@ class Jsonrpc(IModule): case 'jsonrpc': try: if len(cmd) < 2: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'/msg {dnickname} jsonrpc on') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'/msg {dnickname} jsonrpc off') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'/msg {dnickname} jsonrpc on') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'/msg {dnickname} jsonrpc off') return None option = str(cmd[1]).lower() match option: case 'on': - thread_name = 'thread_subscribe' - if self.Base.is_thread_alive(thread_name): - self.Protocol.send_priv_msg(nick_from=dnickname, channel=dchannel, msg=f"The Subscription is running") - return None - elif self.Base.is_thread_exist(thread_name): - self.Protocol.send_priv_msg( - nick_from=dnickname, channel=dchannel, - msg=f"The subscription is not running, wait untill the process will be cleaned up" - ) - return None - - self.Base.create_thread(func=self.Threads.thread_subscribe, func_args=(self, ), run_once=True) - self.update_configuration('jsonrpc', 1) + self.ctx.Base.create_asynctask(thds.thread_subscribe(self)) + await self.update_configuration('jsonrpc', 1) case 'off': - self.Base.create_thread(func=self.Threads.thread_unsubscribe, func_args=(self, ), run_once=True) - self.update_configuration('jsonrpc', 0) + self.ctx.Base.create_asynctask(thds.thread_unsubscribe(self)) + await self.update_configuration('jsonrpc', 0) except IndexError as ie: - self.Logs.error(ie) + self.ctx.Logs.error(ie) case 'jruser': try: if len(cmd) < 2: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'/msg {dnickname} jruser get nickname') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'/msg {dnickname} jruser get nickname') + return None + option = str(cmd[1]).lower() match option: case 'get': @@ -195,42 +192,42 @@ class Jsonrpc(IModule): UserInfo = rpc.User.get(nickname) if UserInfo.error.code != 0: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'{UserInfo.error.message}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'{UserInfo.error.message}') return None - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'UID : {UserInfo.id}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'NICKNAME : {UserInfo.name}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'USERNAME : {UserInfo.user.username}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'REALNAME : {UserInfo.user.realname}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'MODES : {UserInfo.user.modes}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'CHANNELS : {[chan.name for chan in UserInfo.user.channels]}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'SECURITY GROUP : {UserInfo.user.security_groups}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'REPUTATION : {UserInfo.user.reputation}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'UID : {UserInfo.id}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'NICKNAME : {UserInfo.name}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'USERNAME : {UserInfo.user.username}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'REALNAME : {UserInfo.user.realname}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'MODES : {UserInfo.user.modes}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'CHANNELS : {[chan.name for chan in UserInfo.user.channels]}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'SECURITY GROUP : {UserInfo.user.security_groups}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'REPUTATION : {UserInfo.user.reputation}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'IP : {UserInfo.ip}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'COUNTRY CODE : {UserInfo.geoip.country_code}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'ASN : {UserInfo.geoip.asn}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'ASNAME : {UserInfo.geoip.asname}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'CLOAKED HOST : {UserInfo.user.cloakedhost}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'HOSTNAME : {UserInfo.hostname}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'VHOST : {UserInfo.user.vhost}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'CLIENT PORT : {UserInfo.client_port}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'SERVER PORT : {UserInfo.server_port}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'IP : {UserInfo.ip}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'COUNTRY CODE : {UserInfo.geoip.country_code}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'ASN : {UserInfo.geoip.asn}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'ASNAME : {UserInfo.geoip.asname}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'CLOAKED HOST : {UserInfo.user.cloakedhost}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'HOSTNAME : {UserInfo.hostname}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'VHOST : {UserInfo.user.vhost}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'CLIENT PORT : {UserInfo.client_port}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'SERVER PORT : {UserInfo.server_port}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'CERTFP : {UserInfo.tls.certfp}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'CIPHER : {UserInfo.tls.cipher}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'CERTFP : {UserInfo.tls.certfp}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'CIPHER : {UserInfo.tls.cipher}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'IDLE SINCE : {UserInfo.idle_since}') - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'CONNECTED SINCE : {UserInfo.connected_since}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'IDLE SINCE : {UserInfo.idle_since}') + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f'CONNECTED SINCE : {UserInfo.connected_since}') except IndexError as ie: - self.Logs.error(ie) + self.ctx.Logs.error(ie) case 'jrinstances': try: - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"GC Collect: {self.MainUtils.run_python_garbage_collector()}") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Nombre d'instance LiveWebsock: {self.MainUtils.get_number_gc_objects(LiveConnectionFactory)}") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Nombre d'instance ConnectionFactory: {self.MainUtils.get_number_gc_objects(ConnectionFactory)}") - self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Nombre de toute les instances: {self.MainUtils.get_number_gc_objects()}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"GC Collect: {self.ctx.Utils.run_python_garbage_collector()}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Nombre d'instance LiveWebsock: {self.ctx.Utils.get_number_gc_objects(LiveConnectionFactory)}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Nombre d'instance ConnectionFactory: {self.ctx.Utils.get_number_gc_objects(ConnectionFactory)}") + await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Nombre de toute les instances: {self.ctx.Utils.get_number_gc_objects()}") except Exception as err: - self.Logs.error(f"Unknown Error: {err}") \ No newline at end of file + self.ctx.Logs.error(f"Unknown Error: {err}") \ No newline at end of file diff --git a/mods/jsonrpc/schemas.py b/mods/jsonrpc/schemas.py new file mode 100644 index 0000000..ce969f3 --- /dev/null +++ b/mods/jsonrpc/schemas.py @@ -0,0 +1,5 @@ +from core.definition import MainModel, dataclass + +@dataclass +class ModConfModel(MainModel): + jsonrpc: int = 0 diff --git a/mods/jsonrpc/threads.py b/mods/jsonrpc/threads.py index 1585acd..c28442e 100644 --- a/mods/jsonrpc/threads.py +++ b/mods/jsonrpc/threads.py @@ -4,16 +4,23 @@ from typing import TYPE_CHECKING if TYPE_CHECKING: from mods.jsonrpc.mod_jsonrpc import Jsonrpc -def thread_subscribe(uplink: 'Jsonrpc') -> None: +async def thread_subscribe(uplink: 'Jsonrpc') -> None: + + snickname = uplink.ctx.Config.SERVICE_NICKNAME + schannel = uplink.ctx.Config.SERVICE_CHANLOG + if uplink.is_streaming: + await uplink.ctx.Irc.Protocol.send_priv_msg(nick_from=snickname, + msg=f"[{uplink.ctx.Config.COLORS.green}JSONRPC INFO{uplink.ctx.Config.COLORS.nogc}] IRCd Json-rpc already connected!", + channel=schannel + ) + return None - snickname = uplink.Config.SERVICE_NICKNAME - schannel = uplink.Config.SERVICE_CHANLOG uplink.is_streaming = True - response = asyncio.run(uplink.LiveRpc.subscribe(["all"])) + response = await uplink.LiveRpc.subscribe(["all"]) if response.error.code != 0: - uplink.Protocol.send_priv_msg(nick_from=snickname, - msg=f"[{uplink.Config.COLORS.red}JSONRPC ERROR{uplink.Config.COLORS.nogc}] {response.error.message}", + await uplink.ctx.Irc.Protocol.send_priv_msg(nick_from=snickname, + msg=f"[{uplink.ctx.Config.COLORS.red}JSONRPC ERROR{uplink.ctx.Config.COLORS.nogc}] {response.error.message}", channel=schannel ) @@ -21,33 +28,41 @@ def thread_subscribe(uplink: 'Jsonrpc') -> None: message = response.error.message if code == 0: - uplink.Protocol.send_priv_msg( + await uplink.ctx.Irc.Protocol.send_priv_msg( nick_from=snickname, - msg=f"[{uplink.Config.COLORS.green}JSONRPC{uplink.Config.COLORS.nogc}] Stream is OFF", + msg=f"[{uplink.ctx.Config.COLORS.green}JSONRPC{uplink.ctx.Config.COLORS.nogc}] Stream is OFF", channel=schannel ) + uplink.is_streaming = False else: - uplink.Protocol.send_priv_msg( + await uplink.ctx.Irc.Protocol.send_priv_msg( nick_from=snickname, - msg=f"[{uplink.Config.COLORS.red}JSONRPC{uplink.Config.COLORS.nogc}] Stream has crashed! {code} - {message}", + msg=f"[{uplink.ctx.Config.COLORS.red}JSONRPC{uplink.ctx.Config.COLORS.nogc}] Stream has crashed! {code} - {message}", channel=schannel ) + uplink.is_streaming = False -def thread_unsubscribe(uplink: 'Jsonrpc') -> None: +async def thread_unsubscribe(uplink: 'Jsonrpc') -> None: - response = asyncio.run(uplink.LiveRpc.unsubscribe()) - uplink.Logs.debug("[JSONRPC UNLOAD] Unsubscribe from the stream!") + snickname = uplink.ctx.Config.SERVICE_NICKNAME + schannel = uplink.ctx.Config.SERVICE_CHANLOG + + if not uplink.is_streaming: + await uplink.ctx.Irc.Protocol.send_priv_msg(nick_from=snickname, + msg=f"[{uplink.ctx.Config.COLORS.green}JSONRPC INFO{uplink.ctx.Config.COLORS.nogc}] IRCd Json-rpc is already off!", + channel=schannel + ) + return None + + response = await uplink.LiveRpc.unsubscribe() + uplink.ctx.Logs.debug("[JSONRPC UNLOAD] Unsubscribe from the stream!") uplink.is_streaming = False - uplink.update_configuration('jsonrpc', 0) - snickname = uplink.Config.SERVICE_NICKNAME - schannel = uplink.Config.SERVICE_CHANLOG - code = response.error.code message = response.error.message if code != 0: - uplink.Protocol.send_priv_msg( + await uplink.ctx.Irc.Protocol.send_priv_msg( nick_from=snickname, - msg=f"[{uplink.Config.COLORS.red}JSONRPC ERROR{uplink.Config.COLORS.nogc}] {message} ({code})", + msg=f"[{uplink.ctx.Config.COLORS.red}JSONRPC ERROR{uplink.ctx.Config.COLORS.nogc}] {message} ({code})", channel=schannel )