* Refactoring code

* No longer using kwargs to send data, it is all parametrized now
* API calls to msg, action, join, part, quit have been parametrized
* New API call to notice
This commit is contained in:
Elijah Lazkani 2018-03-03 12:44:27 -05:00
parent 626dc04a18
commit bf76c3327c
4 changed files with 201 additions and 150 deletions

View file

@ -206,52 +206,53 @@ class Admin:
:param kwargs: for API compatibility
:return: None
"""
self.logger.debug("We have received nick={} target={} "
"message={} kwargs={}".format(
nick, target, message, kwargs))
self.logger.debug(
"We have received nick={}, target={}, message={}, kwargs={}".format(
nick, target, message, kwargs))
# Set the admin flag
admin = self.is_admin(nick, kwargs['host'])
self.logger.debug(
"We are checking to see if {} is an admin".format(nick))
if admin:
kwargs['is_admin'] = True
kwargs['level'] = self.admins[admin]['level']
is_admin = True
level = self.admins[admin]['level']
else:
kwargs['is_admin'] = False
if kwargs.get('level', None) is not None:
del kwargs['level']
is_admin = False
level = 0
# TODO: fix
self.logger.debug("We are parsing the message sent by {}".format(nick))
if self.HELP.match(message):
self.admin_help(nick, target, message, **kwargs)
await self.admin_help(nick, target, message, is_admin, **kwargs)
elif self.LOGIN.match(message):
await self.log_in(nick, target, message, **kwargs)
await self.log_in(nick, target, message, is_admin, **kwargs)
elif self.LOGOUT.match(message):
await self.log_out(nick, target, **kwargs)
await self.log_out(nick, target, is_admin, **kwargs)
elif self.PASSWD.match(message):
await self.passwd(nick, target, message, **kwargs)
await self.passwd(nick, target, message, is_admin, **kwargs)
elif self.ADD.match(message):
await self.admin_add(nick, target, message, **kwargs)
await self.admin_add(nick, target, message, is_admin, level, **kwargs)
elif self.RM.match(message):
await self.admin_rm(nick, target, message, **kwargs)
await self.admin_rm(nick, target, message, is_admin, level, **kwargs)
elif self.LIST.match(message):
self.admin_list(nick, target, **kwargs)
await self.admin_list(nick, target, is_admin, **kwargs)
self.logger.debug("We are modifying kwargs")
kwargs['nick'] = nick
kwargs['target'] = target
kwargs['message'] = message
self.logger.debug(
"We are triggering a new event called ADMIN with {}".format(
kwargs))
self.client.trigger('ADMIN', **kwargs)
"We are triggering a new event called ADMIN with "
"nick={}, target={}, message={}, is_admin={}, level={}, "
"**kwargs={}".format(nick, target, message, is_admin, level,
kwargs))
self.client.trigger('ADMIN', nick=nick, target=target,
message=message, is_admin=is_admin,
level=level, **kwargs)
def admin_help(self,
nick: str,
target: str,
message: str,
**kwargs) -> None:
async def admin_help(self,
nick: str,
target: str,
message: str,
is_admin: bool,
**kwargs) -> None:
"""
This method will reply back to the user a help manual of the
available commands
@ -269,57 +270,59 @@ class Admin:
:param nick str: the nickname of the caller
:param target str: the target where the message was sent to
:param message str: the message sent to the target
:param is_admin bool: the user is an admin
:param kwargs: for API compatibility
:return: None
"""
if target == self.client.nick:
self.logger.debug(
"We have received a help request from {}".format(nick))
if kwargs.get("is_admin", None) is True:
if is_admin:
match_help = self.HELP.match(message)
match_help_cmd = self.HELP_CMD.match(message)
kwargs['target'] = nick
_target = nick
if match_help_cmd:
if len(match_help_cmd.groups()) == 1:
if match_help_cmd.group(1) == 'login':
kwargs['message'] = \
_message = \
"login <user> <password> <level> - Login as " \
"an admin with your account"
self.client.msg(**kwargs)
await self.client.msg(target=_target, message=_message)
if match_help_cmd.group(1) == 'logout':
kwargs['message'] = \
_message = \
"logout <user> - Log out from your account"
self.client.msg(**kwargs)
await self.client.msg(target=_target, message=_message)
if match_help_cmd.group(1) == 'passwd':
kwargs['message'] = \
_message = \
"passwd <new password> - Change your" \
" account\'s password"
self.client.msg(**kwargs)
await self.client.msg(target=_target, message=_message)
if match_help_cmd.group(1) == 'add':
kwargs['message'] = \
_message = \
"add <user> <password> <level> - adds" \
" an admin account to the list of admins" \
" with provided level"
self.client.msg(**kwargs)
await self.client.msg(target=_target, message=_message)
if match_help_cmd.group(1) == 'rm':
kwargs['message'] = \
_message = \
"rm <user> - removes an admin from the list" \
" of admins"
self.client.msg(**kwargs)
await self.client.msg(target=_target, message=_message)
if match_help_cmd.group(1) == 'list':
kwargs['message'] = "list - lists all the admins"
self.client.msg(**kwargs)
_message = "list - lists all the admins"
await self.client.msg(target=_target, message=_message)
elif match_help:
kwargs['message'] = "help [command]"
self.client.msg(**kwargs)
kwargs['message'] = \
_message = "help [command]"
await self.client.msg(target=_target, message=_message)
_message = \
"commands: login logout passwd add rm list"
self.client.msg(**kwargs)
await self.client.msg(target=_target, message=_message)
async def log_in(self,
nick: str,
target: str,
message: str,
is_admin: bool,
**kwargs) -> None:
"""
This method is called when a user attempts to login to the bot.
@ -334,6 +337,7 @@ class Admin:
:param nick str: the nickname of the caller
:param target str: location the message was sent to
:param message str: message coming from `nick`
:param is_admin bool: the user is an admin
:param kwargs: for API compatibility
:return: None
"""
@ -344,17 +348,16 @@ class Admin:
if user:
login = user['LOGIN']
if login.match(self.hash_pass(message)):
if kwargs.get('is_admin', None) is True and \
match.group(1) != self.is_admin(nick,
kwargs['host']):
if is_admin and \
match.group(1) != self.is_admin(nick, kwargs['host']):
self.logger.warn(
"We detected that {} is already logged in as"
" different user, logging him out".format(nick))
await self.log_out(nick, target, **kwargs)
if match.group(1) == self.is_admin(nick, kwargs['host']):
kwargs['target'] = nick
kwargs['message'] = "{} you are already logged in" \
"...".format(nick)
_target = nick
_message = "{} you are already logged in" \
"...".format(_target)
self.logger.warn("We detected that {} is already "
"logged in, notifying".format(nick))
else:
@ -363,18 +366,23 @@ class Admin:
str(nick)
self.admins[match.group(1)]['logged_in_hostname'] = \
str(kwargs['host'])
kwargs['is_admin'] = True
kwargs['target'] = nick
kwargs['message'] = "{}, you are logged in to {}" \
" successfully".format(
nick, match.group(1))
is_admin = True
_target = nick
_message = "{}, you are logged in to {}" \
" successfully".format(
_target, match.group(1))
self.logger.debug("We have logged in {} successfully, "
"notifying".format(nick))
self.client.msg(**kwargs)
"notifying".format(_target))
await self.client.msg(target=_target, message=_message)
self.logger.debug("We are calling save_config()")
await self.save_config()
async def log_out(self, nick: str, target: str, **kwargs) -> None:
async def log_out(self,
nick: str,
target: str,
is_admin: bool,
**kwargs) -> None:
"""
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
@ -386,24 +394,26 @@ class Admin:
:param nick str: the nickname of the caller
:param target str: location where the message was sent to
:param is_admin bool: the user is an admin
:param kwargs: for API compatibility
:return: None
"""
if target == self.client.nick:
self.logger.debug("We are being called by {}".format(nick))
if kwargs.get('is_admin', None) is True:
if is_admin:
admin = self.is_admin(nick, kwargs['host'])
if admin:
self.admins[admin]['logged_in'] = False
self.admins[admin]['logged_in_nick'] = None
self.admins[admin]['logged_in_hostname'] = None
kwargs['is_admin'] = False
kwargs['target'] = nick
kwargs['message'] = "{}, you are logged out of" \
" successfully".format(nick, admin)
is_admin = False
_target = nick
_message = "{}, you are logged out of " \
"successfully".format(_target, admin)
self.logger.debug("We have successfully logged {}"
" out, notifying".format(nick))
self.client.msg(**kwargs)
" out, notifying".format(_target))
await self.client.msg(target=_target, message=_message)
self.logger.debug("We are calling save_config")
await self.save_config()
@ -411,6 +421,7 @@ class Admin:
nick: str,
target: str,
message: str,
is_admin: bool,
**kwargs) -> None:
"""
This method will change the password to the administrator currently
@ -421,12 +432,13 @@ class Admin:
:param nick str: the nickname of the caller
:param target str: the target where the message was sent to
:param message str: the message sent to target
:param is_admin bool: the user is an admin
:param kwargs: for API compatibility
:return: None
"""
if target == self.client.nick:
self.logger.debug("We are being called by {}".format(nick))
if kwargs.get('is_admin', None) is True:
if is_admin:
match = self.PASSWD.match(message)
if len(match.groups()) == 1:
admin = self.is_admin(nick, kwargs['host'])
@ -434,24 +446,26 @@ class Admin:
self.admins[admin]['LOGIN'] = re.compile(
r'^login\s+({})\s+({})\s*$'.format(
admin, re.escape(self.hash(match.group(1)))))
kwargs['target'] = nick
kwargs['message'] = \
_target = nick
_message = \
'{}, password for {} has been successfully' \
' changed...'.format(nick, admin)
' changed...'.format(_target, admin)
self.logger.debug(
"We have successfully changed {}'s password,"
" notifying".format(nick))
self.client.msg(**kwargs)
" notifying".format(_target))
await self.client.msg(target=_target, message=_message)
self.logger.debug("We are calling save_config()")
await self.save_config()
kwargs['target'] = self.client.nick
self.logger.debug("We are logging {} out".format(nick))
await self.log_out(nick, **kwargs)
_target = self.client.nick
self.logger.debug("We are logging {} out".format(_target))
await self.log_out(nick=nick, target=_target, is_admin=is_admin, **kwargs)
async def admin_add(self,
nick: str,
target: str,
message: str,
is_admin: bool,
level: int,
**kwargs) -> None:
"""
This method will add an administrator to the list of administrators
@ -462,39 +476,42 @@ class Admin:
:param nick str: the nickname of the caller
:param target str: location where the message was sent to
:param message str: the message being sent to the target
:param is_admin bool: the user is an admin
:param level int: the access level of the user being added
:param kwargs: for API compatibility
:return: None
"""
if target == self.client.nick:
self.logger.debug("We are being called by {}".format(nick))
if kwargs.get('is_admin', None) is True:
if is_admin:
match = self.ADD.match(message)
if len(match.groups()) == 3:
if self.admins.get(match.group(1), None) is None:
kwargs['target'] = nick
level = self.level_up(kwargs['level'],
_target = nick
level = self.level_up(level,
int(match.group(3)))
kwargs['message'] = "{} has been added with " \
"level {}...".format(
match.group(1), level)
_message = "{} has been added with " \
"level {}...".format(match.group(1), level)
self.logger.debug(
"We have added {} with level {}, notifying"
" {}".format(match.group(1), level, nick))
" {}".format(match.group(1), level, _target))
await self.add_admin(
match.group(1), match.group(2), level)
else:
kwargs['target'] = nick
kwargs['message'] = "{} has already been added" \
"...".format(match.group(1))
_target = nick
_message = "{} has already been added" \
"...".format(match.group(1))
self.logger.warn(
"We detected that {} has already been added,"
" notifying {}".format(match.group(1), nick))
self.client.msg(**kwargs)
" notifying {}".format(match.group(1), _target))
await self.client.msg(target=_target, message=_message)
async def admin_rm(self,
nick: str,
target: str,
message: str,
is_admin: bool,
level: int,
**kwags) -> None:
"""
This method will remove an administrator from the list of
@ -507,56 +524,59 @@ class Admin:
:param nick str: the nickname of the caller
:param target str: location where the message was sent to
:param message str: the message being sent to the target
:param is_admin bool: the user is an admin
:param level int: the access level of the user being removed
:param kwags: for API compatibility
:return: None
"""
if target == self.client.nick:
self.logger.debug("We are being called by {}".format(nick))
if kwags.get('is_admin', None) is True:
if is_admin:
match = self.RM.match(message)
if len(match.groups()) == 1:
if self.admins.get(match.group(1), None) is None:
kwags['target'] = nick
kwags['message'] = "{} is not on the list" \
"...".format(match.group(1))
_target = nick
_message = "{} is not on the list" \
"...".format(match.group(1))
self.logger.warn("admin_rm() ")
else:
if 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['message'] = "{} has been removed" \
"...".format(match.group(1))
if level > self.admins[match.group(1)]['level'] \
or (level == 1000 and self.admins[match.group(1)]['level']
and level == self.admins[match.group(1)]['level']):
_target = nick
_message = "{} has been removed" \
"...".format(match.group(1))
self.logger.debug("We removed {} successfully,"
" notifying {}".format(
match.group(1), nick))
match.group(1), _target))
await self.rm_admin(match.group(1))
else:
kwags['target'] = nick
kwags['message'] = "{}, you do not have enough" \
" access to delete {}".format(
nick, match.group(1))
_target = nick
_message = "{}, you do not have enough" \
" access to delete {}".format(_target, match.group(1))
self.logger.warn(
"We detected that {0} does not have enough"
" access to delete {1}, notifying {0}".format(
nick, match.group(1)))
self.client.msg(**kwags)
_target, match.group(1)))
await self.client.msg(target=_target, message=_message)
def admin_list(self, nick: str, target: str, **kwargs) -> None:
async def admin_list(self,
nick: str,
target: str,
is_admin: bool,
**kwargs) -> None:
"""
This method returns to the admin the admin list
:param nick str: the nickname of the caller
:param target str: location where the message was sent to
:param is_admin bool: the user is an admin
:param kwargs: for API compatibility
:return: None
"""
if target == self.client.nick:
self.logger.debug("We are being called by {}".format(nick))
if kwargs.get('is_admin', None) is True:
if is_admin:
admins = ""
for key, _ in self.admins.items():
if admins:
@ -565,13 +585,13 @@ class Admin:
else:
admins = "{}({})".format(
key, self.admins[key]['level'])
kwargs['target'] = nick
kwargs['message'] = "List of Administrators:"
self.client.msg(**kwargs)
kwargs['message'] = admins
_target = nick
_message = "List of Administrators:"
await self.client.msg(target=_target, message=_message)
_message = admins
self.logger.debug("We are returning admin list page to"
" {}".format(kwargs))
self.client.msg(**kwargs)
" {}".format(_target))
await self.client.msg(target=_target, message=_message)
def is_admin(self, user: str, host: str):
"""

