Moving votekick to use asyncio, fix when shutdown defender

This commit is contained in:
adator
2025-11-20 16:17:27 +01:00
parent fe4b68e115
commit 6af1377823
7 changed files with 165 additions and 214 deletions

View File

@@ -504,7 +504,15 @@ class Base:
await self.Loader.ModuleUtils.unload_one_module(module.module_name) await self.Loader.ModuleUtils.unload_one_module(module.module_name)
self.logs.debug(f"=======> Closing all Coroutines!") self.logs.debug(f"=======> Closing all Coroutines!")
await asyncio.gather(*self.running_asynctasks) try:
await asyncio.wait_for(asyncio.gather(*self.running_asynctasks), timeout=5)
except asyncio.exceptions.TimeoutError as te:
self.logs.debug(f"Asyncio Timeout reached! {te}")
for task in self.running_asynctasks:
task.cancel()
except asyncio.exceptions.CancelledError as cerr:
self.logs.debug(f"Asyncio CancelledError reached! {cerr}")
# Nettoyage des timers # Nettoyage des timers
self.logs.debug(f"=======> Checking for Timers to stop") self.logs.debug(f"=======> Checking for Timers to stop")
@@ -512,7 +520,7 @@ class Base:
while timer.is_alive(): while timer.is_alive():
self.logs.debug(f"> waiting for {timer.name} to close") self.logs.debug(f"> waiting for {timer.name} to close")
timer.cancel() timer.cancel()
time.sleep(0.2) await asyncio.sleep(0.2)
self.running_timers.remove(timer) self.running_timers.remove(timer)
self.logs.debug(f"> Cancelling {timer.name} {timer.native_id}") self.logs.debug(f"> Cancelling {timer.name} {timer.native_id}")

View File

@@ -1,69 +0,0 @@
from logging import Logger
from core.classes.modules.settings import global_settings
from core.classes.modules import translation, user, admin, client, channel, reputation, settings, sasl
import core.logs as logs
import core.definition as df
import core.utils as utils
import core.base as base_mod
import core.module as module_mod
import core.classes.modules.commands as commands_mod
import core.classes.modules.config as conf_mod
import core.classes.modules.rpc.rpc as rpc_mod
import core.irc as irc
import core.classes.protocols.factory as factory
class IrcContext:
def ctx_modules(self) -> None:
self.Definition: df = df
self.ConfModule: conf_mod = conf_mod
self.BaseModule: base_mod = base_mod
self.CommandModule: commands_mod = commands_mod
self.LoggingModule: logs = logs
self.RpcServerModule: rpc_mod = rpc_mod
self.Utils: utils = utils
def ctx_system(self) -> None:
self.Settings: settings.Settings = global_settings
self.Settings.global_lang = self.Config.LANG if self.Config.LANG else "EN"
self.ServiceLogging: logs.ServiceLogging = self.LoggingModule.ServiceLogging()
self.Logs: Logger = self.ServiceLogging.get_logger()
self.Config: df.MConfig = self.ConfModule.Configuration(self.Logs, self.ServiceLogging).configuration_model
self.Settings.global_logger = self.Logs
self.Translation: translation.Translation = translation.Translation(self)
self.Settings.global_translation = self.Translation.get_translation()
self.Base: base_mod.Base = self.BaseModule.Base(self)
self.User: user.User = user.User(self)
self.Settings.global_user = self.User
self.Client: client.Client = client.Client(self)
self.Admin: admin.Admin = admin.Admin(self)
self.Channel: channel.Channel = channel.Channel(self)
self.Reputation: reputation.Reputation = reputation.Reputation(self)
self.Commands: commands_mod.Command = commands_mod.Command(self)
self.ModuleUtils: module_mod.Module = module_mod.Module(self)
self.Sasl: sasl.Sasl = sasl.Sasl(self)
self.Irc: irc.Irc = irc.Irc(self)
self.PFactory: factory.ProtocolFactorty = factory.ProtocolFactorty(self.Irc)
self.RpcServer: rpc_mod.JSONRPCServer = rpc_mod.JSONRPCServer(self)
self.Base.init()
self.Logs.debug(self.Utils.tr("Loader %s success", __name__))

View File

@@ -128,6 +128,8 @@ class Irc:
# When IRCd server is down # When IRCd server is down
# asyncio.exceptions.IncompleteReadError: 0 bytes read on a total of undefined expected bytes # asyncio.exceptions.IncompleteReadError: 0 bytes read on a total of undefined expected bytes
self.ctx.Logs.critical(f"The IRCd server is no more connected! {ie}") self.ctx.Logs.critical(f"The IRCd server is no more connected! {ie}")
except asyncio.exceptions.CancelledError as cerr:
self.ctx.Logs.debug(f"Asyncio CancelledError reached! {cerr}")
############################################## ##############################################
# CONNEXION IRC # # CONNEXION IRC #
@@ -1006,9 +1008,9 @@ class Irc:
except IndexError as ie: except IndexError as ie:
self.ctx.Logs.error(f'{ie}') self.ctx.Logs.error(f'{ie}')
except ConnectionResetError as cerr: except ConnectionResetError:
if self.writer.is_closing(): if self.writer.is_closing():
self.ctx.Logs.debug(f"Defender stopped properly! {cerr}") self.ctx.Logs.debug(f"Defender stopped properly!")
case 'restart': case 'restart':
final_reason = ' '.join(cmd[1:]) final_reason = ' '.join(cmd[1:])

View File

@@ -15,7 +15,11 @@ import mods.votekick.schemas as schemas
import mods.votekick.utils as utils import mods.votekick.utils as utils
from mods.votekick.votekick_manager import VotekickManager from mods.votekick.votekick_manager import VotekickManager
import mods.votekick.threads as thds import mods.votekick.threads as thds
from typing import Any, Optional from typing import TYPE_CHECKING, Any, Optional
if TYPE_CHECKING:
from core.loader import Loader
class Votekick(IModule): class Votekick(IModule):
@@ -31,6 +35,14 @@ class Votekick(IModule):
'core_version':'Defender-6' 'core_version':'Defender-6'
} }
def __init__(self, context: 'Loader') -> None:
super().__init__(context)
self._mod_config: Optional[schemas.VoteChannelModel] = None
@property
def mod_config(self) -> ModConfModel:
return self._mod_config
def create_tables(self) -> None: def create_tables(self) -> None:
"""Methode qui va créer la base de donnée si elle n'existe pas. """Methode qui va créer la base de donnée si elle n'existe pas.
Une Session unique pour cette classe sera crée, qui sera utilisé dans cette classe / module Une Session unique pour cette classe sera crée, qui sera utilisé dans cette classe / module
@@ -53,57 +65,52 @@ class Votekick(IModule):
) )
''' '''
self.Base.db_execute_query(table_logs) self.ctx.Base.db_execute_query(table_logs)
self.Base.db_execute_query(table_vote) self.ctx.Base.db_execute_query(table_vote)
return None return None
def load(self) -> None: async def load(self) -> None:
self.ModConfig = self.ModConfModel() self._mod_config = self.ModConfModel()
await self.sync_db()
# Add VoteKick Manager # Add VoteKick Manager
self.VoteKickManager = VotekickManager(self) self.VoteKickManager = VotekickManager(self)
# Add Utils module
self.ModUtils = utils
# Add Schemas module
self.Schemas = schemas
# Add Threads module # Add Threads module
self.Threads = thds self.Threads = thds
self.ModUtils.join_saved_channels(self) await utils.join_saved_channels(self)
metadata = self.Settings.get_cache('VOTEKICK') metadata = self.ctx.Settings.get_cache('VOTEKICK')
if metadata is not None: if metadata is not None:
self.VoteKickManager.VOTE_CHANNEL_DB = metadata self.VoteKickManager.VOTE_CHANNEL_DB = metadata
# Créer les nouvelles commandes du module # Créer les nouvelles commandes du module
self.Irc.build_command(1, self.module_name, 'vote', 'The kick vote module') self.ctx.Irc.build_command(1, self.module_name, 'vote', 'The kick vote module')
def unload(self) -> None: async def unload(self) -> None:
try: try:
# Cache the local DB with current votes. # Cache the local DB with current votes.
if self.VoteKickManager.VOTE_CHANNEL_DB: if self.VoteKickManager.VOTE_CHANNEL_DB:
self.Settings.set_cache('VOTEKICK', self.VoteKickManager.VOTE_CHANNEL_DB) self.ctx.Settings.set_cache('VOTEKICK', self.VoteKickManager.VOTE_CHANNEL_DB)
for chan in self.VoteKickManager.VOTE_CHANNEL_DB: for chan in self.VoteKickManager.VOTE_CHANNEL_DB:
self.Protocol.send_part_chan(uidornickname=self.Config.SERVICE_ID, channel=chan.channel_name) await self.ctx.Irc.Protocol.send_part_chan(uidornickname=self.ctx.Config.SERVICE_ID, channel=chan.channel_name)
self.VoteKickManager.VOTE_CHANNEL_DB = [] self.VoteKickManager.VOTE_CHANNEL_DB = []
self.Logs.debug(f'Delete memory DB VOTE_CHANNEL_DB: {self.VoteKickManager.VOTE_CHANNEL_DB}') self.ctx.Logs.debug(f'Delete memory DB VOTE_CHANNEL_DB: {self.VoteKickManager.VOTE_CHANNEL_DB}')
self.Irc.Commands.drop_command_by_module(self.module_name) self.ctx.Commands.drop_command_by_module(self.module_name)
return None return None
except UnboundLocalError as ne: except UnboundLocalError as ne:
self.Logs.error(f'{ne}') self.ctx.Logs.error(f'{ne}')
except NameError as ue: except NameError as ue:
self.Logs.error(f'{ue}') self.ctx.Logs.error(f'{ue}')
except Exception as err: except Exception as err:
self.Logs.error(f'General Error: {err}') self.ctx.Logs.error(f'General Error: {err}')
def cmd(self, data: list) -> None: def cmd(self, data: list) -> None:
@@ -111,7 +118,7 @@ class Votekick(IModule):
return None return None
cmd = data.copy() if isinstance(data, list) else list(data).copy() cmd = data.copy() if isinstance(data, list) else list(data).copy()
index, command = self.Irc.Protocol.get_ircd_protocol_poisition(cmd) index, command = self.ctx.Irc.Protocol.get_ircd_protocol_poisition(cmd)
if index == -1: if index == -1:
return None return None
@@ -129,19 +136,19 @@ class Votekick(IModule):
return None return None
except KeyError as ke: except KeyError as ke:
self.Logs.error(f"Key Error: {ke}") self.ctx.Logs.error(f"Key Error: {ke}")
except IndexError as ie: except IndexError as ie:
self.Logs.error(f"{ie} / {cmd} / length {str(len(cmd))}") self.ctx.Logs.error(f"{ie} / {cmd} / length {str(len(cmd))}")
except Exception as err: except Exception as err:
self.Logs.error(f"General Error: {err}") self.ctx.Logs.error(f"General Error: {err}")
def hcmds(self, user:str, channel: Any, cmd: list, fullcmd: Optional[list] = None) -> None: async def hcmds(self, user:str, channel: Any, cmd: list, fullcmd: Optional[list] = None) -> None:
# cmd is the command starting from the user command # cmd is the command starting from the user command
# full cmd is sending the entire server response # full cmd is sending the entire server response
command = str(cmd[0]).lower() command = str(cmd[0]).lower()
fullcmd = fullcmd fullcmd = fullcmd
dnickname = self.Config.SERVICE_NICKNAME dnickname = self.ctx.Config.SERVICE_NICKNAME
fromuser = user fromuser = user
fromchannel = channel fromchannel = channel
@@ -150,14 +157,14 @@ class Votekick(IModule):
case 'vote': case 'vote':
if len(cmd) == 1: if len(cmd) == 1:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote activate #channel') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote activate #channel')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote deactivate #channel') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote deactivate #channel')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote +') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote +')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote -') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote -')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote cancel') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote cancel')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote status') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote status')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote submit nickname') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote submit nickname')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote verdict') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote verdict')
return None return None
option = str(cmd[1]).lower() option = str(cmd[1]).lower()
@@ -167,19 +174,19 @@ class Votekick(IModule):
case 'activate': case 'activate':
try: try:
# vote activate #channel # vote activate #channel
if self.Admin.get_admin(fromuser) is None: if self.ctx.Admin.get_admin(fromuser) is None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' :Your are not allowed to execute this command') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' :Your are not allowed to execute this command')
return None return None
sentchannel = str(cmd[2]).lower() if self.Channel.is_valid_channel(str(cmd[2]).lower()) else None sentchannel = str(cmd[2]).lower() if self.ctx.Channel.is_valid_channel(str(cmd[2]).lower()) else None
if sentchannel is None: if sentchannel is None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f" The correct command is {self.Config.SERVICE_PREFIX}{command} {option} #CHANNEL") await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f" The correct command is {self.ctx.Config.SERVICE_PREFIX}{command} {option} #CHANNEL")
if self.VoteKickManager.activate_new_channel(sentchannel): if self.VoteKickManager.activate_new_channel(sentchannel):
self.Channel.db_query_channel('add', self.module_name, sentchannel) await self.ctx.Channel.db_query_channel('add', self.module_name, sentchannel)
self.Protocol.send_join_chan(uidornickname=dnickname, channel=sentchannel) await self.ctx.Irc.Protocol.send_join_chan(uidornickname=dnickname, channel=sentchannel)
self.Protocol.send2socket(f":{dnickname} SAMODE {sentchannel} +o {dnickname}") await self.ctx.Irc.Protocol.send2socket(f":{dnickname} SAMODE {sentchannel} +o {dnickname}")
self.Protocol.send_priv_msg(nick_from=dnickname, await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname,
msg="You can now use !submit <nickname> to decide if he will stay or not on this channel ", msg="You can now use !submit <nickname> to decide if he will stay or not on this channel ",
channel=sentchannel channel=sentchannel
) )
@@ -187,117 +194,117 @@ class Votekick(IModule):
return None return None
except Exception as err: except Exception as err:
self.Logs.error(f'{err}') self.ctx.Logs.error(f'{err}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} {command} {option} #channel') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} {command} {option} #channel')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Exemple /msg {dnickname} {command} {option} #welcome') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Exemple /msg {dnickname} {command} {option} #welcome')
case 'deactivate': case 'deactivate':
try: try:
# vote deactivate #channel # vote deactivate #channel
if self.Admin.get_admin(fromuser) is None: if self.ctx.Admin.get_admin(fromuser) is None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f" Your are not allowed to execute this command") await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f" Your are not allowed to execute this command")
return None return None
sentchannel = str(cmd[2]).lower() if self.Channel.is_valid_channel(str(cmd[2]).lower()) else None sentchannel = str(cmd[2]).lower() if self.ctx.Channel.is_valid_channel(str(cmd[2]).lower()) else None
if sentchannel is None: if sentchannel is None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f" The correct command is {self.Config.SERVICE_PREFIX}{command} {option} #CHANNEL") await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f" The correct command is {self.ctx.Config.SERVICE_PREFIX}{command} {option} #CHANNEL")
self.Protocol.send2socket(f":{dnickname} SAMODE {sentchannel} -o {dnickname}") await self.ctx.Irc.Protocol.send2socket(f":{dnickname} SAMODE {sentchannel} -o {dnickname}")
self.Protocol.send_part_chan(uidornickname=dnickname, channel=sentchannel) await self.ctx.Irc.Protocol.send_part_chan(uidornickname=dnickname, channel=sentchannel)
if self.VoteKickManager.drop_vote_channel_model(sentchannel): if self.VoteKickManager.drop_vote_channel_model(sentchannel):
self.Channel.db_query_channel('del', self.module_name, sentchannel) await self.ctx.Channel.db_query_channel('del', self.module_name, sentchannel)
return None return None
except Exception as err: except Exception as err:
self.Logs.error(f'{err}') self.ctx.Logs.error(f'{err}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f" /msg {dnickname} {command} {option} #channel") await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f" /msg {dnickname} {command} {option} #channel")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f" Exemple /msg {dnickname} {command} {option} #welcome") await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f" Exemple /msg {dnickname} {command} {option} #welcome")
case '+': case '+':
try: try:
# vote + # vote +
channel = fromchannel channel = fromchannel
if self.VoteKickManager.action_vote(channel, fromuser, '+'): if self.VoteKickManager.action_vote(channel, fromuser, '+'):
self.Protocol.send_priv_msg(nick_from=dnickname, msg="Vote recorded, thank you",channel=channel) await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg="Vote recorded, thank you",channel=channel)
else: else:
self.Protocol.send_priv_msg(nick_from=dnickname, msg="You already submitted a vote", channel=channel) await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg="You already submitted a vote", channel=channel)
except Exception as err: except Exception as err:
self.Logs.error(f'{err}') self.ctx.Logs.error(f'{err}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} {command} {option}') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} {command} {option}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Exemple /msg {dnickname} {command} {option}') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Exemple /msg {dnickname} {command} {option}')
case '-': case '-':
try: try:
# vote - # vote -
channel = fromchannel channel = fromchannel
if self.VoteKickManager.action_vote(channel, fromuser, '-'): if self.VoteKickManager.action_vote(channel, fromuser, '-'):
self.Protocol.send_priv_msg(nick_from=dnickname, msg="Vote recorded, thank you",channel=channel) await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg="Vote recorded, thank you",channel=channel)
else: else:
self.Protocol.send_priv_msg(nick_from=dnickname, msg="You already submitted a vote", channel=channel) await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname, msg="You already submitted a vote", channel=channel)
except Exception as err: except Exception as err:
self.Logs.error(f'{err}') self.ctx.Logs.error(f'{err}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} {command} {option}') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} {command} {option}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Exemple /msg {dnickname} {command} {option}') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Exemple /msg {dnickname} {command} {option}')
case 'cancel': case 'cancel':
try: try:
# vote cancel # vote cancel
if self.Admin.get_admin(fromuser) is None: if self.ctx.Admin.get_admin(fromuser) is None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Your are not allowed to execute this command') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Your are not allowed to execute this command')
return None return None
if channel is None: if channel is None:
self.Logs.error(f"The channel is not known, defender can't cancel the vote") self.ctx.Logs.error(f"The channel is not known, defender can't cancel the vote")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' You need to specify the channel => /msg {dnickname} vote_cancel #channel') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' You need to specify the channel => /msg {dnickname} vote_cancel #channel')
for vote in self.VoteKickManager.VOTE_CHANNEL_DB: for vote in self.VoteKickManager.VOTE_CHANNEL_DB:
if vote.channel_name == channel: if vote.channel_name == channel:
if self.VoteKickManager.init_vote_system(channel): if self.VoteKickManager.init_vote_system(channel):
self.Protocol.send_priv_msg(nick_from=dnickname, await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname,
msg="Vote system re-initiated", msg="Vote system re-initiated",
channel=channel channel=channel
) )
except Exception as err: except Exception as err:
self.Logs.error(f'{err}') self.ctx.Logs.error(f'{err}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} {command} {option}') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} {command} {option}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Exemple /msg {dnickname} {command} {option}') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Exemple /msg {dnickname} {command} {option}')
case 'status': case 'status':
try: try:
# vote status # vote status
for chan in self.VoteKickManager.VOTE_CHANNEL_DB: for chan in self.VoteKickManager.VOTE_CHANNEL_DB:
if chan.channel_name == channel: if chan.channel_name == channel:
self.Protocol.send_priv_msg(nick_from=dnickname, await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname,
msg=f"Channel: {chan.channel_name} | Target: {self.User.get_nickname(chan.target_user)} | For: {chan.vote_for} | Against: {chan.vote_against} | Number of voters: {str(len(chan.voter_users))}", msg=f"Channel: {chan.channel_name} | Target: {self.ctx.User.get_nickname(chan.target_user)} | For: {chan.vote_for} | Against: {chan.vote_against} | Number of voters: {str(len(chan.voter_users))}",
channel=channel channel=channel
) )
except Exception as err: except Exception as err:
self.Logs.error(f'{err}') self.ctx.Logs.error(f'{err}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} {command} {option}') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} {command} {option}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Exemple /msg {dnickname} {command} {option}') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Exemple /msg {dnickname} {command} {option}')
case 'submit': case 'submit':
try: try:
# vote submit nickname # vote submit nickname
if self.Admin.get_admin(fromuser) is None: if self.ctx.Admin.get_admin(fromuser) is None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Your are not allowed to execute this command') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Your are not allowed to execute this command')
return None return None
nickname_submitted = cmd[2] nickname_submitted = cmd[2]
uid_submitted = self.User.get_uid(nickname_submitted) uid_submitted = self.ctx.User.get_uid(nickname_submitted)
user_submitted = self.User.get_user(nickname_submitted) user_submitted = self.ctx.User.get_user(nickname_submitted)
ongoing_user = None ongoing_user = None
# check if there is an ongoing vote # check if there is an ongoing vote
if self.VoteKickManager.is_vote_ongoing(channel): if self.VoteKickManager.is_vote_ongoing(channel):
votec = self.VoteKickManager.get_vote_channel_model(channel) votec = self.VoteKickManager.get_vote_channel_model(channel)
if votec: if votec:
ongoing_user = self.User.get_nickname(votec.target_user) ongoing_user = self.ctx.User.get_nickname(votec.target_user)
self.Protocol.send_priv_msg(nick_from=dnickname, await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname,
msg=f"There is an ongoing vote on {ongoing_user}", msg=f"There is an ongoing vote on {ongoing_user}",
channel=channel channel=channel
) )
@@ -305,24 +312,24 @@ class Votekick(IModule):
# check if the user exist # check if the user exist
if user_submitted is None: if user_submitted is None:
self.Protocol.send_priv_msg(nick_from=dnickname, await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname,
msg=f"This nickname <{nickname_submitted}> do not exist", msg=f"This nickname <{nickname_submitted}> do not exist",
channel=channel channel=channel
) )
return None return None
uid_cleaned = self.Loader.Utils.clean_uid(uid_submitted) uid_cleaned = self.ctx.Utils.clean_uid(uid_submitted)
channel_obj = self.Channel.get_channel(channel) channel_obj = self.ctx.Channel.get_channel(channel)
if channel_obj is None: if channel_obj is None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' This channel [{channel}] do not exist in the Channel Object') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' This channel [{channel}] do not exist in the Channel Object')
return None return None
clean_uids_in_channel: list = [] clean_uids_in_channel: list = []
for uid in channel_obj.uids: for uid in channel_obj.uids:
clean_uids_in_channel.append(self.Loader.Utils.clean_uid(uid)) clean_uids_in_channel.append(self.ctx.Utils.clean_uid(uid))
if not uid_cleaned in clean_uids_in_channel: if not uid_cleaned in clean_uids_in_channel:
self.Protocol.send_priv_msg(nick_from=dnickname, await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname,
msg=f"This nickname <{nickname_submitted}> is not available in this channel", msg=f"This nickname <{nickname_submitted}> is not available in this channel",
channel=channel channel=channel
) )
@@ -332,7 +339,7 @@ class Votekick(IModule):
pattern = fr'[o|B|S]' pattern = fr'[o|B|S]'
operator_user = re.findall(pattern, user_submitted.umodes) operator_user = re.findall(pattern, user_submitted.umodes)
if operator_user: if operator_user:
self.Protocol.send_priv_msg(nick_from=dnickname, await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname,
msg="You cant vote for this user ! he/she is protected", msg="You cant vote for this user ! he/she is protected",
channel=channel channel=channel
) )
@@ -340,49 +347,49 @@ class Votekick(IModule):
for chan in self.VoteKickManager.VOTE_CHANNEL_DB: for chan in self.VoteKickManager.VOTE_CHANNEL_DB:
if chan.channel_name == channel: if chan.channel_name == channel:
chan.target_user = self.User.get_uid(nickname_submitted) chan.target_user = self.ctx.User.get_uid(nickname_submitted)
self.Protocol.send_priv_msg(nick_from=dnickname, await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname,
msg=f"{nickname_submitted} has been targeted for a vote", msg=f"{nickname_submitted} has been targeted for a vote",
channel=channel channel=channel
) )
self.Base.create_timer(60, self.Threads.timer_vote_verdict, (self, channel)) self.ctx.Base.create_asynctask(thds.timer_vote_verdict(self, channel))
self.Protocol.send_priv_msg(nick_from=dnickname, await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname,
msg="This vote will end after 60 secondes", msg="This vote will end after 60 secondes",
channel=channel channel=channel
) )
except Exception as err: except Exception as err:
self.Logs.error(f'{err}') self.ctx.Logs.error(f'{err}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} {command} {option} nickname') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} {command} {option} nickname')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Exemple /msg {dnickname} {command} {option} adator') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Exemple /msg {dnickname} {command} {option} adator')
case 'verdict': case 'verdict':
try: try:
# vote verdict # vote verdict
if self.Admin.get_admin(fromuser) is None: if self.ctx.Admin.get_admin(fromuser) is None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f'Your are not allowed to execute this command') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f'Your are not allowed to execute this command')
return None return None
votec = self.VoteKickManager.get_vote_channel_model(channel) votec = self.VoteKickManager.get_vote_channel_model(channel)
if votec: if votec:
target_user = self.User.get_nickname(votec.target_user) target_user = self.ctx.User.get_nickname(votec.target_user)
if votec.vote_for >= votec.vote_against: if votec.vote_for >= votec.vote_against:
self.Protocol.send_priv_msg(nick_from=dnickname, await self.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname,
msg=f"User {self.Config.COLORS.bold}{target_user}{self.Config.COLORS.nogc} has {votec.vote_against} votes against and {votec.vote_for} votes for. For this reason, it\'ll be kicked from the channel", msg=f"User {self.ctx.Config.COLORS.bold}{target_user}{self.ctx.Config.COLORS.nogc} has {votec.vote_against} votes against and {votec.vote_for} votes for. For this reason, it\'ll be kicked from the channel",
channel=channel channel=channel
) )
self.Protocol.send2socket(f":{dnickname} KICK {channel} {target_user} Following the vote, you are not welcome in {channel}") await self.ctx.Irc.Protocol.send2socket(f":{dnickname} KICK {channel} {target_user} Following the vote, you are not welcome in {channel}")
else: else:
self.Protocol.send_priv_msg( await self.ctx.Irc.Protocol.send_priv_msg(
nick_from=dnickname, nick_from=dnickname,
msg=f"User {self.Config.COLORS.bold}{target_user}{self.Config.COLORS.nogc} has {votec.vote_against} votes against and {votec.vote_for} votes for. For this reason, it\'ll remain in the channel", msg=f"User {self.ctx.Config.COLORS.bold}{target_user}{self.ctx.Config.COLORS.nogc} has {votec.vote_against} votes against and {votec.vote_for} votes for. For this reason, it\'ll remain in the channel",
channel=channel channel=channel
) )
if self.VoteKickManager.init_vote_system(channel): if self.VoteKickManager.init_vote_system(channel):
self.Protocol.send_priv_msg( await self.ctx.Irc.Protocol.send_priv_msg(
nick_from=dnickname, nick_from=dnickname,
msg="System vote re initiated", msg="System vote re initiated",
channel=channel channel=channel
@@ -390,19 +397,19 @@ class Votekick(IModule):
return None return None
except Exception as err: except Exception as err:
self.Logs.error(f'{err}') self.ctx.Logs.error(f'{err}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} {command} {option}') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} {command} {option}')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Exemple /msg {dnickname} {command} {option}') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' Exemple /msg {dnickname} {command} {option}')
case _: case _:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote activate #channel') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote activate #channel')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote deactivate #channel') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote deactivate #channel')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote +') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote +')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote -') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote -')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote cancel') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote cancel')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote status') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote status')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote submit nickname') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote submit nickname')
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote verdict') await self.ctx.Irc.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser,msg=f' /msg {dnickname} vote verdict')
return None return None
case _: case _:

View File

@@ -1,35 +1,38 @@
import asyncio
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from mods.votekick.mod_votekick import Votekick from mods.votekick.mod_votekick import Votekick
def timer_vote_verdict(uplink: 'Votekick', channel: str) -> None: async def timer_vote_verdict(uplink: 'Votekick', channel: str) -> None:
dnickname = uplink.Config.SERVICE_NICKNAME dnickname = uplink.ctx.Config.SERVICE_NICKNAME
if not uplink.VoteKickManager.is_vote_ongoing(channel): if not uplink.VoteKickManager.is_vote_ongoing(channel):
return None return None
asyncio.sleep(60)
votec = uplink.VoteKickManager.get_vote_channel_model(channel) votec = uplink.VoteKickManager.get_vote_channel_model(channel)
if votec: if votec:
target_user = uplink.User.get_nickname(votec.target_user) target_user = uplink.ctx.User.get_nickname(votec.target_user)
if votec.vote_for >= votec.vote_against and votec.vote_for != 0: if votec.vote_for >= votec.vote_against and votec.vote_for != 0:
uplink.Protocol.send_priv_msg(nick_from=dnickname, await uplink.ctx.Irc.Protocol.send_priv_msg(nick_from=dnickname,
msg=f"User {uplink.Config.COLORS.bold}{target_user}{uplink.Config.COLORS.nogc} has {votec.vote_against} votes against and {votec.vote_for} votes for. For this reason, it\'ll be kicked from the channel", msg=f"User {uplink.ctx.Config.COLORS.bold}{target_user}{uplink.ctx.Config.COLORS.nogc} has {votec.vote_against} votes against and {votec.vote_for} votes for. For this reason, it\'ll be kicked from the channel",
channel=channel channel=channel
) )
uplink.Protocol.send2socket(f":{dnickname} KICK {channel} {target_user} Following the vote, you are not welcome in {channel}") await uplink.ctx.Irc.Protocol.send2socket(f":{dnickname} KICK {channel} {target_user} Following the vote, you are not welcome in {channel}")
else: else:
uplink.Protocol.send_priv_msg( await uplink.ctx.Irc.Protocol.send_priv_msg(
nick_from=dnickname, nick_from=dnickname,
msg=f"User {uplink.Config.COLORS.bold}{target_user}{uplink.Config.COLORS.nogc} has {votec.vote_against} votes against and {votec.vote_for} votes for. For this reason, it\'ll remain in the channel", msg=f"User {uplink.ctx.Config.COLORS.bold}{target_user}{uplink.ctx.Config.COLORS.nogc} has {votec.vote_against} votes against and {votec.vote_for} votes for. For this reason, it\'ll remain in the channel",
channel=channel channel=channel
) )
if uplink.VoteKickManager.init_vote_system(channel): if uplink.VoteKickManager.init_vote_system(channel):
uplink.Protocol.send_priv_msg( await uplink.ctx.Irc.Protocol.send_priv_msg(
nick_from=dnickname, nick_from=dnickname,
msg="System vote re initiated", msg="System vote re initiated",
channel=channel channel=channel

View File

@@ -4,7 +4,7 @@ from typing import TYPE_CHECKING
if TYPE_CHECKING: if TYPE_CHECKING:
from mods.votekick.mod_votekick import Votekick from mods.votekick.mod_votekick import Votekick
def add_vote_channel_to_database(uplink: 'Votekick', channel: str) -> bool: async def add_vote_channel_to_database(uplink: 'Votekick', channel: str) -> bool:
"""Adds a new channel to the votekick database if it doesn't already exist. """Adds a new channel to the votekick database if it doesn't already exist.
This function checks if the specified channel is already registered in the This function checks if the specified channel is already registered in the
@@ -18,16 +18,16 @@ def add_vote_channel_to_database(uplink: 'Votekick', channel: str) -> bool:
bool: True if the channel was successfully inserted into the database. bool: True if the channel was successfully inserted into the database.
False if the channel already exists or the insertion failed. False if the channel already exists or the insertion failed.
""" """
current_datetime = uplink.Utils.get_sdatetime() current_datetime = uplink.ctx.Utils.get_sdatetime()
mes_donnees = {'channel': channel} mes_donnees = {'channel': channel}
response = uplink.Base.db_execute_query("SELECT id FROM votekick_channel WHERE channel = :channel", mes_donnees) response = await uplink.ctx.Base.db_execute_query("SELECT id FROM votekick_channel WHERE channel = :channel", mes_donnees)
is_channel_exist = response.fetchone() is_channel_exist = response.fetchone()
if is_channel_exist is None: if is_channel_exist is None:
mes_donnees = {'datetime': current_datetime, 'channel': channel} mes_donnees = {'datetime': current_datetime, 'channel': channel}
insert = uplink.Base.db_execute_query(f"INSERT INTO votekick_channel (datetime, channel) VALUES (:datetime, :channel)", mes_donnees) insert = await uplink.ctx.Base.db_execute_query(f"INSERT INTO votekick_channel (datetime, channel) VALUES (:datetime, :channel)", mes_donnees)
if insert.rowcount > 0: if insert.rowcount > 0:
return True return True
else: else:
@@ -35,7 +35,7 @@ def add_vote_channel_to_database(uplink: 'Votekick', channel: str) -> bool:
else: else:
return False return False
def delete_vote_channel_from_database(uplink: 'Votekick', channel: str) -> bool: async def delete_vote_channel_from_database(uplink: 'Votekick', channel: str) -> bool:
"""Deletes a channel entry from the votekick database. """Deletes a channel entry from the votekick database.
This function removes the specified channel from the `votekick_channel` table This function removes the specified channel from the `votekick_channel` table
@@ -49,7 +49,7 @@ def delete_vote_channel_from_database(uplink: 'Votekick', channel: str) -> bool:
bool: True if the channel was successfully deleted, False if no rows were affected. bool: True if the channel was successfully deleted, False if no rows were affected.
""" """
mes_donnes = {'channel': channel} mes_donnes = {'channel': channel}
response = uplink.Base.db_execute_query("DELETE FROM votekick_channel WHERE channel = :channel", mes_donnes) response = await uplink.ctx.Base.db_execute_query("DELETE FROM votekick_channel WHERE channel = :channel", mes_donnes)
affected_row = response.rowcount affected_row = response.rowcount
@@ -61,14 +61,14 @@ def delete_vote_channel_from_database(uplink: 'Votekick', channel: str) -> bool:
async def join_saved_channels(uplink: 'Votekick') -> None: async def join_saved_channels(uplink: 'Votekick') -> None:
param = {'module_name': uplink.module_name} param = {'module_name': uplink.module_name}
result = uplink.Base.db_execute_query(f"SELECT id, channel_name FROM {uplink.Config.TABLE_CHANNEL} WHERE module_name = :module_name", param) result = await uplink.ctx.Base.db_execute_query(f"SELECT id, channel_name FROM {uplink.ctx.Config.TABLE_CHANNEL} WHERE module_name = :module_name", param)
channels = result.fetchall() channels = result.fetchall()
for channel in channels: for channel in channels:
id_, chan = channel id_, chan = channel
uplink.VoteKickManager.activate_new_channel(chan) uplink.VoteKickManager.activate_new_channel(chan)
await uplink.Protocol.send_sjoin(channel=chan) await uplink.ctx.Irc.Protocol.send_sjoin(channel=chan)
await uplink.Protocol.send2socket(f":{uplink.Config.SERVICE_NICKNAME} SAMODE {chan} +o {uplink.Config.SERVICE_NICKNAME}") await uplink.ctx.Irc.Protocol.send2socket(f":{uplink.ctx.Config.SERVICE_NICKNAME} SAMODE {chan} +o {uplink.ctx.Config.SERVICE_NICKNAME}")
return None return None

View File

@@ -10,8 +10,8 @@ class VotekickManager:
def __init__(self, uplink: 'Votekick'): def __init__(self, uplink: 'Votekick'):
self.uplink = uplink self.uplink = uplink
self.Logs = uplink.Logs self.Logs = uplink.ctx.Logs
self.Utils = uplink.MainUtils self.Utils = uplink.ctx.Utils
def activate_new_channel(self, channel_name: str) -> bool: def activate_new_channel(self, channel_name: str) -> bool:
"""Activate a new channel in the votekick systeme """Activate a new channel in the votekick systeme