59 Commits

Author SHA1 Message Date
adator
be36c56ceb Merge pull request #73 from adator85/update/protocol
Update/protocol
2025-07-20 19:44:49 +02:00
adator
ac332e6802 Update version number 2025-07-20 19:42:59 +02:00
adator
6063ceba35 Update Protocol Connection 2025-07-20 19:41:10 +02:00
adator
2204c4fdf8 Merge pull request #72 from adator85/V6.X.X
V6.1.1 Updates
2024-12-08 23:03:01 +01:00
adator
b98a20ad45 Merge pull request #71 from adator85/V6.X.X
V6.1.0 update the help command
2024-12-08 12:56:18 +01:00
adator
dc63df08cf Merge pull request #70 from adator85/V6.X.X
Update on_version method
2024-11-22 23:27:15 +01:00
adator
a3a61c332f Merge pull request #69 from adator85/V6.X.X
V6.0.4
2024-11-18 23:50:25 +01:00
adator
eeaacddbf2 Merge pull request #68 from adator85/V6.X.X
Update to version 6.0.3
2024-11-17 21:09:51 +01:00
adator
39412fc1c0 Merge pull request #67 from adator85/V6.X.X
V6.0.2
2024-11-15 22:14:55 +01:00
adator
e148659d00 Merge pull request #66 from adator85/V6.X.X
V6.0.1
2024-11-11 23:38:26 +01:00
adator
71a7d29b08 Merge pull request #65 from adator85/V6.X.X
Update the version 6
2024-11-11 15:39:20 +01:00
adator
71170baf1a Merge pull request #64 from adator85/V6.X.X
Fix clone reply
2024-11-07 23:43:02 +01:00
adator
1b20435b83 Merge pull request #63 from adator85/V6.X.X
fix main file name
2024-11-07 23:11:26 +01:00
adator
008dacfde6 Merge pull request #62 from adator85/V6.X.X
Disable console
2024-11-07 23:03:47 +01:00
adator
5347c45579 Merge pull request #61 from adator85/V6.X.X
V6.0.0
2024-11-07 22:50:18 +01:00
adator
63130fbc06 Merge pull request #60 from adator85/V6.X.X
V6.0.0
2024-11-07 22:46:20 +01:00
adator
b27b503d78 Merge pull request #59 from adator85/V5.X.X
V5.3.9
2024-10-13 22:22:00 +02:00
adator
36e3835e6c Merge pull request #58 from adator85/V5.X.X
update websocket connection
2024-10-06 21:58:24 +02:00
adator
2c78025bfb Merge pull request #57 from adator85/V5.X.X
V5.3.8
2024-10-06 21:49:13 +02:00
adator
979ba40c05 Merge pull request #56 from adator85/V5.X.X
V5.x.x
2024-10-04 01:10:33 +02:00
adator
cea69c1580 Merge pull request #54 from adator85/dev
V5.3.6
2024-10-02 23:40:38 +02:00
adator
c404cc3234 Merge pull request #53 from adator85/dev
Dev
2024-10-02 00:06:54 +02:00
adator
80b329dd5d Merge pull request #52 from adator85/dev
You need to have unrealirc_rpc_py v1.0.3
2024-09-30 01:40:36 +02:00
adator
f7b49c151f Merge pull request #51 from adator85/dev
V5.3.4
2024-09-29 22:43:28 +02:00
adator
1ee9b7e3ff Merge pull request #50 from adator85/dev
Dev
2024-09-26 01:00:39 +02:00
adator
4d0087623c Merge pull request #49 from adator85/dev
unsubscribe before unload
2024-09-22 23:54:22 +02:00
adator
dc20f5ec3c Merge pull request #48 from adator85/dev
Dev
2024-09-22 23:20:37 +02:00
adator
110cae3b84 Merge pull request #47 from adator85/dev
Update the way to clean exceptions and bans
2024-09-22 16:45:54 +02:00
adator
857cbfc85d Merge pull request #46 from adator85/dev
Send the ready msg to channel log
2024-09-22 16:33:49 +02:00
adator
3518589e9c Merge pull request #45 from adator85/dev
Fix ConfModel error
2024-09-22 16:31:35 +02:00
adator
e14c97de03 Merge pull request #44 from adator85/dev
V5.3.0
2024-09-22 16:20:45 +02:00
adator
69360be3ad Merge pull request #43 from adator85/dev
Update info command
2024-09-21 20:28:29 +02:00
adator
bfa90c6bd5 Merge pull request #42 from adator85/dev
V5.2.9
2024-09-21 20:22:42 +02:00
adator
5c8378a0e7 Merge pull request #41 from adator85/dev
V5.2.9
2024-09-21 16:43:14 +02:00
adator
e3b212ea88 Merge pull request #40 from adator85/dev
finetune clone connection
2024-09-20 23:13:33 +02:00
adator
0c2a350d38 Merge pull request #39 from adator85/dev
Dev
2024-09-20 21:12:59 +02:00
adator
1cea8d0601 Merge pull request #38 from adator85/dev
V5.2.1
2024-09-15 03:09:22 +02:00
adator
652b400d5e Merge pull request #37 from adator85/dev
update mode clone
2024-09-15 02:50:27 +02:00
adator
2f8b965b59 Merge pull request #36 from adator85/dev
Dev
2024-09-15 02:04:32 +02:00
adator
3c043cefd8 Merge pull request #35 from adator85/dev
V5.1.8
2024-09-08 00:42:57 +02:00
adator
59a75cecd8 Merge pull request #34 from adator85/dev
V5.1.7
2024-09-03 00:21:32 +02:00
adator
71053437a7 Merge pull request #33 from adator85/dev
V5.1.6
2024-09-01 22:15:54 +02:00
adator
7796d05206 Merge pull request #32 from adator85/dev
Update vote kick commands
2024-09-01 18:55:57 +02:00
adator
5f2567f9e5 Merge pull request #31 from adator85/dev
mod_command update
2024-09-01 17:30:05 +02:00
adator
aaa1dd9a1a Merge pull request #30 from adator85/dev
adding Say command for clones
2024-09-01 16:40:25 +02:00
adator
a02f2f9a26 Merge pull request #29 from adator85/dev
update mod_clone module
2024-09-01 15:54:50 +02:00
adator
d73adb6f0b Merge pull request #28 from adator85/dev
update readme
2024-09-01 15:35:59 +02:00
adator
b812e64992 Merge pull request #27 from adator85/dev
Dev
2024-09-01 15:24:18 +02:00
adator
9bd1f68df2 Merge pull request #26 from adator85/dev
Dev
2024-09-01 14:59:38 +02:00
adator
f44b08bf36 Merge pull request #25 from adator85/dev
fix Installation
2024-08-29 01:36:38 +02:00
adator
1a19e1613a Merge pull request #24 from adator85/dev
Fix Bug installation
2024-08-29 01:31:19 +02:00
adator
cdc15b7b47 Merge pull request #23 from adator85/dev
Dev
2024-08-29 01:16:55 +02:00
adator
31fe9f62ec Merge pull request #22 from adator85/dev
Dev
2024-08-24 01:39:11 +02:00
adator
f0853e3afb Merge pull request #21 from adator85/dev
New Installation file created for unix system
2024-08-22 01:02:00 +02:00
adator
6dade09257 Merge pull request #20 from adator85/dev
README Update
2024-08-21 00:50:31 +02:00
adator
9533b010b2 Merge pull request #19 from adator85/dev
V5.0.4 - Delete a user when a user has been kicked
2024-08-20 02:24:37 +02:00
adator
824db73590 Merge pull request #18 from adator85/dev
Delete channel mode information
2024-08-20 02:14:31 +02:00
adator
96bf4b6f80 Merge pull request #17 from adator85/dev
Fix channel update
2024-08-20 02:08:09 +02:00
adator
922336363e Merge pull request #16 from adator85/dev
Dev
2024-08-20 01:56:04 +02:00
16 changed files with 191 additions and 758 deletions

View File

@@ -37,9 +37,6 @@ class Admin:
result = False result = False
if not self.is_exist(uid):
return result
for record in self.UID_ADMIN_DB: for record in self.UID_ADMIN_DB:
if record.uid == uid: if record.uid == uid:
# If the admin exist, update and do not go further # If the admin exist, update and do not go further
@@ -49,7 +46,7 @@ class Admin:
return result return result
if not result: if not result:
self.Logs.critical(f'Admin: The new nickname {newNickname} was not updated, uid = {uid}') self.Logs.critical(f'The new nickname {newNickname} was not updated, uid = {uid}')
return result return result
@@ -127,18 +124,4 @@ class Admin:
if record.uid == uidornickname: if record.uid == uidornickname:
nickname = record.nickname nickname = record.nickname
self.Logs.debug(f'The value {uidornickname} -- {nickname}') self.Logs.debug(f'The value {uidornickname} -- {nickname}')
return nickname return nickname
def is_exist(self, uidornickname: str) -> bool:
"""Check if this uid or nickname is logged in as an admin
Args:
uidornickname (str): The UID or the Nickname
Returns:
bool: True if the Nickname or UID is an admin
"""
if self.get_Admin(uidornickname) is None:
return False
else:
return True

View File

@@ -90,7 +90,6 @@ class Channel:
if self.Base.clean_uid(userid) == self.Base.clean_uid(uid): if self.Base.clean_uid(userid) == self.Base.clean_uid(uid):
chanObj.uids.remove(userid) chanObj.uids.remove(userid)
result = True result = True
self.Logs.debug(f"The UID: {userid} has been removed from the {channel_name}")
self.clean_channel() self.clean_channel()

View File

@@ -219,7 +219,7 @@ class Client:
account_to_check_result = account_to_check_query.fetchone() account_to_check_result = account_to_check_query.fetchone()
if account_to_check_result: if account_to_check_result:
self.Logs.debug(f"Account ({account}) already exist") self.Logs.error(f"Account ({account}) already exist")
return True return True
return False return False

View File

@@ -10,6 +10,7 @@ class Unrealircd6:
def __init__(self, ircInstance: 'Irc'): def __init__(self, ircInstance: 'Irc'):
self.name = 'UnrealIRCD-6' self.name = 'UnrealIRCD-6'
self.protocol_version = 6100
self.__Irc = ircInstance self.__Irc = ircInstance
self.__Config = ircInstance.Config self.__Config = ircInstance.Config
@@ -158,6 +159,7 @@ class Unrealircd6:
umodes = self.__Config.SERVICE_UMODES umodes = self.__Config.SERVICE_UMODES
host = self.__Config.SERVICE_HOST host = self.__Config.SERVICE_HOST
service_name = self.__Config.SERVICE_NAME service_name = self.__Config.SERVICE_NAME
protocolversion = self.protocol_version
password = self.__Config.SERVEUR_PASSWORD password = self.__Config.SERVEUR_PASSWORD
link = self.__Config.SERVEUR_LINK link = self.__Config.SERVEUR_LINK
@@ -169,16 +171,15 @@ class Unrealircd6:
self.send2socket(f":{server_id} PASS :{password}", print_log=False) self.send2socket(f":{server_id} PASS :{password}", print_log=False)
self.send2socket(f":{server_id} PROTOCTL SID NOQUIT NICKv2 SJOIN SJ3 NICKIP TKLEXT2 NEXTBANS CLK EXTSWHOIS MLOCK MTAGS") self.send2socket(f":{server_id} PROTOCTL SID NOQUIT NICKv2 SJOIN SJ3 NICKIP TKLEXT2 NEXTBANS CLK EXTSWHOIS MLOCK MTAGS")
# self.__Irc.send2socket(f":{sid} PROTOCTL NICKv2 VHP UMODE2 NICKIP SJOIN SJOIN2 SJ3 NOQUIT TKLEXT MLOCK SID MTAGS") self.send2socket(f":{server_id} PROTOCTL EAUTH={link},{protocolversion},,{service_name}-v{version}")
self.send2socket(f":{server_id} PROTOCTL EAUTH={link},,,{service_name}-v{version}")
self.send2socket(f":{server_id} PROTOCTL SID={server_id}") self.send2socket(f":{server_id} PROTOCTL SID={server_id}")
self.send2socket(f":{server_id} PROTOCTL BOOTED={unixtime}")
self.send2socket(f":{server_id} SERVER {link} 1 :{info}") self.send2socket(f":{server_id} SERVER {link} 1 :{info}")
self.send2socket(f":{server_id} {nickname} :Reserved for services") self.send2socket(f":{server_id} {nickname} :Reserved for services")
self.send2socket(f":{server_id} UID {nickname} 1 {unixtime} {username} {host} {service_id} * {smodes} * * fwAAAQ== :{realname}") self.send2socket(f":{server_id} UID {nickname} 1 {unixtime} {username} {host} {service_id} * {smodes} * * fwAAAQ== :{realname}")
self.sjoin(chan) self.sjoin(chan)
self.send2socket(f":{server_id} TKL + Q * {nickname} {host} 0 {unixtime} :Reserved for services") self.send2socket(f":{server_id} TKL + Q * {nickname} {host} 0 {unixtime} :Reserved for services")
self.send2socket(f":{service_id} MODE {chan} {cmodes}") self.send2socket(f":{service_id} MODE {chan} {cmodes}")
# self.send2socket(f":{service_id} MODE {chan} {umodes} {service_id}")
self.__Base.logs.debug(f'>> {__name__} Link information sent to the server') self.__Base.logs.debug(f'>> {__name__} Link information sent to the server')
@@ -245,33 +246,6 @@ class Unrealircd6:
self.__Irc.Channel.insert(self.__Irc.Loader.Definition.MChannel(name=channel, uids=[self.__Config.SERVICE_ID])) self.__Irc.Channel.insert(self.__Irc.Loader.Definition.MChannel(name=channel, uids=[self.__Config.SERVICE_ID]))
return None return None
def send_svs_nick(self, oldnickname: str, newnickname: str) -> None:
unixtime = self.__Base.get_unixtime()
self.send2socket(f':{self.__Config.SERVEUR_ID} SVSNICK {oldnickname} {newnickname} {unixtime}')
user_obj = self.__Irc.User.get_User(oldnickname)
self.__Irc.User.update_nickname(user_obj.uid, newnickname)
return None
def send_sjoin(self, uid_to_join: str, channel: str) -> None:
"""UID will join a channel with pre defined umodes
Args:
channel (str): Channel to join
"""
if not self.__Irc.Channel.Is_Channel(channel):
self.__Base.logs.error(f"The channel [{channel}] is not valid")
return None
self.send2socket(f":{self.__Config.SERVEUR_ID} SJOIN {self.__Base.get_unixtime()} {channel} {self.__Config.SERVICE_UMODES} :{uid_to_join}")
self.send2socket(f":{self.__Config.SERVICE_ID} MODE {channel} {self.__Config.SERVICE_UMODES} {uid_to_join}")
# Add defender to the channel uids list
self.__Irc.Channel.insert(self.__Irc.Loader.Definition.MChannel(name=channel, uids=[uid_to_join]))
return None
def send_sapart(self, nick_to_sapart: str, channel_name: str) -> None: def send_sapart(self, nick_to_sapart: str, channel_name: str) -> None:
"""_summary_ """_summary_
@@ -353,26 +327,7 @@ class Unrealircd6:
except Exception as err: except Exception as err:
self.__Base.logs.error(f"{__name__} - General Error: {err}") self.__Base.logs.error(f"{__name__} - General Error: {err}")
def send_svs2mode(self, service_uid: str, nickname: str, user_mode: str) -> None: def send_quit(self, uid: str, reason: str, print_log: True) -> None:
try:
user_obj = self.__Irc.User.get_User(uidornickname=nickname)
service_uid = service_uid
if user_obj is None:
# User not exist: leave
return None
self.send2socket(f':{service_uid} SVS2MODE {nickname} {user_mode}')
# Update new mode
self.__Irc.User.update_mode(user_obj.uid, user_mode)
return None
except Exception as err:
self.__Base.logs.error(f"{__name__} - General Error: {err}")
def send_quit(self, uid: str, reason: str, print_log: bool = True) -> None:
"""Send quit message """Send quit message
- Delete uid from User object - Delete uid from User object
- Delete uid from Clone object - Delete uid from Clone object
@@ -515,22 +470,6 @@ class Unrealircd6:
self.send2socket(f":{self.__Config.SERVICE_NICKNAME} MODE {channel_name} {channel_mode}") self.send2socket(f":{self.__Config.SERVICE_NICKNAME} MODE {channel_name} {channel_mode}")
return None return None
def send_topic_chan(self, channel_name: str, topic_msg: str) -> None:
"""Set a channel topic
Args:
channel_name (str): Channel name starting with #
topic_msg (str): The message of the topic
"""
if self.__Irc.Channel.Is_Channel(channel_name) is None:
self.__Base.logs.error(f"The channel {channel_name} is not valid")
return None
self.send2socket(f":{self.__Config.SERVICE_NICKNAME} TOPIC {channel_name} :{topic_msg}")
return None
def send_raw(self, raw_command: str) -> None: def send_raw(self, raw_command: str) -> None:
self.send2socket(f":{self.__Config.SERVICE_NICKNAME} {raw_command}") self.send2socket(f":{self.__Config.SERVICE_NICKNAME} {raw_command}")
@@ -777,7 +716,7 @@ class Unrealircd6:
# ['@unrealircd.org/geoip=FR;unrealircd.org/userhost=50d6492c@80.214.73.44;unrealircd.org/userip=50d6492c@80.214.73.44;msgid=YSIPB9q4PcRu0EVfC9ci7y-/mZT0+Gj5FLiDSZshH5NCw;time=2024-08-15T15:35:53.772Z', # ['@unrealircd.org/geoip=FR;unrealircd.org/userhost=50d6492c@80.214.73.44;unrealircd.org/userip=50d6492c@80.214.73.44;msgid=YSIPB9q4PcRu0EVfC9ci7y-/mZT0+Gj5FLiDSZshH5NCw;time=2024-08-15T15:35:53.772Z',
# ':001EPFBRD', 'PART', '#welcome', ':WEB', 'IRC', 'Paris'] # ':001EPFBRD', 'PART', '#welcome', ':WEB', 'IRC', 'Paris']
uid = str(serverMsg[1]).replace(':', '') uid = str(serverMsg[1]).lstrip(':')
channel = str(serverMsg[3]).lower() channel = str(serverMsg[3]).lower()
self.__Irc.Channel.delete_user_from_channel(channel, uid) self.__Irc.Channel.delete_user_from_channel(channel, uid)
@@ -901,23 +840,29 @@ class Unrealircd6:
isWebirc = True if 'webirc' in serverMsg[0] else False isWebirc = True if 'webirc' in serverMsg[0] else False
isWebsocket = True if 'websocket' in serverMsg[0] else False isWebsocket = True if 'websocket' in serverMsg[0] else False
uid = str(serverMsg[8])
nickname = str(serverMsg[3]) nickname = str(serverMsg[3])
hopcount = str(serverMsg[4])
timestamp = str(serverMsg[5])
username = str(serverMsg[6]) username = str(serverMsg[6])
hostname = str(serverMsg[7]) hostname = str(serverMsg[7])
uid = str(serverMsg[8])
servicestamp = str(serverMsg[9])
umodes = str(serverMsg[10]) umodes = str(serverMsg[10])
vhost = str(serverMsg[11]) vhost = str(serverMsg[11])
cloacked_host = str(serverMsg[12])
remote_ip = self.__Base.decode_ip(str(serverMsg[13])) if 'S' in umodes else '127.0.0.1' if not 'S' in umodes:
remote_ip = self.__Base.decode_ip(str(serverMsg[13]))
else:
remote_ip = '127.0.0.1'
# extract realname
realname = ' '.join(serverMsg[14:]).lstrip(':') realname = ' '.join(serverMsg[14:]).lstrip(':')
# Extract Geoip information # Extract Geoip information
pattern = r'^.*geoip=cc=(\S{2}).*$' pattern = r'^.*geoip=cc=(\S{2}).*$'
geoip_match = match(pattern, serverMsg[0]) geoip_match = match(pattern, serverMsg[0])
geoip = geoip_match.group(1) if geoip_match else None
if geoip_match:
geoip = geoip_match.group(1)
else:
geoip = None
score_connexion = self.__Irc.first_score score_connexion = self.__Irc.first_score
@@ -930,10 +875,6 @@ class Unrealircd6:
hostname=hostname, hostname=hostname,
umodes=umodes, umodes=umodes,
vhost=vhost, vhost=vhost,
hopcount=hopcount,
timestamp=timestamp,
servicestamp=servicestamp,
cloacked_host=cloacked_host,
isWebirc=isWebirc, isWebirc=isWebirc,
isWebsocket=isWebsocket, isWebsocket=isWebsocket,
remote_ip=remote_ip, remote_ip=remote_ip,
@@ -1000,7 +941,7 @@ class Unrealircd6:
fromchannel = str(cmd[2]).lower() if self.__Irc.Channel.Is_Channel(cmd[2]) else None fromchannel = str(cmd[2]).lower() if self.__Irc.Channel.Is_Channel(cmd[2]) else None
self.__Irc.hcmds(user_trigger, fromchannel, arg, cmd) self.__Irc.hcmds(user_trigger, fromchannel, arg, cmd)
if cmd[2] == self.__Config.SERVICE_ID or cmd[2] == self.__Settings.NICKSERV_UID: if cmd[2] == self.__Config.SERVICE_ID:
pattern = fr'^:.*?:(.*)$' pattern = fr'^:.*?:(.*)$'
hcmds = search(pattern, ' '.join(cmd)) hcmds = search(pattern, ' '.join(cmd))

View File

@@ -13,5 +13,3 @@ class Settings:
PROTOCTL_USER_MODES: list[str] = [] PROTOCTL_USER_MODES: list[str] = []
PROTOCTL_PREFIX: list[str] = [] PROTOCTL_PREFIX: list[str] = []
NICKSERV_UID: str = None

View File

@@ -6,18 +6,14 @@ from os import sep
@dataclass @dataclass
class MClient: class MClient:
"""Model Client for registred nickname""" """Model Client for registred nickname"""
account: str = None
uid: str = None uid: str = None
account: str = None
nickname: str = None nickname: str = None
username: str = None username: str = None
realname: str = None realname: str = None
hostname: str = None hostname: str = None
umodes: str = None umodes: str = None
vhost: str = None vhost: str = None
hopcount: str = None
timestamp: str = None
servicestamp: str = None
cloacked_host: str = None
isWebirc: bool = False isWebirc: bool = False
isWebsocket: bool = False isWebsocket: bool = False
remote_ip: str = None remote_ip: str = None
@@ -36,10 +32,6 @@ class MUser:
hostname: str = None hostname: str = None
umodes: str = None umodes: str = None
vhost: str = None vhost: str = None
hopcount: str = None
timestamp: str = None
servicestamp: str = None
cloacked_host: str = None
isWebirc: bool = False isWebirc: bool = False
isWebsocket: bool = False isWebsocket: bool = False
remote_ip: str = None remote_ip: str = None
@@ -58,10 +50,6 @@ class MAdmin:
hostname: str = None hostname: str = None
umodes: str = None umodes: str = None
vhost: str = None vhost: str = None
hopcount: str = None
timestamp: str = None
servicestamp: str = None
cloacked_host: str = None
isWebirc: bool = False isWebirc: bool = False
isWebsocket: bool = False isWebsocket: bool = False
remote_ip: str = None remote_ip: str = None

View File

@@ -97,7 +97,7 @@ class Irc:
self.build_command(0, 'core', 'uptime', 'Give you since when the service is connected') self.build_command(0, 'core', 'uptime', 'Give you since when the service is connected')
self.build_command(0, 'core', 'firstauth', 'First authentication of the Service') self.build_command(0, 'core', 'firstauth', 'First authentication of the Service')
self.build_command(0, 'core', 'register', f'Register your nickname /msg {self.Config.SERVICE_NICKNAME} REGISTER <password> <email>') self.build_command(0, 'core', 'register', f'Register your nickname /msg {self.Config.SERVICE_NICKNAME} REGISTER <password> <email>')
# self.build_command(0, 'core', 'identify', f'Identify yourself with your password /msg {self.Config.SERVICE_NICKNAME} IDENTIFY <account> <password>') self.build_command(0, 'core', 'identify', f'Identify yourself with your password /msg {self.Config.SERVICE_NICKNAME} IDENTIFY <account> <password>')
self.build_command(0, 'core', 'logout', 'Reverse the effect of the identify command') self.build_command(0, 'core', 'logout', 'Reverse the effect of the identify command')
self.build_command(1, 'core', 'load', 'Load an existing module') self.build_command(1, 'core', 'load', 'Load an existing module')
self.build_command(1, 'core', 'unload', 'Unload a module') self.build_command(1, 'core', 'unload', 'Unload a module')
@@ -321,7 +321,7 @@ class Irc:
except AssertionError as ae: except AssertionError as ae:
self.Logs.error(f"Assertion error : {ae}") self.Logs.error(f"Assertion error : {ae}")
def unload(self, reloading: bool = False) -> None: def unload(self) -> None:
# This is only to reference the method # This is only to reference the method
return None return None
@@ -616,7 +616,7 @@ class Irc:
if 'mods.' + module_name in sys.modules: if 'mods.' + module_name in sys.modules:
self.Logs.info('Unload the module ...') self.Logs.info('Unload the module ...')
self.loaded_classes[class_name].unload(reloading=True) self.loaded_classes[class_name].unload()
self.Logs.info('Module Already Loaded ... reloading the module ...') self.Logs.info('Module Already Loaded ... reloading the module ...')
the_module = sys.modules['mods.' + module_name] the_module = sys.modules['mods.' + module_name]
importlib.reload(the_module) importlib.reload(the_module)
@@ -854,7 +854,7 @@ class Irc:
self.Logs.debug(f"** handle {parsed_protocol}") self.Logs.debug(f"** handle {parsed_protocol}")
case 'PART': case 'PART':
self.Protocol.on_part(serverMsg=original_response) self.Protocol.on_part(serverMsg=parsed_protocol)
self.Logs.debug(f"** handle {parsed_protocol}") self.Logs.debug(f"** handle {parsed_protocol}")
case 'VERSION': case 'VERSION':
@@ -1233,6 +1233,154 @@ class Irc:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Impossible de supprimer l'utilisateur.") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Impossible de supprimer l'utilisateur.")
self.Logs.warning(f":{dnickname} NOTICE {fromuser} : Impossible de supprimer l'utilisateur.") self.Logs.warning(f":{dnickname} NOTICE {fromuser} : Impossible de supprimer l'utilisateur.")
case 'register':
# Register PASSWORD EMAIL
try:
if len(cmd) < 3:
self.Protocol.send_notice(
nick_from=dnickname,
nick_to=fromuser,
msg=f'/msg {self.Config.SERVICE_NICKNAME} {command.upper()} <PASSWORD> <EMAIL>'
)
return None
password = cmd[1]
email = cmd[2]
if not self.Base.is_valid_email(email_to_control=email):
self.Protocol.send_notice(
nick_from=dnickname,
nick_to=fromuser,
msg='The email is not valid. You must provide a valid email address (first.name@email.extension)'
)
return None
user_obj = self.User.get_User(fromuser)
if user_obj is None:
self.Logs.error(f"Nickname ({fromuser}) doesn't exist, it is impossible to register this nickname")
return None
# If the account already exist.
if self.Client.db_is_account_exist(fromuser):
self.Protocol.send_notice(
nick_from=dnickname,
nick_to=fromuser,
msg=f"Your account already exist, please try to login instead /msg {self.Config.SERVICE_NICKNAME} IDENTIFY <account> <password>"
)
return None
# If the account doesn't exist then insert into database
data_to_record = {
'createdOn': self.Base.get_datetime(), 'account': fromuser,
'nickname': user_obj.nickname, 'hostname': user_obj.hostname, 'vhost': user_obj.vhost, 'realname': user_obj.realname, 'email': email,
'password': self.Base.crypt_password(password=password), 'level': 0
}
insert_to_db = self.Base.db_execute_query(f"""
INSERT INTO {self.Config.TABLE_CLIENT}
(createdOn, account, nickname, hostname, vhost, realname, email, password, level)
VALUES
(:createdOn, :account, :nickname, :hostname, :vhost, :realname, :email, :password, :level)
""", data_to_record)
if insert_to_db.rowcount > 0:
self.Protocol.send_notice(
nick_from=dnickname,
nick_to=fromuser,
msg=f"You have register your nickname successfully"
)
return None
except ValueError as ve:
self.Logs.error(f"Value Error : {ve}")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" {self.Config.SERVICE_PREFIX}{command.upper()} <PASSWORD> <EMAIL>")
case 'identify':
# Identify ACCOUNT PASSWORD
try:
if len(cmd) < 3:
self.Protocol.send_notice(
nick_from=dnickname,
nick_to=fromuser,
msg=f'/msg {self.Config.SERVICE_NICKNAME} {command.upper()} <ACCOUNT> <PASSWORD>'
)
return None
account = str(cmd[1]) # account
encrypted_password = self.Base.crypt_password(cmd[2])
user_obj = self.User.get_User(fromuser)
client_obj = self.Client.get_Client(user_obj.uid)
if client_obj is not None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You are already logged in")
return None
db_query = f"SELECT account FROM {self.Config.TABLE_CLIENT} WHERE account = :account AND password = :password"
db_param = {'account': account, 'password': encrypted_password}
exec_query = self.Base.db_execute_query(
db_query,
db_param
)
result_query = exec_query.fetchone()
if result_query:
account = result_query[0]
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You are now logged in")
client = self.Loader.Definition.MClient(
uid=user_obj.uid, account=account, nickname=fromuser,
username=user_obj.username, realname=user_obj.realname, hostname=user_obj.hostname, umodes=user_obj.umodes, vhost=user_obj.vhost,
isWebirc=user_obj.isWebirc, isWebsocket=user_obj.isWebsocket, remote_ip=user_obj.remote_ip, score_connexion=user_obj.score_connexion,
geoip=user_obj.geoip, connexion_datetime=user_obj.connexion_datetime
)
self.Client.insert(client)
self.Protocol.send_svs_mode(nickname=fromuser, user_mode='+r')
else:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"Wrong password or account")
return None
except ValueError as ve:
self.Logs.error(f"Value Error: {ve}")
self.Protocol.send_notice(
nick_from=dnickname,
nick_to=fromuser,
msg=f'/msg {self.Config.SERVICE_NICKNAME} {command.upper()} <ACCOUNT> <PASSWORD>'
)
except Exception as err:
self.Logs.error(f"General Error: {err}")
case 'logout':
try:
# LOGOUT <account>
if len(cmd) < 2:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} <account>")
return None
user_obj = self.User.get_User(fromuser)
if user_obj is None:
self.Logs.error(f"The User [{fromuser}] is not available in the database")
return None
client_obj = self.Client.get_Client(user_obj.uid)
if client_obj is None:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="Nothing to logout. please login first")
return None
self.Protocol.send_svs_mode(nickname=fromuser, user_mode='-r')
self.Client.delete(user_obj.uid)
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"You have been logged out successfully")
except ValueError as ve:
self.Logs.error(f"Value Error: {ve}")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} <account>")
except Exception as err:
self.Logs.error(f"General Error: {err}")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} <account>")
case 'help': case 'help':
self.generate_help_menu(nickname=fromuser) self.generate_help_menu(nickname=fromuser)

View File

@@ -111,7 +111,7 @@ class Clone():
except TypeError as te: except TypeError as te:
self.Logs.critical(te) self.Logs.critical(te)
def unload(self, reloading: bool = False) -> None: def unload(self) -> None:
"""Cette methode sera executée a chaque désactivation ou """Cette methode sera executée a chaque désactivation ou
rechargement de module rechargement de module
""" """

View File

@@ -164,14 +164,15 @@ class Command:
""" """
self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value) self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value)
def unload(self, reloading: bool = False) -> None: def unload(self) -> None:
return None return None
def cmd(self, data: list[str]) -> None: def cmd(self, data: list[str]) -> None:
try: try:
# service_id = self.Config.SERVICE_ID
dnickname = self.Config.SERVICE_NICKNAME dnickname = self.Config.SERVICE_NICKNAME
# dchanlog = self.Config.SERVICE_CHANLOG
red = self.Config.COLORS.red red = self.Config.COLORS.red
green = self.Config.COLORS.green green = self.Config.COLORS.green
bold = self.Config.COLORS.bold bold = self.Config.COLORS.bold
@@ -302,7 +303,7 @@ class Command:
service_id = self.Config.SERVICE_ID service_id = self.Config.SERVICE_ID
dchanlog = self.Config.SERVICE_CHANLOG dchanlog = self.Config.SERVICE_CHANLOG
self.user_to_notice = uidornickname self.user_to_notice = uidornickname
fromuser = self.User.get_nickname(uidornickname) fromuser = uidornickname
fromchannel = channel_name fromchannel = channel_name
match command: match command:
@@ -852,9 +853,9 @@ class Command:
case 'topic': case 'topic':
try: try:
# TOPIC <#CHANNEL> <THE TOPIC DESCRIPTION> if len(cmd) == 1:
if len(cmd) < 2: self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} TOPIC #channel THE_TOPIC_MESSAGE")
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} {command.upper()} <#channel> THE_TOPIC_MESSAGE") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f" /msg {dnickname} TOPIC #channel THE_TOPIC_MESSAGE")
return None return None
chan = str(cmd[1]) chan = str(cmd[1])
@@ -863,10 +864,10 @@ class Command:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} TOPIC #channel THE_TOPIC_MESSAGE") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {dnickname} TOPIC #channel THE_TOPIC_MESSAGE")
return None return None
topic_msg: str = ' '.join(cmd[2:]).strip() topic_msg = ' '.join(cmd[2:]).strip()
if topic_msg: if topic_msg:
self.Protocol.send_topic_chan(channel_name=chan, topic_msg=topic_msg) self.Protocol.send2socket(f':{dnickname} TOPIC {chan} :{topic_msg}')
else: else:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You need to specify the topic") self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg="You need to specify the topic")

View File

@@ -200,7 +200,7 @@ class Defender():
self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value) self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value)
def unload(self, reloading: bool = False) -> None: def unload(self) -> None:
"""Cette methode sera executée a chaque désactivation ou """Cette methode sera executée a chaque désactivation ou
rechargement de module rechargement de module
""" """

View File

@@ -182,7 +182,7 @@ class Jsonrpc():
""" """
self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value) self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value)
def unload(self, reloading: bool = False) -> None: def unload(self) -> None:
if self.UnrealIrcdRpcLive.Error.code != -1: if self.UnrealIrcdRpcLive.Error.code != -1:
self.UnrealIrcdRpcLive.unsubscribe() self.UnrealIrcdRpcLive.unsubscribe()
return None return None

View File

@@ -1,367 +0,0 @@
import socket
import json
import time
import re
import psutil
import requests
from dataclasses import dataclass
from datetime import datetime
from typing import Union, TYPE_CHECKING
from core.classes import user
import core.definition as df
if TYPE_CHECKING:
from core.irc import Irc
class Nickserv():
@dataclass
class ModConfModel:
active: bool = False
def __init__(self, ircInstance: 'Irc') -> None:
# Module name (Mandatory)
self.module_name = 'mod_' + str(self.__class__.__name__).lower()
# Add Irc Object to the module (Mandatory)
self.Irc = ircInstance
# Add Loader Object to the module (Mandatory)
self.Loader = ircInstance.Loader
# Add server protocol Object to the module (Mandatory)
self.Protocol = ircInstance.Protocol
# Add Global Configuration to the module (Mandatory)
self.Config = ircInstance.Config
# Add Base object to the module (Mandatory)
self.Base = ircInstance.Base
# Add logs object to the module (Mandatory)
self.Logs = ircInstance.Base.logs
# Add User object to the module (Mandatory)
self.User = ircInstance.User
# Add Client object to the module (Mandatory)
self.Client = ircInstance.Client
# Add Channel object to the module (Mandatory)
self.Channel = ircInstance.Channel
# Add Reputation object to the module (Optional)
self.Reputation = ircInstance.Reputation
# Check if NickServ already exist
# for user_obj in self.User.UID_DB:
# if user_obj.nickname.lower() == 'nickserv':
# self.Logs.warning(f"The NickServ service already exist, impossible to load 2 NickServ services")
# return None
# Create module commands (Mandatory)
self.Irc.build_command(0, self.module_name, 'register', f'Register your nickname /msg NickServ REGISTER <password> <email>')
self.Irc.build_command(0, self.module_name, 'identify', f'Identify yourself with your password /msg NickServ IDENTIFY <account> <password>')
self.Irc.build_command(0, self.module_name, 'logout', 'Reverse the effect of the identify command')
# Init the module (Mandatory)
self.__init_module()
# Log the module
self.Logs.debug(f'-- Module {self.module_name} loaded ...')
def __init_module(self) -> None:
# Create you own tables if needed (Mandatory)
self.__create_tables()
# Load module configuration (Mandatory)
self.__load_module_configuration()
# End of mandatory methods you can start your customization #
self.build_nickserv_information()
return None
def __create_tables(self) -> None:
"""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
Args:
database_name (str): Nom de la base de données ( pas d'espace dans le nom )
Returns:
None: Aucun retour n'es attendu
"""
# table_autoop = '''CREATE TABLE IF NOT EXISTS defender_autoop (
# id INTEGER PRIMARY KEY AUTOINCREMENT,
# datetime TEXT,
# nickname TEXT,
# channel TEXT
# )
# '''
# self.Base.db_execute_query(table_autoop)
# self.Base.db_execute_query(table_config)
# self.Base.db_execute_query(table_trusted)
return None
def __load_module_configuration(self) -> None:
"""### Load Module Configuration
"""
try:
# Variable qui va contenir les options de configuration du module Defender
self.ModConfig = self.ModConfModel(active=True)
# Sync the configuration with core configuration (Mandatory)
self.Base.db_sync_core_config(self.module_name, self.ModConfig)
return None
except TypeError as te:
self.Logs.critical(te)
def __update_configuration(self, param_key: str, param_value: str):
self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value)
def build_nickserv_information(self) -> None:
self.NICKSERV_NICKNAME = 'NickServ'
if self.User.is_exist(self.NICKSERV_NICKNAME):
# If NickServ already exist just return None
self.NICKSERV_UID = self.User.get_uid(self.NICKSERV_NICKNAME)
self.Irc.Settings.NICKSERV_UID = self.NICKSERV_UID
return None
self.NICKSERV_UID = self.Config.SERVEUR_ID + self.Base.get_random(6)
nickserv_uid = self.NICKSERV_UID
self.Irc.Settings.NICKSERV_UID = self.NICKSERV_UID
self.Protocol.send_uid(
nickname=self.NICKSERV_NICKNAME, username='NickServ', hostname='nickserv.deb.biz.st', uid=nickserv_uid, umodes='+ioqBS',
vhost='nickserv.deb.biz.st', remote_ip='127.0.0.1', realname='Nick Service'
)
new_user_obj = self.Loader.Definition.MUser(uid=nickserv_uid, nickname=self.NICKSERV_NICKNAME, username='NickServ', realname='Nick Service',
hostname='nickserv.deb.biz.st', umodes='+ioqBS', vhost='nickserv.deb.biz.st', remote_ip='127.0.0.1')
self.User.insert(new_user_obj)
self.Protocol.send_sjoin(nickserv_uid, self.Config.SERVICE_CHANLOG)
return None
def timer_force_change_nickname(self, nickname: str) -> None:
client_obj = self.Client.get_Client(nickname)
if client_obj is None:
self.Protocol.send_svs_nick(nickname, self.Base.get_random(8))
return None
def unload(self, reloading: bool = False) -> None:
"""Cette methode sera executée a chaque désactivation ou
rechargement de module
"""
if reloading:
pass
else:
# NickServ will be disconnected
self.Protocol.send_quit(self.NICKSERV_UID, f'Stopping {self.module_name} module')
del self.NICKSERV_NICKNAME
del self.NICKSERV_UID
return None
def cmd(self, data: list[str]) -> None:
try:
service_id = self.Config.SERVICE_ID # Defender serveur id
original_serv_response = list(data).copy()
parsed_protocol = self.Protocol.parse_server_msg(data.copy())
match parsed_protocol:
case 'UID':
try:
# ['@...', ':001', 'UID', 'adator', '0', '1733865747', '...', '192.168.1.10', '00118YU01', '0', '+iotwxz', 'netadmin.irc.dev.local', '745A32E5.421A4718.F33AB65A.IP', 'wKgBCg==', ':...']
get_uid = str(original_serv_response[8])
user_obj = self.User.get_User(get_uid)
self.Protocol.send_notice(nick_from=self.NICKSERV_NICKNAME, nick_to=user_obj.nickname,
msg='NickServ is here to protect your nickname'
)
self.Protocol.send_notice(nick_from=self.NICKSERV_NICKNAME, nick_to=user_obj.nickname,
msg='To register a nickname tape /msg NickServ register password email'
)
if self.Client.db_is_account_exist(user_obj.nickname):
self.Protocol.send_notice(nick_from=self.NICKSERV_NICKNAME, nick_to=user_obj.nickname, msg='The nickname is protected please login to keep it')
self.Protocol.send_notice(nick_from=self.NICKSERV_NICKNAME, nick_to=user_obj.nickname, msg=f'/msg {self.NICKSERV_NICKNAME} IDENTIFY <ACCOUNT> <PASSWORD>')
self.Base.create_timer(60, self.timer_force_change_nickname, (user_obj.nickname, ))
except IndexError as ie:
self.Logs.error(f'cmd reputation: index error: {ie}')
case None:
self.Logs.debug(f"** TO BE HANDLE {original_serv_response} {__name__}")
except KeyError as ke:
self.Logs.error(f"{ke} / {original_serv_response} / length {str(len(original_serv_response))}")
except IndexError as ie:
self.Logs.error(f"{ie} / {original_serv_response} / length {str(len(original_serv_response))}")
except Exception as err:
self.Logs.error(f"General Error: {err}")
def hcmds(self, user: str, channel: str, cmd: list, fullcmd: list = []) -> None:
command = str(cmd[0]).lower()
fromuser = user
fromchannel = channel if self.Channel.Is_Channel(channel) else None
dnickname = self.Config.SERVICE_NICKNAME # Defender nickname
dchanlog = self.Config.SERVICE_CHANLOG # Defender chan log
dumodes = self.Config.SERVICE_UMODES # Les modes de Defender
service_id = self.Config.SERVICE_ID # Defender serveur id
match command:
case 'register':
# Register PASSWORD EMAIL
try:
if len(cmd) < 3:
self.Protocol.send_notice(
nick_from=self.NICKSERV_NICKNAME,
nick_to=fromuser,
msg=f'/msg {self.NICKSERV_NICKNAME} {command.upper()} <PASSWORD> <EMAIL>'
)
return None
password = cmd[1]
email = cmd[2]
if not self.Base.is_valid_email(email_to_control=email):
self.Protocol.send_notice(
nick_from=self.NICKSERV_NICKNAME,
nick_to=fromuser,
msg='The email is not valid. You must provide a valid email address (first.name@email.extension)'
)
return None
user_obj = self.User.get_User(fromuser)
if user_obj is None:
self.Logs.error(f"Nickname ({fromuser}) doesn't exist, it is impossible to register this nickname")
return None
# If the account already exist.
if self.Client.db_is_account_exist(fromuser):
self.Protocol.send_notice(
nick_from=self.NICKSERV_NICKNAME,
nick_to=fromuser,
msg=f"Your account already exist, please try to login instead /msg {self.NICKSERV_NICKNAME} IDENTIFY <account> <password>"
)
return None
# If the account doesn't exist then insert into database
data_to_record = {
'createdOn': self.Base.get_datetime(), 'account': fromuser,
'nickname': user_obj.nickname, 'hostname': user_obj.hostname, 'vhost': user_obj.vhost, 'realname': user_obj.realname, 'email': email,
'password': self.Base.crypt_password(password=password), 'level': 0
}
insert_to_db = self.Base.db_execute_query(f"""
INSERT INTO {self.Config.TABLE_CLIENT}
(createdOn, account, nickname, hostname, vhost, realname, email, password, level)
VALUES
(:createdOn, :account, :nickname, :hostname, :vhost, :realname, :email, :password, :level)
""", data_to_record)
if insert_to_db.rowcount > 0:
self.Protocol.send_notice(
nick_from=self.NICKSERV_NICKNAME,
nick_to=fromuser,
msg=f"You have register your nickname successfully"
)
return None
except ValueError as ve:
self.Logs.error(f"Value Error : {ve}")
self.Protocol.send_notice(nick_from=self.NICKSERV_NICKNAME, nick_to=fromuser, msg=f" {self.Config.SERVICE_PREFIX}{command.upper()} <PASSWORD> <EMAIL>")
case 'identify':
try:
# IDENTIFY <ACCOUNT> <PASSWORD>
if len(cmd) < 3:
self.Protocol.send_notice(
nick_from=dnickname,
nick_to=fromuser,
msg=f'/msg {self.NICKSERV_NICKNAME} {command.upper()} <ACCOUNT> <PASSWORD>'
)
return None
account = str(cmd[1]) # account
encrypted_password = self.Base.crypt_password(cmd[2])
user_obj = self.User.get_User(fromuser)
client_obj = self.Client.get_Client(user_obj.uid)
if client_obj is not None:
self.Protocol.send_notice(nick_from=self.NICKSERV_NICKNAME, nick_to=fromuser, msg=f"You are already logged in")
return None
db_query = f"SELECT account FROM {self.Config.TABLE_CLIENT} WHERE account = :account AND password = :password"
db_param = {'account': account, 'password': encrypted_password}
exec_query = self.Base.db_execute_query(
db_query,
db_param
)
result_query = exec_query.fetchone()
if result_query:
account = result_query[0]
self.Protocol.send_notice(nick_from=self.NICKSERV_NICKNAME, nick_to=fromuser, msg=f"You are now logged in")
user_obj_dict = self.User.get_User_AsDict(fromuser)
client = self.Loader.Definition.MClient(
account=account,
**user_obj_dict
)
self.Client.insert(client)
self.Protocol.send_svs2mode(service_uid=self.NICKSERV_UID, nickname=fromuser, user_mode='+r')
else:
self.Protocol.send_notice(nick_from=self.NICKSERV_NICKNAME, nick_to=fromuser, msg=f"Wrong password or account")
except TypeError as te:
self.Logs.error(f"Type Error -> {te}")
except ValueError as ve:
self.Logs.error(f"Value Error -> {ve}")
case 'logout':
try:
# LOGOUT <account>
if len(cmd) < 2:
self.Protocol.send_notice(nick_from=self.NICKSERV_NICKNAME, nick_to=fromuser, msg=f"/msg {self.NICKSERV_NICKNAME} {command.upper()} <ACCOUNT>")
return None
user_obj = self.User.get_User(fromuser)
if user_obj is None:
self.Logs.error(f"The User [{fromuser}] is not available in the database")
return None
client_obj = self.Client.get_Client(user_obj.uid)
if client_obj is None:
self.Protocol.send_notice(nick_from=self.NICKSERV_NICKNAME, nick_to=fromuser, msg="Nothing to logout. please login first")
return None
self.Protocol.send_svs2mode(service_uid=self.NICKSERV_UID, nickname=fromuser, user_mode='-r')
self.Client.delete(user_obj.uid)
self.Protocol.send_notice(nick_from=self.NICKSERV_NICKNAME, nick_to=fromuser, msg=f"You have been logged out successfully")
except ValueError as ve:
self.Logs.error(f"Value Error: {ve}")
self.Protocol.send_notice(nick_from=self.NICKSERV_NICKNAME, nick_to=fromuser, msg=f"/msg {self.NICKSERV_NICKNAME} {command.upper()} <account>")
except Exception as err:
self.Logs.error(f"General Error: {err}")
self.Protocol.send_notice(nick_from=self.NICKSERV_NICKNAME, nick_to=fromuser, msg=f"/msg {self.NICKSERV_NICKNAME} {command.upper()} <account>")

View File

@@ -113,7 +113,7 @@ class Test():
""" """
self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value) self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value)
def unload(self, reloading: bool = False) -> None: def unload(self) -> None:
return None return None

View File

@@ -101,7 +101,7 @@ class Votekick():
self.Base.db_execute_query(table_vote) self.Base.db_execute_query(table_vote)
return None return None
def unload(self, reloading: bool = False) -> None: def unload(self) -> None:
try: try:
for chan in self.VOTE_CHANNEL_DB: for chan in self.VOTE_CHANNEL_DB:
self.Protocol.send_part_chan(uidornickname=self.Config.SERVICE_ID, channel=chan.channel_name) self.Protocol.send_part_chan(uidornickname=self.Config.SERVICE_ID, channel=chan.channel_name)

View File

@@ -1,258 +0,0 @@
from urllib import request
import requests
from dataclasses import dataclass
from datetime import datetime
from typing import Union, TYPE_CHECKING
from core.classes import user
import core.definition as df
if TYPE_CHECKING:
from core.irc import Irc
class Weather():
@dataclass
class ModConfModel:
active: bool = False
def __init__(self, ircInstance: 'Irc') -> None:
# Module name (Mandatory)
self.module_name = 'mod_' + str(self.__class__.__name__).lower()
# Add Irc Object to the module (Mandatory)
self.Irc = ircInstance
# Add Loader Object to the module (Mandatory)
self.Loader = ircInstance.Loader
# Add server protocol Object to the module (Mandatory)
self.Protocol = ircInstance.Protocol
# Add Global Configuration to the module (Mandatory)
self.Config = ircInstance.Config
# Add Base object to the module (Mandatory)
self.Base = ircInstance.Base
# Add logs object to the module (Mandatory)
self.Logs = ircInstance.Base.logs
# Add User object to the module (Mandatory)
self.User = ircInstance.User
# Add Client object to the module (Mandatory)
self.Client = ircInstance.Client
# Add Channel object to the module (Mandatory)
self.Channel = ircInstance.Channel
# Add Reputation object to the module (Optional)
self.Reputation = ircInstance.Reputation
# Create module commands (Mandatory)
self.Irc.build_command(0, self.module_name, 'meteo', 'Get the meteo of a current city')
# Init the module (Mandatory)
self.__init_module()
# Log the module
self.Logs.debug(f'-- Module {self.module_name} loaded ...')
def __init_module(self) -> None:
# Create you own tables if needed (Mandatory)
self.__create_tables()
# Load module configuration (Mandatory)
self.__load_module_configuration()
# End of mandatory methods you can start your customization #
self.from_user = None
self.from_channel = None
return None
def __create_tables(self) -> None:
"""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
Args:
database_name (str): Nom de la base de données ( pas d'espace dans le nom )
Returns:
None: Aucun retour n'es attendu
"""
# table_autoop = '''CREATE TABLE IF NOT EXISTS defender_autoop (
# id INTEGER PRIMARY KEY AUTOINCREMENT,
# datetime TEXT,
# nickname TEXT,
# channel TEXT
# )
# '''
# self.Base.db_execute_query(table_autoop)
# self.Base.db_execute_query(table_config)
# self.Base.db_execute_query(table_trusted)
return None
def __load_module_configuration(self) -> None:
"""### Load Module Configuration
"""
try:
# Variable qui va contenir les options de configuration du module Defender
self.ModConfig = self.ModConfModel(active=True)
# Sync the configuration with core configuration (Mandatory)
self.Base.db_sync_core_config(self.module_name, self.ModConfig)
return None
except TypeError as te:
self.Logs.critical(te)
def __update_configuration(self, param_key: str, param_value: str):
self.Base.db_update_core_config(self.module_name, self.ModConfig, param_key, param_value)
def get_geo_information(self, city: str) -> tuple[str, str, float, float]:
"""_summary_
Args:
city (str): The city you want to get
Returns:
tuple[str, str, float, float]: Country Code, City Name Latitude, Longitude
"""
api_key = 'fd36a3f3715c93f6770a13f5a34ae1e3'
geo_api_url = "http://api.openweathermap.org/geo/1.0/direct"
response = requests.get(
url=geo_api_url,
params={'q': city, 'limit': 1, 'appid': api_key}
)
geo_data = response.json()
if not geo_data:
return (None, None, 0, 0)
country_code = geo_data[0]['country']
city_name = geo_data[0]['name']
latitude: float = geo_data[0]['lat']
longitude: float = geo_data[0]['lon']
return (country_code, city_name, latitude, longitude)
def get_meteo_information(self, city: str, to_nickname: str) -> None:
api_key = 'fd36a3f3715c93f6770a13f5a34ae1e3'
meteo_api_url = "https://api.openweathermap.org/data/2.5/weather" #?lat={lat}&lon={lon}&appid={API key}
country_code, city_name, latitude, longitude = self.get_geo_information(city=city)
response_meteo = requests.get(
url=meteo_api_url,
params={'lat': latitude, 'lon': longitude, 'appid': api_key, 'units': "metric"}
)
meteo_data = response_meteo.json()
if not meteo_data or city_name is None:
self.Protocol.send_notice(nick_from=self.Config.SERVICE_NICKNAME, nick_to=to_nickname,
msg=f"Impossible to find the meteo for [{city}]")
return None
temp_cur = meteo_data['main']['temp']
temp_min = meteo_data['main']['temp_min']
temp_max = meteo_data['main']['temp_max']
if self.from_channel is None:
self.Protocol.send_notice(nick_from=self.Config.SERVICE_NICKNAME, nick_to=to_nickname,
msg=f"Weather of {city_name} located in {country_code} is:")
self.Protocol.send_notice(nick_from=self.Config.SERVICE_NICKNAME, nick_to=to_nickname,
msg=f"Current temperature: {temp_cur} °C")
self.Protocol.send_notice(nick_from=self.Config.SERVICE_NICKNAME, nick_to=to_nickname,
msg=f"Minimum temperature: {temp_min} °C")
self.Protocol.send_notice(nick_from=self.Config.SERVICE_NICKNAME, nick_to=to_nickname,
msg=f"Maximum temperature: {temp_max} °C")
else:
self.Protocol.send_priv_msg(nick_from=self.Config.SERVICE_NICKNAME, channel=self.from_channel,
msg=f"Weather of {city_name} located in {country_code} is:")
self.Protocol.send_priv_msg(nick_from=self.Config.SERVICE_NICKNAME, channel=self.from_channel,
msg=f"Current temperature: {temp_cur} °C")
self.Protocol.send_priv_msg(nick_from=self.Config.SERVICE_NICKNAME, channel=self.from_channel,
msg=f"Minimum temperature: {temp_min} °C")
self.Protocol.send_priv_msg(nick_from=self.Config.SERVICE_NICKNAME, channel=self.from_channel,
msg=f"Maximum temperature: {temp_max} °C")
return None
def unload(self, reloading: bool = False) -> None:
"""Cette methode sera executée a chaque désactivation ou
rechargement de module
"""
if reloading:
pass
else:
self.Protocol.send_quit(self.NICKSERV_UID, f'Stopping {self.module_name} module')
return None
def cmd(self, data: list[str]) -> None:
try:
service_id = self.Config.SERVICE_ID # Defender serveur id
original_serv_response = list(data).copy()
parsed_protocol = self.Protocol.parse_server_msg(data.copy())
match parsed_protocol:
case 'UID':
try:
pass
except IndexError as ie:
self.Logs.error(f'cmd reputation: index error: {ie}')
case None:
self.Logs.debug(f"** TO BE HANDLE {original_serv_response} {__name__}")
except KeyError as ke:
self.Logs.error(f"{ke} / {original_serv_response} / length {str(len(original_serv_response))}")
except IndexError as ie:
self.Logs.error(f"{ie} / {original_serv_response} / length {str(len(original_serv_response))}")
except Exception as err:
self.Logs.error(f"General Error: {err}")
def hcmds(self, user: str, channel: any, cmd: list, fullcmd: list = []) -> None:
command = str(cmd[0]).lower()
fromuser = user
fromchannel = channel if self.Channel.Is_Channel(channel) else None
self.from_channel = fromchannel
self.from_user = fromuser
dnickname = self.Config.SERVICE_NICKNAME # Defender nickname
dchanlog = self.Config.SERVICE_CHANLOG # Defender chan log
dumodes = self.Config.SERVICE_UMODES # Les modes de Defender
service_id = self.Config.SERVICE_ID # Defender serveur id
match command:
case 'meteo':
try:
# meteo <CITY>
if len(cmd) < 2:
self.Protocol.send_notice(nick_from=dnickname, nick_to=fromuser, msg=f"/msg {self.Config.SERVICE_NICKNAME} {command.upper()} METEO <City name>")
return None
city = str(' '.join(cmd[1:]))
to_nickname = fromuser
self.Base.create_thread(self.get_meteo_information, (city, to_nickname))
except TypeError as te:
self.Logs.error(f"Type Error -> {te}")
except ValueError as ve:
self.Logs.error(f"Value Error -> {ve}")

View File

@@ -1,5 +1,5 @@
{ {
"version": "6.1.5", "version": "6.1.2",
"requests": "2.32.3", "requests": "2.32.3",
"psutil": "6.0.0", "psutil": "6.0.0",