View file

@ -22,18 +22,25 @@ class AdminCmd:
self.services = {}
admin.client.on("ADMIN")(self._handle)
def _handle(self, target: str, message: str, **kwargs) -> None:
def _handle(self,
nick: str,
target: str,
message: str,
is_admin: bool,
**kwargs) -> None:
"""
client callback on event trigger
:param nick str: the nickname of the user triggering the ADMIN event
:param target str: the target the message was sent to
:param message str: the message sent to the target
:param is_admin bool: the user is an admin
:param kwargs: for API compatibility
:return: None
"""
if bool(kwargs.get('is_admin', None)):
if is_admin:
self.logger.debug(
"We are being called by {}".format(kwargs['nick']))
"We are being called by {}".format(nick))
for regex, (func, pattern) in self.services.items():
match = regex.match(message)
if match:

View file

@ -48,19 +48,27 @@ async def plugins(bot: robot.Bot):
@admin_cmd.on_command("part")
async def part(target, message, **kwargs):
await bot.part(channel=message)
_target = message.split(' ')[0]
_message = " ".join(message.split(' ')[1:])
await bot.part(channel=_target, message=_message)
@admin_cmd.on_command("msg")
async def msg(target, message, **kwargs):
kwargs['target'] = message.split(' ')[0]
kwargs['message'] = " ".join(message.split(' ')[1:])
await bot.msg(**kwargs)
_target = message.split(' ')[0]
_message = " ".join(message.split(' ')[1:])
await bot.msg(target=_target, message=_message)
@admin_cmd.on_command("action")
async def action(target, message, **kwargs):
kwargs['target'] = message.split(' ')[0]
kwargs['message'] = " ".join(message.split(' ')[1:])
await bot.action(**kwargs)
_target = message.split(' ')[0]
_message = " ".join(message.split(' ')[1:])
await bot.action(target=_target, message=_message)
@admin_cmd.on_command("notice")
async def msg(target, message, **kwargs):
_target = message.split(' ')[0]
_message = " ".join(message.split(' ')[1:])
await bot.notice(target=_target, message=_message)
@admin_cmd.on_command("quit")
async def quit(target, message, **kwargs):

View file

@ -46,8 +46,8 @@ class Bot(bottom.Client):
self.global_timestamp_queue = []
self.on("ping", self.keepalive)
self.on("CLIENT_CONNECT", self.on_connect)
self.on("PRIVMSG", self.privmsg)
self.on("NOTICE", self.notice)
self.on("PRIVMSG", self.on_privmsg)
self.on("NOTICE", self.on_notice)
async def keepalive(self, message: str = None, **kwargs) -> None:
"""
@ -95,6 +95,9 @@ class Bot(bottom.Client):
self.logger.debug("Running {}".format(func))
await self.loop.create_task(func(**kwargs))
# Wait 5 seconds to make sure everything synched up
await asyncio.sleep(5)
self.logger.info(
"We are auto-joining channels {}".format(self.channels))
for channel in self.channels:
@ -213,62 +216,75 @@ class Bot(bottom.Client):
await self.global_buffer(command, **kwargs)
async def msg(self, **kwargs) -> None:
async def msg(self, target: str, message: str, **kwargs) -> None:
"""
This method will send a private message to the messages buffer
:param kwargs: the information required for the command
:param target str: the target for the message to be sent to
:param message str: the message to send to target
:param kwargs: any other parameters that needs to be sent
:return None
"""
await self.msg_buffer("PRIVMSG", **kwargs)
await self.msg_buffer("PRIVMSG", target=target, message=message, **kwargs)
async def action(self, **kwargs) -> None:
async def action(self, target: str, message: str, **kwargs) -> None:
"""
This method will send an action message to the messages buffer
:param kwargs: the information required for the command
:param target str: the target for the message to be sent to
:param message str: the message to send to target
:param kwargs: any other parameters that needs to be sent
:return None
"""
if kwargs.get('message', None):
kwargs['message'] = \
"\x01ACTION {}\x01".format(kwargs['message'])
_message = "\x01ACTION {}\x01".format(message)
await self.msg_buffer("PRIVMSG", target=target, message=_message, **kwargs)
await self.msg_buffer("PRIVMSG", **kwargs)
else:
# TODO: better error handling for the future
self.logger.error("ACTION does not have a message\n{}".format(kwargs))
async def notice(self, target: str, message: str, **kwargs) -> None:
"""
This method will send a notice message to the messages buffer
async def join(self, **kwargs) -> None:
:param target str: the target for the notice to be sent to
:param message str: the message to send to target
:param kwargs: any other parameters that needs to be sent
:return None
"""
await self.msg_buffer("NOTICE", target=target, message=message, **kwargs)
async def join(self, channel: str, **kwargs) -> None:
"""
This method will send a join command to the action buffer
:param kwargs: the information required for the command
:param channel str: the channel to join
:param kwargs: any other parameters that needs to be sent
:return None
"""
await self.action_buffer("JOIN", **kwargs)
await self.action_buffer("JOIN", channel=channel, **kwargs)
async def part(self, **kwargs) -> None:
async def part(self, channel: str, message: str = None, **kwargs) -> None:
"""
This method will send a part command to the action buffer
:param kwargs: the information required for the command
:param channel str: the channel to part
:param message str: the message to send on part
:param kwargs: any other parameters that needs to be sent
:return None
"""
await self.action_buffer("PART", **kwargs)
await self.action_buffer("PART", channel=channel, message=message, **kwargs)
async def quit(self, **kwargs) -> None:
async def quit(self, message: str, **kwargs) -> None:
"""
This method will send a quit command to the action buffer
:param kwargs: the information required for the command
:param message str: the message to send on quit
:param kwargs: any other parameters that needs to be sent
:return None
"""
await self.action_buffer("QUIT", **kwargs)
await self.action_buffer("QUIT", message=message, **kwargs)
def privmsg(self, **kwargs) -> None:
def on_privmsg(self, **kwargs) -> None:
self.logger.debug("PRIVMSG {}".format(kwargs))
def notice(self, **kwargs) -> None:
def on_notice(self, **kwargs) -> None:
self.logger.debug("NOTICE {}".format(kwargs))
async def on_disconnect(self, **kwargs) -> None: