Adding the ability to inject functions to be ran prior to the Bot joining channels
* PEP8 compliance changes in formatting * multiple bugfixes * fixing documentation
This commit is contained in:
parent
c416ac14b8
commit
7da5650153
7 changed files with 286 additions and 135 deletions
|
@ -42,4 +42,7 @@ A few default behaviours to note about the `Admin` module.
|
||||||
|
|
||||||
# TODO
|
# TODO
|
||||||
|
|
||||||
|
- Test suites
|
||||||
|
- Module to handle service authentication
|
||||||
- A better way to handle help pages
|
- A better way to handle help pages
|
||||||
|
- `Sphinx` documentation generation
|
||||||
|
|
240
boots/admin.py
240
boots/admin.py
|
@ -21,7 +21,7 @@ class Admin:
|
||||||
LIST = re.compile(r'^list.*$')
|
LIST = re.compile(r'^list.*$')
|
||||||
|
|
||||||
def __init__(self, client: robot.Bot, config: str = None):
|
def __init__(self, client: robot.Bot, config: str = None):
|
||||||
self.logger = logging.getLogger(__class__.__name__)
|
self.logger = logging.getLogger(self.__class__.__name__)
|
||||||
self.logger.debug("Initializing...")
|
self.logger.debug("Initializing...")
|
||||||
self.client = client
|
self.client = client
|
||||||
self.config = config or "./config/admin.pkl"
|
self.config = config or "./config/admin.pkl"
|
||||||
|
@ -115,34 +115,43 @@ class Admin:
|
||||||
self.logger.info("Loading configuration...")
|
self.logger.info("Loading configuration...")
|
||||||
self.logger.debug("Attempting to load configuration {}".format(config))
|
self.logger.debug("Attempting to load configuration {}".format(config))
|
||||||
try:
|
try:
|
||||||
async with aiofiles.open(self.abspath(config or self.config), mode='rb') as f:
|
async with aiofiles.open(
|
||||||
|
self.abspath(config or self.config), mode='rb') as f:
|
||||||
_file = await f.read()
|
_file = await f.read()
|
||||||
try:
|
try:
|
||||||
self.admins = pickle.loads(_file)
|
self.admins = pickle.loads(_file)
|
||||||
except pickle.PickleError:
|
except pickle.PickleError:
|
||||||
self.logger.warn("We failed to load configuration, creating a new one")
|
self.logger.warn(
|
||||||
|
"We failed to load configuration, creating a new one")
|
||||||
self.admins = {}
|
self.admins = {}
|
||||||
await self.add_admin("Admin", "Pa$$w0rd", 1000)
|
await self.add_admin("Admin", "Pa$$w0rd", 1000)
|
||||||
f.close()
|
f.close()
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
self.logger.warn("We failed to read the configuration file, creating a new configuration")
|
self.logger.warn(
|
||||||
|
"We failed to read the configuration file, "
|
||||||
|
"creating a new configuration")
|
||||||
self.admins = {}
|
self.admins = {}
|
||||||
await self.add_admin("Admin", "Pa$$w0rd", 1000)
|
await self.add_admin("Admin", "Pa$$w0rd", 1000)
|
||||||
|
|
||||||
async def save_config(self, config: str = None) -> None:
|
async def save_config(self, config: str = None) -> None:
|
||||||
"""
|
"""
|
||||||
This method will save the configuration of the admins into a pickled database
|
This method will save the configuration of the admins
|
||||||
|
into a pickled database
|
||||||
|
|
||||||
:param config str: the path to the configuration
|
:param config str: the path to the configuration
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
self.logger.debug("We are attempting to write to drive...")
|
self.logger.debug("We are attempting to write to drive...")
|
||||||
async with aiofiles.open(self.abspath(config or self.config), mode='wb+') as f:
|
async with aiofiles.open(
|
||||||
|
self.abspath(config or self.config), mode='wb+') as f:
|
||||||
_file = pickle.dumps(self.admins)
|
_file = pickle.dumps(self.admins)
|
||||||
await f.write(_file)
|
await f.write(_file)
|
||||||
f.close()
|
f.close()
|
||||||
|
|
||||||
async def add_admin(self, user: str, password: str, level: int = 1) -> None:
|
async def add_admin(self,
|
||||||
|
user: str,
|
||||||
|
password: str,
|
||||||
|
level: int = 1) -> None:
|
||||||
"""
|
"""
|
||||||
Method to add an admin to the list of admins
|
Method to add an admin to the list of admins
|
||||||
|
|
||||||
|
@ -160,7 +169,8 @@ class Admin:
|
||||||
self.admins[user]['logged_in_hostname'] = None
|
self.admins[user]['logged_in_hostname'] = None
|
||||||
self.admins[user]['logged_in_nick'] = None
|
self.admins[user]['logged_in_nick'] = None
|
||||||
self.admins[user]['LOGIN'] = re.compile(
|
self.admins[user]['LOGIN'] = re.compile(
|
||||||
r'^login\s+({})\s+({})\s*$'.format(user, re.escape(self.hash(password))))
|
r'^login\s+({})\s+({})\s*$'.format(
|
||||||
|
user, re.escape(self.hash(password))))
|
||||||
self.logger.debug("We are calling save_config()")
|
self.logger.debug("We are calling save_config()")
|
||||||
await self.save_config()
|
await self.save_config()
|
||||||
|
|
||||||
|
@ -179,23 +189,30 @@ class Admin:
|
||||||
self.logger.debug("We are calling save_config()")
|
self.logger.debug("We are calling save_config()")
|
||||||
await self.save_config()
|
await self.save_config()
|
||||||
|
|
||||||
async def _handle(self, nick: str, target: str, message: str, **kwargs: dict) -> None:
|
async def _handle(self,
|
||||||
|
nick: str,
|
||||||
|
target: str,
|
||||||
|
message: str,
|
||||||
|
**kwargs) -> None:
|
||||||
"""
|
"""
|
||||||
Admin handler, this will check if the user is asking actions from the bot
|
Admin handler, this will check if the user
|
||||||
and triggers an ADMIN event that can be consumed later
|
is asking actions from the bot and triggers
|
||||||
|
an ADMIN event that can be consumed later
|
||||||
|
|
||||||
:param nick str: nickname of the caller
|
:param nick str: nickname of the caller
|
||||||
:param target str: location the message was sent to
|
:param target str: location the message was sent to
|
||||||
:param message str: messages coming from the `nick`
|
:param message str: messages coming from the `nick`
|
||||||
:param kwargs dict: for API compatibility
|
:param kwargs: for API compatibility
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
self.logger.debug("We have received nick={} target={} message={} kwargs={}".format(
|
self.logger.debug("We have received nick={} target={} "
|
||||||
|
"message={} kwargs={}".format(
|
||||||
nick, target, message, kwargs))
|
nick, target, message, kwargs))
|
||||||
|
|
||||||
# Set the admin flag
|
# Set the admin flag
|
||||||
admin = self.is_admin(nick, kwargs['host'])
|
admin = self.is_admin(nick, kwargs['host'])
|
||||||
self.logger.debug("We are checking to see if {} is an admin".format(nick))
|
self.logger.debug(
|
||||||
|
"We are checking to see if {} is an admin".format(nick))
|
||||||
if admin:
|
if admin:
|
||||||
kwargs['is_admin'] = True
|
kwargs['is_admin'] = True
|
||||||
kwargs['level'] = self.admins[admin]['level']
|
kwargs['level'] = self.admins[admin]['level']
|
||||||
|
@ -224,12 +241,19 @@ class Admin:
|
||||||
kwargs['nick'] = nick
|
kwargs['nick'] = nick
|
||||||
kwargs['target'] = target
|
kwargs['target'] = target
|
||||||
kwargs['message'] = message
|
kwargs['message'] = message
|
||||||
self.logger.debug("We are triggering a new event called ADMIN with {}".format(kwargs))
|
self.logger.debug(
|
||||||
|
"We are triggering a new event called ADMIN with {}".format(
|
||||||
|
kwargs))
|
||||||
self.client.trigger('ADMIN', **kwargs)
|
self.client.trigger('ADMIN', **kwargs)
|
||||||
|
|
||||||
def admin_help(self, nick: str, target: str, message: str, **kwargs: dict) -> None:
|
def admin_help(self,
|
||||||
|
nick: str,
|
||||||
|
target: str,
|
||||||
|
message: str,
|
||||||
|
**kwargs) -> None:
|
||||||
"""
|
"""
|
||||||
This method will reply back to the user a help manual of the available commands
|
This method will reply back to the user a help manual of the
|
||||||
|
available commands
|
||||||
> help
|
> help
|
||||||
>> help [command]
|
>> help [command]
|
||||||
>> commands: login logout add rm list
|
>> commands: login logout add rm list
|
||||||
|
@ -244,11 +268,12 @@ class Admin:
|
||||||
:param nick str: the nickname of the caller
|
:param nick str: the nickname of the caller
|
||||||
:param target str: the target where the message was sent to
|
:param target str: the target where the message was sent to
|
||||||
:param message str: the message sent to the target
|
:param message str: the message sent to the target
|
||||||
:param kwargs dict: for API compatibility
|
:param kwargs: for API compatibility
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if target == self.client.nick:
|
if target == self.client.nick:
|
||||||
self.logger.debug("We have received a help request from {}".format(nick))
|
self.logger.debug(
|
||||||
|
"We have received a help request from {}".format(nick))
|
||||||
if kwargs.get("is_admin", None) is True:
|
if kwargs.get("is_admin", None) is True:
|
||||||
match_help = self.HELP.match(message)
|
match_help = self.HELP.match(message)
|
||||||
match_help_cmd = self.HELP_CMD.match(message)
|
match_help_cmd = self.HELP_CMD.match(message)
|
||||||
|
@ -256,21 +281,29 @@ class Admin:
|
||||||
if match_help_cmd:
|
if match_help_cmd:
|
||||||
if len(match_help_cmd.groups()) == 1:
|
if len(match_help_cmd.groups()) == 1:
|
||||||
if match_help_cmd.group(1) == 'login':
|
if match_help_cmd.group(1) == 'login':
|
||||||
kwargs['message'] = "login <user> <password> <level> - Login as an admin with your account"
|
kwargs['message'] = \
|
||||||
|
"login <user> <password> <level> - Login as " \
|
||||||
|
"an admin with your account"
|
||||||
self.client.send("PRIVMSG", **kwargs)
|
self.client.send("PRIVMSG", **kwargs)
|
||||||
if match_help_cmd.group(1) == 'logout':
|
if match_help_cmd.group(1) == 'logout':
|
||||||
kwargs['message'] = "logout <user> - Log out from your account"
|
kwargs['message'] = \
|
||||||
|
"logout <user> - Log out from your account"
|
||||||
self.client.send("PRIVMSG", **kwargs)
|
self.client.send("PRIVMSG", **kwargs)
|
||||||
if match_help_cmd.group(1) == 'passwd':
|
if match_help_cmd.group(1) == 'passwd':
|
||||||
kwargs['message'] = "passwd <new password> - Change your account\'s password"
|
kwargs['message'] = \
|
||||||
|
"passwd <new password> - Change your" \
|
||||||
|
" account\'s password"
|
||||||
self.client.send("PRIVMSG", **kwargs)
|
self.client.send("PRIVMSG", **kwargs)
|
||||||
if match_help_cmd.group(1) == 'add':
|
if match_help_cmd.group(1) == 'add':
|
||||||
kwargs['message'] = \
|
kwargs['message'] = \
|
||||||
"add <user> <password> <level> - adds an admin account to the list of" \
|
"add <user> <password> <level> - adds" \
|
||||||
"admins with provided level"
|
" an admin account to the list of admins" \
|
||||||
|
" with provided level"
|
||||||
self.client.send("PRIVMSG", **kwargs)
|
self.client.send("PRIVMSG", **kwargs)
|
||||||
if match_help_cmd.group(1) == 'rm':
|
if match_help_cmd.group(1) == 'rm':
|
||||||
kwargs['message'] = "rm <user> - removes an admin from the list of admins"
|
kwargs['message'] = \
|
||||||
|
"rm <user> - removes an admin from the list" \
|
||||||
|
" of admins"
|
||||||
self.client.send("PRIVMSG", **kwargs)
|
self.client.send("PRIVMSG", **kwargs)
|
||||||
if match_help_cmd.group(1) == 'list':
|
if match_help_cmd.group(1) == 'list':
|
||||||
kwargs['message'] = "list - lists all the admins"
|
kwargs['message'] = "list - lists all the admins"
|
||||||
|
@ -278,10 +311,15 @@ class Admin:
|
||||||
elif match_help:
|
elif match_help:
|
||||||
kwargs['message'] = "help [command]"
|
kwargs['message'] = "help [command]"
|
||||||
self.client.send("PRIVMSG", **kwargs)
|
self.client.send("PRIVMSG", **kwargs)
|
||||||
kwargs['message'] = "commands: login logout passwd add rm list"
|
kwargs['message'] = \
|
||||||
|
"commands: login logout passwd add rm list"
|
||||||
self.client.send("PRIVMSG", **kwargs)
|
self.client.send("PRIVMSG", **kwargs)
|
||||||
|
|
||||||
async def log_in(self, nick: str, target: str, message:str , **kwargs: dict) -> None:
|
async def log_in(self,
|
||||||
|
nick: str,
|
||||||
|
target: str,
|
||||||
|
message: str,
|
||||||
|
**kwargs) -> None:
|
||||||
"""
|
"""
|
||||||
This method is called when a user attempts to login to the bot.
|
This method is called when a user attempts to login to the bot.
|
||||||
It will mark the user as logged on on successful authentication
|
It will mark the user as logged on on successful authentication
|
||||||
|
@ -295,7 +333,7 @@ class Admin:
|
||||||
:param nick str: the nickname of the caller
|
:param nick str: the nickname of the caller
|
||||||
:param target str: location the message was sent to
|
:param target str: location the message was sent to
|
||||||
:param message str: message coming from `nick`
|
:param message str: message coming from `nick`
|
||||||
:param kwargs dict: for API compatibility
|
:param kwargs: for API compatibility
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if target == self.client.nick:
|
if target == self.client.nick:
|
||||||
|
@ -306,28 +344,36 @@ class Admin:
|
||||||
login = user['LOGIN']
|
login = user['LOGIN']
|
||||||
if login.match(self.hash_pass(message)):
|
if login.match(self.hash_pass(message)):
|
||||||
if kwargs.get('is_admin', None) is True and \
|
if kwargs.get('is_admin', None) is True and \
|
||||||
match.group(1) != self.is_admin(nick, kwargs['host']):
|
match.group(1) != self.is_admin(nick,
|
||||||
|
kwargs['host']):
|
||||||
self.logger.warn(
|
self.logger.warn(
|
||||||
"We detected that {} is already logged in as different user, logging him out".format(nick))
|
"We detected that {} is already logged in as"
|
||||||
|
" different user, logging him out".format(nick))
|
||||||
await self.log_out(nick, target, **kwargs)
|
await self.log_out(nick, target, **kwargs)
|
||||||
if match.group(1) == self.is_admin(nick, kwargs['host']):
|
if match.group(1) == self.is_admin(nick, kwargs['host']):
|
||||||
kwargs['target'] = nick
|
kwargs['target'] = nick
|
||||||
kwargs['message'] = "{} you are already logged in...".format(nick)
|
kwargs['message'] = "{} you are already logged in" \
|
||||||
self.logger.warn("We detected that {} is already logged in, notifying".format(nick))
|
"...".format(nick)
|
||||||
|
self.logger.warn("We detected that {} is already "
|
||||||
|
"logged in, notifying".format(nick))
|
||||||
else:
|
else:
|
||||||
self.admins[match.group(1)]['logged_in'] = True
|
self.admins[match.group(1)]['logged_in'] = True
|
||||||
self.admins[match.group(1)]['logged_in_nick'] = str(nick)
|
self.admins[match.group(1)]['logged_in_nick'] =\
|
||||||
self.admins[match.group(1)]['logged_in_hostname'] = str(kwargs['host'])
|
str(nick)
|
||||||
|
self.admins[match.group(1)]['logged_in_hostname'] = \
|
||||||
|
str(kwargs['host'])
|
||||||
kwargs['is_admin'] = True
|
kwargs['is_admin'] = True
|
||||||
kwargs['target'] = nick
|
kwargs['target'] = nick
|
||||||
kwargs['message'] = "{}, you are logged in to {} successfully".format(
|
kwargs['message'] = "{}, you are logged in to {}" \
|
||||||
|
" successfully".format(
|
||||||
nick, match.group(1))
|
nick, match.group(1))
|
||||||
self.logger.debug("We have logged in {} successfully, notifying".format(nick))
|
self.logger.debug("We have logged in {} successfully, "
|
||||||
|
"notifying".format(nick))
|
||||||
self.client.send("PRIVMSG", **kwargs)
|
self.client.send("PRIVMSG", **kwargs)
|
||||||
self.logger.debug("We are calling save_config()")
|
self.logger.debug("We are calling save_config()")
|
||||||
await self.save_config()
|
await self.save_config()
|
||||||
|
|
||||||
async def log_out(self, nick: str, target: str, **kwargs: dict) -> None:
|
async def log_out(self, nick: str, target: str, **kwargs) -> None:
|
||||||
"""
|
"""
|
||||||
This method is called when a user attempts to logout to the bot.
|
This method is called when a user attempts to logout to the bot.
|
||||||
It will mark the user as logged out if they are the user logged
|
It will mark the user as logged out if they are the user logged
|
||||||
|
@ -339,7 +385,7 @@ class Admin:
|
||||||
|
|
||||||
:param nick str: the nickname of the caller
|
:param nick str: the nickname of the caller
|
||||||
:param target str: location where the message was sent to
|
:param target str: location where the message was sent to
|
||||||
:param kwargs dict: for API compatibility
|
:param kwargs: for API compatibility
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if target == self.client.nick:
|
if target == self.client.nick:
|
||||||
|
@ -352,24 +398,29 @@ class Admin:
|
||||||
self.admins[admin]['logged_in_hostname'] = None
|
self.admins[admin]['logged_in_hostname'] = None
|
||||||
kwargs['is_admin'] = False
|
kwargs['is_admin'] = False
|
||||||
kwargs['target'] = nick
|
kwargs['target'] = nick
|
||||||
kwargs['message'] = "{}, you are logged out of {} successfully".format(
|
kwargs['message'] = "{}, you are logged out of" \
|
||||||
nick, admin)
|
" successfully".format(nick, admin)
|
||||||
self.logger.debug("We have successfully logged {} out, notifying".format(nick))
|
self.logger.debug("We have successfully logged {}"
|
||||||
|
" out, notifying".format(nick))
|
||||||
self.client.send("PRIVMSG", **kwargs)
|
self.client.send("PRIVMSG", **kwargs)
|
||||||
self.logger.debug("We are calling save_config")
|
self.logger.debug("We are calling save_config")
|
||||||
await self.save_config()
|
await self.save_config()
|
||||||
|
|
||||||
async def passwd(self, nick: str, target: str, message: str, **kwargs: dict) -> None:
|
async def passwd(self,
|
||||||
|
nick: str,
|
||||||
|
target: str,
|
||||||
|
message: str,
|
||||||
|
**kwargs) -> None:
|
||||||
"""
|
"""
|
||||||
This method will change the password to the administrator currently logged in
|
This method will change the password to the administrator currently
|
||||||
to the account.
|
logged in to the account.
|
||||||
|
|
||||||
Saves the configuration to database
|
Saves the configuration to database
|
||||||
|
|
||||||
:param nick str: the nickname of the caller
|
:param nick str: the nickname of the caller
|
||||||
:param target str: the target where the message was sent to
|
:param target str: the target where the message was sent to
|
||||||
:param message str: the message sent to target
|
:param message str: the message sent to target
|
||||||
:param kwargs dict: for API compatibility
|
:param kwargs: for API compatibility
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if target == self.client.nick:
|
if target == self.client.nick:
|
||||||
|
@ -380,11 +431,15 @@ class Admin:
|
||||||
admin = self.is_admin(nick, kwargs['host'])
|
admin = self.is_admin(nick, kwargs['host'])
|
||||||
self.admins[admin]['password'] = self.hash(match.group(1))
|
self.admins[admin]['password'] = self.hash(match.group(1))
|
||||||
self.admins[admin]['LOGIN'] = re.compile(
|
self.admins[admin]['LOGIN'] = re.compile(
|
||||||
r'^login\s+({})\s+({})\s*$'.format(admin, re.escape(self.hash(match.group(1)))))
|
r'^login\s+({})\s+({})\s*$'.format(
|
||||||
|
admin, re.escape(self.hash(match.group(1)))))
|
||||||
kwargs['target'] = nick
|
kwargs['target'] = nick
|
||||||
kwargs['message'] = '{}, password for {} has been successfully changed...'.format(
|
kwargs['message'] = \
|
||||||
nick, admin)
|
'{}, password for {} has been successfully' \
|
||||||
self.logger.debug("We have successfully changed {}'s password, notifying".format(nick))
|
' changed...'.format(nick, admin)
|
||||||
|
self.logger.debug(
|
||||||
|
"We have successfully changed {}'s password,"
|
||||||
|
" notifying".format(nick))
|
||||||
self.client.send("PRIVMSG", **kwargs)
|
self.client.send("PRIVMSG", **kwargs)
|
||||||
self.logger.debug("We are calling save_config()")
|
self.logger.debug("We are calling save_config()")
|
||||||
await self.save_config()
|
await self.save_config()
|
||||||
|
@ -392,17 +447,21 @@ class Admin:
|
||||||
self.logger.debug("We are logging {} out".format(nick))
|
self.logger.debug("We are logging {} out".format(nick))
|
||||||
await self.log_out(nick, **kwargs)
|
await self.log_out(nick, **kwargs)
|
||||||
|
|
||||||
async def admin_add(self, nick: str, target: str, message: str, **kwargs: dict) -> None:
|
async def admin_add(self,
|
||||||
|
nick: str,
|
||||||
|
target: str,
|
||||||
|
message: str,
|
||||||
|
**kwargs) -> None:
|
||||||
"""
|
"""
|
||||||
This method will add an administrator to the list of administrators only
|
This method will add an administrator to the list of administrators
|
||||||
if the administrator user exists
|
only if the administrator user exists
|
||||||
|
|
||||||
Saves configuration to database
|
Saves configuration to database
|
||||||
|
|
||||||
:param nick str: the nickname of the caller
|
:param nick str: the nickname of the caller
|
||||||
:param target str: location where the message was sent to
|
:param target str: location where the message was sent to
|
||||||
:param message str: the message being sent to the target
|
:param message str: the message being sent to the target
|
||||||
:param kwargs dict: for API compatibility
|
:param kwargs: for API compatibility
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if target == self.client.nick:
|
if target == self.client.nick:
|
||||||
|
@ -412,24 +471,33 @@ class Admin:
|
||||||
if len(match.groups()) == 3:
|
if len(match.groups()) == 3:
|
||||||
if self.admins.get(match.group(1), None) is None:
|
if self.admins.get(match.group(1), None) is None:
|
||||||
kwargs['target'] = nick
|
kwargs['target'] = nick
|
||||||
level = self.level_up(kwargs['level'], int(match.group(3)))
|
level = self.level_up(kwargs['level'],
|
||||||
kwargs['message'] = "{} has been added with level {}...".format(
|
int(match.group(3)))
|
||||||
|
kwargs['message'] = "{} has been added with " \
|
||||||
|
"level {}...".format(
|
||||||
match.group(1), level)
|
match.group(1), level)
|
||||||
self.logger.debug(
|
self.logger.debug(
|
||||||
"We have added {} with level {}, notifying {}".format(
|
"We have added {} with level {}, notifying"
|
||||||
match.group(1), level, nick))
|
" {}".format(match.group(1), level, nick))
|
||||||
await self.add_admin(match.group(1), match.group(2), level)
|
await self.add_admin(
|
||||||
|
match.group(1), match.group(2), level)
|
||||||
else:
|
else:
|
||||||
kwargs['target'] = nick
|
kwargs['target'] = nick
|
||||||
kwargs['message'] = "{} has already been added...".format(match.group(1))
|
kwargs['message'] = "{} has already been added" \
|
||||||
|
"...".format(match.group(1))
|
||||||
self.logger.warn(
|
self.logger.warn(
|
||||||
"We detected that {} has already been added, notifying {}".format(match.group(1), nick))
|
"We detected that {} has already been added,"
|
||||||
|
" notifying {}".format(match.group(1), nick))
|
||||||
self.client.send("PRIVMSG", **kwargs)
|
self.client.send("PRIVMSG", **kwargs)
|
||||||
|
|
||||||
async def admin_rm(self, nick: str, target: str, message: str, **kwags: dict) -> None:
|
async def admin_rm(self,
|
||||||
|
nick: str,
|
||||||
|
target: str,
|
||||||
|
message: str,
|
||||||
|
**kwags) -> None:
|
||||||
"""
|
"""
|
||||||
This method will remove an administrator from the list of administrators only
|
This method will remove an administrator from the list of
|
||||||
if the administrator user exists
|
administrators only if the administrator user exists
|
||||||
|
|
||||||
The caller will be notified either way
|
The caller will be notified either way
|
||||||
|
|
||||||
|
@ -438,7 +506,7 @@ class Admin:
|
||||||
:param nick str: the nickname of the caller
|
:param nick str: the nickname of the caller
|
||||||
:param target str: location where the message was sent to
|
:param target str: location where the message was sent to
|
||||||
:param message str: the message being sent to the target
|
:param message str: the message being sent to the target
|
||||||
:param kwags dict: for API compatibility
|
:param kwags: for API compatibility
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if target == self.client.nick:
|
if target == self.client.nick:
|
||||||
|
@ -448,33 +516,41 @@ class Admin:
|
||||||
if len(match.groups()) == 1:
|
if len(match.groups()) == 1:
|
||||||
if self.admins.get(match.group(1), None) is None:
|
if self.admins.get(match.group(1), None) is None:
|
||||||
kwags['target'] = nick
|
kwags['target'] = nick
|
||||||
kwags['message'] = "{} is not on the list...".format(match.group(1))
|
kwags['message'] = "{} is not on the list" \
|
||||||
|
"...".format(match.group(1))
|
||||||
self.logger.warn("admin_rm() ")
|
self.logger.warn("admin_rm() ")
|
||||||
else:
|
else:
|
||||||
if kwags['level'] > self.admins[match.group(1)]['level'] or \
|
if kwags['level'] > \
|
||||||
(kwags['level'] == 1000 and self.admins[match.group(1)]['level'] and
|
self.admins[match.group(1)]['level'] \
|
||||||
kwags['level'] == self.admins[match.group(1)]['level']):
|
or (kwags['level'] == 1000
|
||||||
|
and self.admins[match.group(1)]['level']
|
||||||
|
and kwags['level'] ==
|
||||||
|
self.admins[match.group(1)]['level']):
|
||||||
kwags['target'] = nick
|
kwags['target'] = nick
|
||||||
kwags['message'] = "{} has been removed...".format(match.group(1))
|
kwags['message'] = "{} has been removed" \
|
||||||
self.logger.debug("We removed {} successfully, notifying {}".format(
|
"...".format(match.group(1))
|
||||||
|
self.logger.debug("We removed {} successfully,"
|
||||||
|
" notifying {}".format(
|
||||||
match.group(1), nick))
|
match.group(1), nick))
|
||||||
await self.rm_admin(match.group(1))
|
await self.rm_admin(match.group(1))
|
||||||
else:
|
else:
|
||||||
kwags['target'] = nick
|
kwags['target'] = nick
|
||||||
kwags['message'] = "{}, you do not have enough access to delete {}".format(
|
kwags['message'] = "{}, you do not have enough" \
|
||||||
|
" access to delete {}".format(
|
||||||
nick, match.group(1))
|
nick, match.group(1))
|
||||||
self.logger.warn(
|
self.logger.warn(
|
||||||
"We detected that {0} does not have enough access to delete {1}, notifying {0}".format(
|
"We detected that {0} does not have enough"
|
||||||
|
" access to delete {1}, notifying {0}".format(
|
||||||
nick, match.group(1)))
|
nick, match.group(1)))
|
||||||
self.client.send("PRIVMSG", **kwags)
|
self.client.send("PRIVMSG", **kwags)
|
||||||
|
|
||||||
def admin_list(self, nick: str, target: str, **kwargs: dict) -> None:
|
def admin_list(self, nick: str, target: str, **kwargs) -> None:
|
||||||
"""
|
"""
|
||||||
This method returns to the admin the admin list
|
This method returns to the admin the admin list
|
||||||
|
|
||||||
:param nick str: the nickname of the caller
|
:param nick str: the nickname of the caller
|
||||||
:param target str: location where the message was sent to
|
:param target str: location where the message was sent to
|
||||||
:param kwargs dict: for API compatibility
|
:param kwargs: for API compatibility
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if target == self.client.nick:
|
if target == self.client.nick:
|
||||||
|
@ -483,15 +559,17 @@ class Admin:
|
||||||
admins = ""
|
admins = ""
|
||||||
for key, _ in self.admins.items():
|
for key, _ in self.admins.items():
|
||||||
if admins:
|
if admins:
|
||||||
admins = "{} {}({})".format(admins, key, self.admins[key]['level'])
|
admins = "{} {}({})".format(
|
||||||
|
admins, key, self.admins[key]['level'])
|
||||||
else:
|
else:
|
||||||
admins = "{}({})".format(key, self.admins[key]['level'])
|
admins = "{}({})".format(
|
||||||
|
key, self.admins[key]['level'])
|
||||||
kwargs['target'] = nick
|
kwargs['target'] = nick
|
||||||
kwargs['message'] = "List of Administrators:"
|
kwargs['message'] = "List of Administrators:"
|
||||||
self.client.send("PRIVMSG", **kwargs)
|
self.client.send("PRIVMSG", **kwargs)
|
||||||
kwargs['message'] = admins
|
kwargs['message'] = admins
|
||||||
self.logger.debug("We are returning admin list page to {}".format(
|
self.logger.debug("We are returning admin list page to"
|
||||||
kwargs))
|
" {}".format(kwargs))
|
||||||
self.client.send("PRIVMSG", **kwargs)
|
self.client.send("PRIVMSG", **kwargs)
|
||||||
|
|
||||||
def is_admin(self, user: str, host: str):
|
def is_admin(self, user: str, host: str):
|
||||||
|
@ -508,7 +586,9 @@ class Admin:
|
||||||
if value.get('logged_in', None) and \
|
if value.get('logged_in', None) and \
|
||||||
value.get('logged_in_nick', None) == user and \
|
value.get('logged_in_nick', None) == user and \
|
||||||
value.get('logged_in_hostname', None) == host:
|
value.get('logged_in_hostname', None) == host:
|
||||||
self.logger.debug("We are returning {} as an admin".format(user))
|
self.logger.debug("We are returning {} as an"
|
||||||
|
" admin".format(user))
|
||||||
return admin
|
return admin
|
||||||
self.logger.debug("We are returning nothing, {} is not an admin".format(user))
|
self.logger.debug("We are returning nothing, {} is"
|
||||||
|
" not an admin".format(user))
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -5,13 +5,14 @@ import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
import admin
|
import admin
|
||||||
|
|
||||||
|
|
||||||
class AdminCmd:
|
class AdminCmd:
|
||||||
"""
|
"""
|
||||||
This is AdminCmd class that consumes ADMIN events and parses them
|
This is AdminCmd class that consumes ADMIN events and parses them
|
||||||
into known actions defined by users
|
into known actions defined by users
|
||||||
"""
|
"""
|
||||||
def __init__(self, admin: admin.Admin, modifier: str = "!"):
|
def __init__(self, admin: admin.Admin, modifier: str = "!"):
|
||||||
self.logger = logging.getLogger(__class__.__name__)
|
self.logger = logging.getLogger(self.__class__.__name__)
|
||||||
self.logger.debug("Initializing...")
|
self.logger.debug("Initializing...")
|
||||||
self.admin = admin
|
self.admin = admin
|
||||||
self.client = admin.client
|
self.client = admin.client
|
||||||
|
@ -20,21 +21,24 @@ class AdminCmd:
|
||||||
self.services = {}
|
self.services = {}
|
||||||
admin.client.on("ADMIN")(self._handle)
|
admin.client.on("ADMIN")(self._handle)
|
||||||
|
|
||||||
def _handle(self, target: str, message: str, **kwargs: dict) -> None:
|
def _handle(self, target: str, message: str, **kwargs) -> None:
|
||||||
"""
|
"""
|
||||||
client callback on event trigger
|
client callback on event trigger
|
||||||
|
|
||||||
:param target str: the target the message was sent to
|
:param target str: the target the message was sent to
|
||||||
:param message str: the message sent to the target
|
:param message str: the message sent to the target
|
||||||
:param kwargs dict: for API compatibility
|
:param kwargs: for API compatibility
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
if bool(kwargs.get('is_admin', None)):
|
if bool(kwargs.get('is_admin', None)):
|
||||||
self.logger.debug("We are being called by {}".format(kwargs['nick']))
|
self.logger.debug(
|
||||||
|
"We are being called by {}".format(kwargs['nick']))
|
||||||
for regex, (func, pattern) in self.services.items():
|
for regex, (func, pattern) in self.services.items():
|
||||||
match = regex.match(message)
|
match = regex.match(message)
|
||||||
if match:
|
if match:
|
||||||
self.logger.debug("We are calling the function that matched the regex {}".format(regex))
|
self.logger.debug(
|
||||||
|
"We are calling the function that matched the regex"
|
||||||
|
" {}".format(regex))
|
||||||
split_msg = message.split(" ")
|
split_msg = message.split(" ")
|
||||||
message = " ".join(split_msg[1:])
|
message = " ".join(split_msg[1:])
|
||||||
self.client.loop.create_task(
|
self.client.loop.create_task(
|
||||||
|
@ -43,13 +47,13 @@ class AdminCmd:
|
||||||
def on_command(self,
|
def on_command(self,
|
||||||
command: str,
|
command: str,
|
||||||
func: types.FunctionType = None,
|
func: types.FunctionType = None,
|
||||||
** kwargs: dict) -> types.FunctionType:
|
** kwargs) -> types.FunctionType:
|
||||||
"""
|
"""
|
||||||
Decorator function for the administrator commands
|
Decorator function for the administrator commands
|
||||||
|
|
||||||
:param commant str: the command that the admins are allowed to do
|
:param commant str: the command that the admins are allowed to do
|
||||||
:param func types.FunctionType: the function being decorated
|
:param func types.FunctionType: the function being decorated
|
||||||
:param kwargs dict: for API compatibility
|
:param kwargs: for API compatibility
|
||||||
:return: types.FunctionType the function that called it
|
:return: types.FunctionType the function that called it
|
||||||
"""
|
"""
|
||||||
if func is None:
|
if func is None:
|
||||||
|
@ -59,7 +63,8 @@ class AdminCmd:
|
||||||
if not asyncio.iscoroutinefunction(wrapped):
|
if not asyncio.iscoroutinefunction(wrapped):
|
||||||
wrapped = asyncio.coroutine(wrapped)
|
wrapped = asyncio.coroutine(wrapped)
|
||||||
|
|
||||||
compiled = re.compile(r'^{}{}\s*(.*)$'.format(re.escape(self.modifier), command))
|
compiled = re.compile(r'^{}{}\s*(.*)$'.format(
|
||||||
|
re.escape(self.modifier), command))
|
||||||
self.services[compiled] = (wrapped, command)
|
self.services[compiled] = (wrapped, command)
|
||||||
|
|
||||||
return func
|
return func
|
||||||
|
|
|
@ -11,7 +11,28 @@ logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
async def plugins(bot: robot.Bot):
|
async def plugins(bot: robot.Bot):
|
||||||
|
|
||||||
|
@bot.pre_public
|
||||||
|
async def auth(**kwargs):
|
||||||
|
logger.debug("Asking Help")
|
||||||
|
bot.send("USERMODE", nick=bot.nick, modes="+x")
|
||||||
|
target = "E@channels.evilnet.org"
|
||||||
|
message = "login <nick> <password>"
|
||||||
|
bot.send("PRIVMSG", target=target, message=message)
|
||||||
|
await bot.wait("NOTICE")
|
||||||
|
|
||||||
|
# Code below will not work, it is awaiting a PR upstream
|
||||||
|
# @bot.on("USERMODE")
|
||||||
|
# def umode(**kwargs):
|
||||||
|
# logger.debug("USERMODE {}".format(kwargs))
|
||||||
|
|
||||||
|
# @bot.on("CHANNELMODE")
|
||||||
|
# def cmode(**kwargs):
|
||||||
|
# logger.debug("CHANNELMODE {}".format(kwargs))
|
||||||
|
|
||||||
|
# 8Ball
|
||||||
magic_ball = eightball.EightBall(bot)
|
magic_ball = eightball.EightBall(bot)
|
||||||
|
|
||||||
@magic_ball.on_keyword
|
@magic_ball.on_keyword
|
||||||
async def ball(target, message, **kwargs):
|
async def ball(target, message, **kwargs):
|
||||||
bot.send("PRIVMSG", target=target, message=message)
|
bot.send("PRIVMSG", target=target, message=message)
|
||||||
|
@ -38,7 +59,8 @@ async def plugins(bot: robot.Bot):
|
||||||
@admin_cmd.on_command("action")
|
@admin_cmd.on_command("action")
|
||||||
def action(target, message, **kwargs):
|
def action(target, message, **kwargs):
|
||||||
kwargs['target'] = message.split(' ')[0]
|
kwargs['target'] = message.split(' ')[0]
|
||||||
kwargs['message'] = "\x01ACTION {}\x01".format(" ".join(message.split(' ')[1:]))
|
kwargs['message'] = \
|
||||||
|
"\x01ACTION {}\x01".format(" ".join(message.split(' ')[1:]))
|
||||||
bot.send("PRIVMSG", **kwargs)
|
bot.send("PRIVMSG", **kwargs)
|
||||||
|
|
||||||
@admin_cmd.on_command("quit")
|
@admin_cmd.on_command("quit")
|
||||||
|
@ -48,16 +70,19 @@ async def plugins(bot: robot.Bot):
|
||||||
# Exit the event loop cleanly
|
# Exit the event loop cleanly
|
||||||
bot.loop.stop()
|
bot.loop.stop()
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
|
|
||||||
host = 'eu.undernet.org'
|
host = 'irc.evilnet.org'
|
||||||
port = 6667
|
port = 6667
|
||||||
ssl = False
|
ssl = False
|
||||||
|
|
||||||
nick = "LuckyBoots"
|
nick = "LuckyBoots"
|
||||||
channel = "#msaytbeh"
|
channel = "#boots"
|
||||||
|
|
||||||
bot = robot.Bot(host=host, port=port, ssl=ssl, nick=nick, channels=[channel])
|
bot = robot.Bot(host=host, port=port,
|
||||||
|
ssl=ssl, nick=nick,
|
||||||
|
channels=[channel])
|
||||||
|
|
||||||
bot.loop.create_task(bot.connect())
|
bot.loop.create_task(bot.connect())
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@ import functools
|
||||||
import asyncio
|
import asyncio
|
||||||
import robot
|
import robot
|
||||||
|
|
||||||
|
|
||||||
class EightBall:
|
class EightBall:
|
||||||
"""
|
"""
|
||||||
EightBall Game for the IRC bot
|
EightBall Game for the IRC bot
|
||||||
|
@ -34,7 +35,7 @@ class EightBall:
|
||||||
]
|
]
|
||||||
|
|
||||||
def __init__(self, client: robot.Bot, keyword: str = ".8ball"):
|
def __init__(self, client: robot.Bot, keyword: str = ".8ball"):
|
||||||
self.logger = logging.getLogger(__class__.__name__)
|
self.logger = logging.getLogger(self.__class__.__name__)
|
||||||
self.logger.debug("Initializing...")
|
self.logger.debug("Initializing...")
|
||||||
self.client = client
|
self.client = client
|
||||||
self.questions = {}
|
self.questions = {}
|
||||||
|
@ -48,7 +49,7 @@ class EightBall:
|
||||||
:param nick str: nickname of the caller
|
:param nick str: nickname of the caller
|
||||||
:param target str: nickname to reply to
|
:param target str: nickname to reply to
|
||||||
:param message str: the question asked
|
:param message str: the question asked
|
||||||
:param kwargs dict:
|
:param kwargs: for API compatibility
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
self.logger.debug("We are being called by {}".format(nick))
|
self.logger.debug("We are being called by {}".format(nick))
|
||||||
|
@ -61,14 +62,17 @@ class EightBall:
|
||||||
for regex, (func, pattern) in self.questions.items():
|
for regex, (func, pattern) in self.questions.items():
|
||||||
match = regex.match(message)
|
match = regex.match(message)
|
||||||
if match:
|
if match:
|
||||||
if is_question(match.group(1)):
|
if EightBall.is_question(match.group(1)):
|
||||||
answer = self._get_answer()
|
answer = self._get_answer()
|
||||||
message = "{}, {}".format(nick, answer)
|
message = "{}, {}".format(nick, answer)
|
||||||
self.logger.debug("We found '{}', notifying {}".format(answer, nick))
|
self.logger.debug("We found '{}', notifying"
|
||||||
|
" {}".format(answer, nick))
|
||||||
else:
|
else:
|
||||||
message = \
|
message = \
|
||||||
"{}, I did not detect a question for me to answer".format(nick)
|
"{}, I did not detect a question for me" \
|
||||||
self.logger.debug("We did not detect a question, notifying {}".format(nick))
|
" to answer".format(nick)
|
||||||
|
self.logger.debug("We did not detect a question,"
|
||||||
|
" notifying {}".format(nick))
|
||||||
self.client.loop.create_task(
|
self.client.loop.create_task(
|
||||||
func(target, message, **kwargs))
|
func(target, message, **kwargs))
|
||||||
|
|
||||||
|
@ -100,13 +104,13 @@ class EightBall:
|
||||||
|
|
||||||
def on_keyword(self,
|
def on_keyword(self,
|
||||||
func: types.FunctionType = None,
|
func: types.FunctionType = None,
|
||||||
**kwargs: dict):
|
**kwargs):
|
||||||
"""
|
"""
|
||||||
Decorator function for the 8ball game
|
Decorator function for the 8ball game
|
||||||
|
|
||||||
:param keyword str: the keyword to activate the 8ball game
|
:param keyword str: the keyword to activate the 8ball game
|
||||||
:param func types.FunctionType: the function being decorated
|
:param func types.FunctionType: the function being decorated
|
||||||
:param kwargs dict: for API compatibility
|
:param kwargs: for API compatibility
|
||||||
:return: function the function that called it
|
:return: function the function that called it
|
||||||
"""
|
"""
|
||||||
if func is None:
|
if func is None:
|
||||||
|
@ -120,21 +124,15 @@ class EightBall:
|
||||||
self.questions[compiled] = (wrapped, self.keyword_pattern)
|
self.questions[compiled] = (wrapped, self.keyword_pattern)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
logger = logging.getLogger(__name__)
|
def is_question(phrase: str) -> bool:
|
||||||
|
|
||||||
|
|
||||||
def is_question(phrase: str) -> bool:
|
|
||||||
"""
|
"""
|
||||||
Method to check if a string is a question
|
Method to check if a string is a question
|
||||||
|
|
||||||
:param phrase str: the phrase to check
|
:param phrase str: the phrase to check
|
||||||
:return: bool if the phrase is a question or not
|
:return: bool if the phrase is a question or not
|
||||||
"""
|
"""
|
||||||
logger.debug("We are being called for '{}'".format(phrase))
|
|
||||||
compiled = re.compile(r'^[^\?]+\?\s*$')
|
compiled = re.compile(r'^[^\?]+\?\s*$')
|
||||||
if compiled.match(phrase):
|
if compiled.match(phrase):
|
||||||
logger.debug("Returning True")
|
|
||||||
return True
|
return True
|
||||||
logger.debug("Returning False")
|
|
||||||
return False
|
return False
|
||||||
|
|
|
@ -6,8 +6,7 @@ import yaml
|
||||||
def setup_logging(
|
def setup_logging(
|
||||||
default_path: str = None,
|
default_path: str = None,
|
||||||
default_level: int = logging.INFO,
|
default_level: int = logging.INFO,
|
||||||
env_key: str = 'LOG_CFG'
|
env_key: str = 'LOG_CFG'):
|
||||||
):
|
|
||||||
if default_path:
|
if default_path:
|
||||||
path = default_path
|
path = default_path
|
||||||
value = os.getenv(env_key, None)
|
value = os.getenv(env_key, None)
|
||||||
|
@ -18,5 +17,6 @@ def setup_logging(
|
||||||
config = yaml.safe_load(f.read())
|
config = yaml.safe_load(f.read())
|
||||||
logging.config.dictConfig(config)
|
logging.config.dictConfig(config)
|
||||||
else:
|
else:
|
||||||
_format = '%(asctime)s - %(levelname)s - %(filename)s:%(name)s.%(funcName)s:%(lineno)d - %(message)s'
|
_format = '%(asctime)s - %(levelname)s - %(filename)s:' \
|
||||||
|
'%(name)s.%(funcName)s:%(lineno)d - %(message)s'
|
||||||
logging.basicConfig(level=default_level, format=_format)
|
logging.basicConfig(level=default_level, format=_format)
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
import logging
|
import logging
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import types
|
||||||
|
import functools
|
||||||
import bottom
|
import bottom
|
||||||
|
|
||||||
|
|
||||||
|
@ -17,41 +19,46 @@ class Bot(bottom.Client):
|
||||||
realname: str = None,
|
realname: str = None,
|
||||||
channels: list = None) -> None:
|
channels: list = None) -> None:
|
||||||
super().__init__(host=host, port=port, ssl=ssl)
|
super().__init__(host=host, port=port, ssl=ssl)
|
||||||
self.logger = logging.getLogger(__class__.__name__)
|
self.logger = logging.getLogger(self.__class__.__name__)
|
||||||
self.logger.debug("Initializing...")
|
self.logger.debug("Initializing...")
|
||||||
self.nick = nick
|
self.nick = nick
|
||||||
self.user = user or self.nick
|
self.user = user or self.nick
|
||||||
self.realname = realname or self.nick
|
self.realname = realname or self.nick
|
||||||
self.channels = channels or []
|
self.channels = channels or []
|
||||||
|
self.pre_pub = []
|
||||||
self.on("ping", self.keepalive)
|
self.on("ping", self.keepalive)
|
||||||
self.on("CLIENT_CONNECT", self.on_connect)
|
self.on("CLIENT_CONNECT", self.on_connect)
|
||||||
|
self.on("PRIVMSG", self.privmsg)
|
||||||
|
self.on("NOTICE", self.notice)
|
||||||
|
|
||||||
async def keepalive(self, message: str = None, **kwargs: dict) -> None:
|
async def keepalive(self, message: str = None, **kwargs) -> None:
|
||||||
"""
|
"""
|
||||||
Essential keepalive method to pong the server back
|
Essential keepalive method to pong the server back
|
||||||
automagically everytime it pings
|
automagically everytime it pings
|
||||||
|
|
||||||
:param message str: the ping parameters
|
:param message str: the ping parameters
|
||||||
:param kwargs dict: for API compatibility
|
:param kwargs: for API compatibility
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
message = message or ""
|
message = message or ""
|
||||||
self.logger.debug("PONG {}".format(message))
|
self.logger.debug("PONG {}".format(message))
|
||||||
self.send("pong", message=message)
|
self.send("pong", message=message)
|
||||||
|
|
||||||
async def on_connect(self, **kwargs: dict) -> None:
|
async def on_connect(self, **kwargs) -> None:
|
||||||
"""
|
"""
|
||||||
Essential user information to send at the
|
Essential user information to send at the
|
||||||
beginning of the connection with the server
|
beginning of the connection with the server
|
||||||
|
|
||||||
:param kwargs dict: for API compatibility
|
:param kwargs: for API compatibility
|
||||||
:return: None
|
:return: None
|
||||||
"""
|
"""
|
||||||
self.logger.debug("We are being called")
|
self.logger.debug("We are being called")
|
||||||
self.logger.info("Connecting...")
|
self.logger.info("Connecting...")
|
||||||
self.logger.debug("We are sending NICK as {} to server ".format(self.nick))
|
self.logger.debug(
|
||||||
|
"We are sending NICK as {} to server ".format(self.nick))
|
||||||
self.send('NICK', nick=self.nick)
|
self.send('NICK', nick=self.nick)
|
||||||
self.logger.debug("We are sending USER {} {}".format(self.user, self.realname))
|
self.logger.debug(
|
||||||
|
"We are sending USER {} {}".format(self.user, self.realname))
|
||||||
self.send('USER', user=self.user,
|
self.send('USER', user=self.user,
|
||||||
realname=self.realname)
|
realname=self.realname)
|
||||||
|
|
||||||
|
@ -65,11 +72,44 @@ class Bot(bottom.Client):
|
||||||
# Cancel whichever waiter's event didn't come in
|
# Cancel whichever waiter's event didn't come in
|
||||||
for future in pending:
|
for future in pending:
|
||||||
future.cancel()
|
future.cancel()
|
||||||
self.logger.info("We are auto-joining channels {}".format(self.channels))
|
|
||||||
|
for func in self.pre_pub:
|
||||||
|
self.logger.debug("Running {}".format(func))
|
||||||
|
await self.loop.create_task(func(**kwargs))
|
||||||
|
|
||||||
|
self.logger.info(
|
||||||
|
"We are auto-joining channels {}".format(self.channels))
|
||||||
for channel in self.channels:
|
for channel in self.channels:
|
||||||
self.send('JOIN', channel=channel)
|
self.send('JOIN', channel=channel)
|
||||||
|
|
||||||
async def on_disconnect(self, **kwargs: dict) -> None:
|
def pre_public(self,
|
||||||
|
func: types.FunctionType = None,
|
||||||
|
**kwargs) -> types.FunctionType:
|
||||||
|
"""
|
||||||
|
This method will inject a function to be trigger before
|
||||||
|
the Bot module joins channels
|
||||||
|
|
||||||
|
:param func types.FunctionType: the method being decorated
|
||||||
|
:param kwargs: for API compatibility
|
||||||
|
:return func types.FunctionType: always return the function itself
|
||||||
|
"""
|
||||||
|
if func is None:
|
||||||
|
return functools.partial(self.pre_public)
|
||||||
|
|
||||||
|
wrapped = func
|
||||||
|
if not asyncio.iscoroutinefunction(wrapped):
|
||||||
|
wrapped = asyncio.coroutine(wrapped)
|
||||||
|
|
||||||
|
self.pre_pub.extend([wrapped])
|
||||||
|
return func
|
||||||
|
|
||||||
|
def privmsg(self, **kwargs) -> None:
|
||||||
|
self.logger.debug("PRIVMSG {}".format(kwargs))
|
||||||
|
|
||||||
|
def notice(self, **kwargs) -> None:
|
||||||
|
self.logger.debug("NOTICE {}".format(kwargs))
|
||||||
|
|
||||||
|
async def on_disconnect(self, **kwargs) -> None:
|
||||||
self.logger.debug("We are being called")
|
self.logger.debug("We are being called")
|
||||||
await self.disconnect()
|
await self.disconnect()
|
||||||
self.logger.debug("We are calling loop.stop()")
|
self.logger.debug("We are calling loop.stop()")
|
||||||
|
|
Loading…
Reference in a new issue