better permission management, some minor changes and fixes, impelemted ".say", even more cleanup
This commit is contained in:
parent
df1ca3ad2d
commit
644da76873
1 changed files with 70 additions and 58 deletions
128
main.py
128
main.py
|
@ -56,7 +56,7 @@ class log():
|
||||||
class pircbot():
|
class pircbot():
|
||||||
def __init__(self, nicknames, server, port=6667,
|
def __init__(self, nicknames, server, port=6667,
|
||||||
ident="pircbot", realname="pircbot", serverpasswd="",
|
ident="pircbot", realname="pircbot", serverpasswd="",
|
||||||
encodings=("utf-8", "latin-1"), admins="",
|
encodings=("utf-8", "latin-1"), users="",
|
||||||
query_type="", command_prefix=".",
|
query_type="", command_prefix=".",
|
||||||
parser_wait_time=0.1):
|
parser_wait_time=0.1):
|
||||||
self.server = server
|
self.server = server
|
||||||
|
@ -68,7 +68,7 @@ class pircbot():
|
||||||
self.ident = ident
|
self.ident = ident
|
||||||
self.realname = realname
|
self.realname = realname
|
||||||
|
|
||||||
self.admins = admins
|
self.users = users
|
||||||
self.cmdprefix = command_prefix
|
self.cmdprefix = command_prefix
|
||||||
self.query_type = query_type.upper()
|
self.query_type = query_type.upper()
|
||||||
|
|
||||||
|
@ -85,7 +85,7 @@ class pircbot():
|
||||||
self.die_event = Event()
|
self.die_event = Event()
|
||||||
self.ready = False
|
self.ready = False
|
||||||
|
|
||||||
self.mode_reply_to = None
|
self.mode_reply = {}
|
||||||
|
|
||||||
def connect(self):
|
def connect(self):
|
||||||
# connect
|
# connect
|
||||||
|
@ -178,7 +178,6 @@ class pircbot():
|
||||||
# parse params
|
# parse params
|
||||||
params = head
|
params = head
|
||||||
params.append(larg.strip())
|
params.append(larg.strip())
|
||||||
print(params)
|
|
||||||
|
|
||||||
log.show(log.DEBUG, " > %s" % rawline)
|
log.show(log.DEBUG, " > %s" % rawline)
|
||||||
|
|
||||||
|
@ -187,22 +186,23 @@ class pircbot():
|
||||||
self.send("PONG %s" % params[0])
|
self.send("PONG %s" % params[0])
|
||||||
# PRIVMSG and NOTICE
|
# PRIVMSG and NOTICE
|
||||||
elif command == "PRIVMSG" or command == "NOTICE":
|
elif command == "PRIVMSG" or command == "NOTICE":
|
||||||
if params[1].startswith(self.cmdprefix):
|
if params[1][0] == self.cmdprefix:
|
||||||
args = []
|
args = []
|
||||||
for v in params[1].lstrip(self.cmdprefix).split(" "):
|
for v in params[1][1:].split(" "):
|
||||||
if v!="": args.append(v)
|
if v!="": args.append(v)
|
||||||
sndline = self.on_command(command, prefix, origin, params[0], args[0].lower(), args[1:])
|
rp = self.on_command(command, prefix, origin, params[0], args[0].lower(), args[1:])
|
||||||
if sndline != None:
|
if rp not in (None, ""):
|
||||||
self.send(sndline)
|
self.reply(origin, params[0], rp, command)
|
||||||
# 221 (RPL_UMODEIS)
|
# 221 (RPL_UMODEIS)
|
||||||
elif command == "221" and self.mode_reply_to is not None:
|
elif command == "221" and self.mode_reply is not {}:
|
||||||
self.send("PRIVMSG %s :Modes are %s" % (self.mode_reply_to, params[1]))
|
self.query(self.mode_reply["to"], "Modes are %s" % params[1], self.mode_reply["type"])
|
||||||
|
self.mode_reply = {}
|
||||||
# INVITE
|
# INVITE
|
||||||
elif command == "INVITE":
|
elif command == "INVITE":
|
||||||
if self.is_admin(origin["mask"]):
|
if self.check_privileges(origin["mask"], command):
|
||||||
self.join(params[1])
|
self.join(params[1])
|
||||||
else:
|
else:
|
||||||
self.send("NOTICE %s :You can not force me to do that!" % origin["nick"])
|
self.query(origin["nick"], "You can not force me to do that!", "NOTICE")
|
||||||
# 001 (RPL_WELCOME)
|
# 001 (RPL_WELCOME)
|
||||||
elif command == "001":
|
elif command == "001":
|
||||||
self.user["mask"] = re.search(r" (\S+!\S+@\S+)$", rawline.split(" :", 1)[1]).groups()[0]
|
self.user["mask"] = re.search(r" (\S+!\S+@\S+)$", rawline.split(" :", 1)[1]).groups()[0]
|
||||||
|
@ -237,16 +237,18 @@ class pircbot():
|
||||||
return textstring.decode(self.encodings[0], 'ignore')
|
return textstring.decode(self.encodings[0], 'ignore')
|
||||||
|
|
||||||
|
|
||||||
# checks if a given user is listed in admins
|
# checks if a given user may execute a given command
|
||||||
def is_admin(self, user):
|
def check_privileges(self, usermask, command):
|
||||||
for admin in self.admins:
|
for user, privs in self.users.items():
|
||||||
if re.search(admin, user) != None:
|
if re.search(user, usermask, re.IGNORECASE) != None:
|
||||||
return True
|
if command.lower() in privs or "*" in privs:
|
||||||
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
# checks if s is a valid channel name
|
# checks if s is a valid channel name
|
||||||
def is_channel(self, s):
|
def is_channel(self, s):
|
||||||
return (True if s[0] in ('&', '#', '+', '!') else False)
|
return (True if s[0] in ('&', '#', '!') else False)
|
||||||
|
|
||||||
|
|
||||||
def exec_on_ready(self, command, retry_times=-1, interval=1):
|
def exec_on_ready(self, command, retry_times=-1, interval=1):
|
||||||
|
@ -281,15 +283,7 @@ class pircbot():
|
||||||
log.show(log.FATAL, e)
|
log.show(log.FATAL, e)
|
||||||
self.disconnect(send_quit=False)
|
self.disconnect(send_quit=False)
|
||||||
|
|
||||||
# replies to channel by PRIVMSG
|
# decides whether to reply to user or to channel
|
||||||
def chanmsg(self, channel, msg):
|
|
||||||
self.send("".join(("PRIVMSG ", channel, " :", msg)))
|
|
||||||
|
|
||||||
# replies to user by NOTICE or PRIVMSG
|
|
||||||
def query(self, nick, msg, in_query_type):
|
|
||||||
self.send("".join((self.query_type if self.query_type!="" else in_query_type, " ", nick, " :", msg)))
|
|
||||||
|
|
||||||
# decides whether to print to user or to channel based on the string origin
|
|
||||||
def reply(self, origin, source, msg, in_query_type):
|
def reply(self, origin, source, msg, in_query_type):
|
||||||
if self.is_channel(source):
|
if self.is_channel(source):
|
||||||
self.chanmsg(source, msg)
|
self.chanmsg(source, msg)
|
||||||
|
@ -299,6 +293,14 @@ class pircbot():
|
||||||
|
|
||||||
### irc command wrapper ###
|
### irc command wrapper ###
|
||||||
|
|
||||||
|
# replies to channel by PRIVMSG
|
||||||
|
def chanmsg(self, channel, msg):
|
||||||
|
self.send("".join(("PRIVMSG ", channel, " :", msg)))
|
||||||
|
|
||||||
|
# replies to user by NOTICE or PRIVMSG
|
||||||
|
def query(self, nick, msg, in_query_type):
|
||||||
|
self.send("".join((self.query_type if self.query_type!="" else in_query_type, " ", nick, " :", msg)))
|
||||||
|
|
||||||
def nick(self, nick):
|
def nick(self, nick):
|
||||||
self.exec_on_ready("".join(('self.send("JOIN %s" % "', channel, '")')))
|
self.exec_on_ready("".join(('self.send("JOIN %s" % "', channel, '")')))
|
||||||
|
|
||||||
|
@ -308,11 +310,11 @@ class pircbot():
|
||||||
def part(self, channel):
|
def part(self, channel):
|
||||||
self.exec_on_ready("".join(('self.send("PART %s" % "', channel, '")')))
|
self.exec_on_ready("".join(('self.send("PART %s" % "', channel, '")')))
|
||||||
|
|
||||||
def set_mode(self, modes):
|
def set_mode(self, modes, target=""):
|
||||||
self.exec_on_ready("".join(('self.send("MODE %s :%s" % (self.user["nick"], "', modes, '"))')))
|
self.exec_on_ready("".join(('self.send("MODE %s :%s" % (', ''.join(('"', target, '"')) if target != "" else 'self.user["nick"]', ', "', modes, '"))')))
|
||||||
|
|
||||||
def get_modes(self):
|
def get_modes(self, target=""):
|
||||||
self.exec_on_ready("".join(('self.send("MODE %s" % self.user["nick"])')))
|
self.exec_on_ready("".join(('self.send("MODE %s" % ', ''.join(('"', target, '"')) if target != "" else 'self.user["nick"]', ')')))
|
||||||
|
|
||||||
### handler ###
|
### handler ###
|
||||||
|
|
||||||
|
@ -331,36 +333,42 @@ class pircbot():
|
||||||
# hello
|
# hello
|
||||||
if command == "hello":
|
if command == "hello":
|
||||||
greeting = "".join(("Hi " + origin["nick"] +"!"))
|
greeting = "".join(("Hi " + origin["nick"] +"!"))
|
||||||
self.reply(origin, source, greeting, in_query_type)
|
return greeting
|
||||||
|
# say
|
||||||
|
if command == "say":
|
||||||
|
return " ".join(params)
|
||||||
# join <channel>
|
# join <channel>
|
||||||
elif command == "join" and len(params)>0:
|
elif command == "join":
|
||||||
if self.is_admin(origin["mask"]): self.join(params[0])
|
if len(params)>0:
|
||||||
else: return "PRIVMSG %s :You cannot do that!" % origin["nick"]
|
if self.check_privileges(origin["mask"], command): self.join(params[0])
|
||||||
|
else: self.query(origin["nick"], "You cannot do that!", in_query_type)
|
||||||
# part <channel>
|
# part <channel>
|
||||||
elif command == "part" and len(params)>0:
|
elif command == "part":
|
||||||
if self.is_admin(origin["mask"]): self.part(params[0])
|
if len(params)>0:
|
||||||
else: return "PRIVMSG %s :You cannot do that!" % origin["nick"]
|
if self.check_privileges(origin["mask"], command): self.part(params[0])
|
||||||
|
else: self.query(origin["nick"], "You cannot do that!", in_query_type)
|
||||||
# mode ±<modes>
|
# mode ±<modes>
|
||||||
elif command == "mode":
|
elif command == "mode":
|
||||||
if self.is_admin(origin["mask"]):
|
if self.check_privileges(origin["mask"], command):
|
||||||
if len(params) > 0:
|
if len(params)==0:
|
||||||
self.set_mode(params[0])
|
self.mode_reply["to"] = origin["nick"]
|
||||||
else:
|
self.mode_reply["type"] = in_query_type
|
||||||
self.mode_reply_to = origin["nick"]
|
|
||||||
self.get_modes()
|
self.get_modes()
|
||||||
else: return "PRIVMSG %s :You cannot do that!" % origin["nick"]
|
else:
|
||||||
|
self.set_mode(" ".join(params) if len(params)>0 else params)
|
||||||
|
else: self.query(origin["nick"], "You cannot do that!", in_query_type)
|
||||||
# die [<quitmsg>]
|
# die [<quitmsg>]
|
||||||
elif command == "die":
|
elif command == "die":
|
||||||
if self.is_admin(origin["mask"]):
|
if self.check_privileges(origin["mask"], command):
|
||||||
self.disconnect("".join(params) if len(params)>0 else "".join((origin["nick"], " shot me, dying now... Bye...")))
|
self.disconnect("".join(params) if len(params)>0 else "".join((origin["nick"], " shot me, dying now... Bye...")))
|
||||||
else: return "PRIVMSG %s :Go die yourself!" % origin["nick"]
|
else: self.query(origin["nick"], "Go die yourself!", in_query_type)
|
||||||
else:
|
else:
|
||||||
replies = [
|
replies = [
|
||||||
("PRIVMSG %s :What? \"%s\" is not a command!", 15),
|
("What? \"%s\" is not a command!", 15),
|
||||||
("PRIVMSG %s :%s? What's that?", 3),
|
("%s? What's that?", 3),
|
||||||
("PRIVMSG %s :Sorry, I don't know how to %s...", 1)
|
("Sorry, I don't know how to %s...", 1)
|
||||||
]
|
]
|
||||||
return choice([val for val, cnt in replies for i in range(cnt)]) % (origin["nick"], command)
|
self.query(origin["nick"], choice([val for val, cnt in replies for i in range(cnt)]) % (command), in_query_type)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -379,7 +387,7 @@ def main():
|
||||||
try:
|
try:
|
||||||
bot = pircbot(nicknames=NICKNAMES, ident=IDENT, realname=REALNAME,
|
bot = pircbot(nicknames=NICKNAMES, ident=IDENT, realname=REALNAME,
|
||||||
server=SERVER, port=PORT, serverpasswd=SERVERPASSWD,
|
server=SERVER, port=PORT, serverpasswd=SERVERPASSWD,
|
||||||
encodings=ENCODINGS, admins=ADMINS,
|
encodings=ENCODINGS, users=USERS,
|
||||||
query_type=QUERY_TYPE, command_prefix=COMMAND_PREFIX,
|
query_type=QUERY_TYPE, command_prefix=COMMAND_PREFIX,
|
||||||
parser_wait_time=PARSER_WAIT_TIME)
|
parser_wait_time=PARSER_WAIT_TIME)
|
||||||
bot.connect()
|
bot.connect()
|
||||||
|
@ -425,7 +433,7 @@ if __name__ == '__main__':
|
||||||
# Command for registering with nickserv, without leading slash.
|
# Command for registering with nickserv, without leading slash.
|
||||||
NICKSERVCMD = ""
|
NICKSERVCMD = ""
|
||||||
|
|
||||||
MODES = "+B"
|
MODES = "+iB"
|
||||||
|
|
||||||
|
|
||||||
# The Server name to connect to. Duh!
|
# The Server name to connect to. Duh!
|
||||||
|
@ -449,15 +457,19 @@ if __name__ == '__main__':
|
||||||
ENCODINGS = ['utf-8', 'latin-1', 'iso-8859-1', 'cp1252']
|
ENCODINGS = ['utf-8', 'latin-1', 'iso-8859-1', 'cp1252']
|
||||||
|
|
||||||
|
|
||||||
# List of users (hostmasks, will be parsed as regex) who can do important stuff,
|
# List of users (hostmasks as regex) and the commands they are allowed to execute.
|
||||||
# like joining and parting channels and shutting down the bot.
|
# "*" Can be used instead of commands to allow every command.
|
||||||
ADMINS = ["Fanir\!.*"]
|
# All command names should be lowercase.
|
||||||
|
USERS = {
|
||||||
|
"Fanir\!fanir@.*": ["*"],
|
||||||
|
"\!@some weird user that cannot exist": ["join", "part", "invite"],
|
||||||
|
}
|
||||||
|
|
||||||
# The prefix for commands for the bot.
|
# The prefix for commands for the bot.
|
||||||
COMMAND_PREFIX = "."
|
COMMAND_PREFIX = "."
|
||||||
|
|
||||||
# Which way shouldbe used to speak to users?
|
# Which way should be used to speak to users?
|
||||||
# "" means, the type of the incomming message should be used.
|
# "" means the type of the incoming message should be used.
|
||||||
# One of: "NOTICE", "PRIVMSG", ""
|
# One of: "NOTICE", "PRIVMSG", ""
|
||||||
QUERY_TYPE = ""
|
QUERY_TYPE = ""
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue