idk, allowing to disable commands, moved all except eval/exec/reload into commands module, swapped around utils' argument order to funzies, idk what else, lol

This commit is contained in:
jan6 2021-10-04 00:36:22 +03:00
parent 405b756d88
commit 85d7a3e4d2
5 changed files with 150 additions and 82 deletions

44
bot.py
View File

@ -1,31 +1,37 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
import ircstates,socket,ssl import ircstates, socket, ssl
from config import * from config import *
from stuff import stuff from stuff import stuff
from util import Util from util import Util
class bot:
server=ircstates.Server(config.server.name)
host=config.server.host
port=config.server.port
if __name__==__module__=="__main__": class bot:
server = ircstates.Server(config.server.name)
host = config.server.host
port = config.server.port
if __name__ == __module__ == "__main__":
@classmethod @classmethod
def __init__(self): def __init__(self):
if config.server.ssl: if config.server.ssl:
with socket.create_connection((self.host, self.port)) as sock_raw: with socket.create_connection((self.host, self.port)) as sock_raw:
ctx=ssl.create_default_context() ctx = ssl.create_default_context()
with ctx.wrap_socket(sock_raw, server_hostname=self.host) as sock: with ctx.wrap_socket(sock_raw, server_hostname=self.host) as sock:
try:
util=Util(sock,config)
stuff(self,sock)
except KeyboardInterrupt: util.quit("^C")
else:
with socket.create_connection((self.host, self.port)) as sock:
try: try:
util=Util(sock,config) util = Util(config, sock)
stuff(self,sock) stuff(self, sock)
except KeyboardInterrupt: util.quit("^C") except KeyboardInterrupt:
util.quit("^C")
else:
with socket.create_connection((self.host, self.port)) as sock:
try:
util = Util(config, sock)
stuff(self, sock)
except KeyboardInterrupt:
util.quit("^C")
print("starting bot...") print("starting bot...")
bot() bot()

View File

@ -1,50 +1,107 @@
from util import Util
class Command: class Command:
def __init__(self,sock,config): def __init__(self,config):
self.sock=sock
self.config=config self.config=config
self.util=Util(sock,config) self.commands=[]
def mesg(self,msg): self.util.mesg(msg) def mesg(self,msg): self.util.mesg(msg)
def err_perm(self,level="admin"): mesg("Error: insufficient privileges, you lack {level} access") def err_perm(self,level="admin"): self.mesg(f"Error: insufficient privileges, you lack {level} access")
def exec_cmd(self,command,extra=[None]): def adm(func,*args, **kwargs):
if extra!=[None]: global adm_cmds
eval(f"self.{command}(self.prefix,self.cmd,self.pm,self.line,self.admin,extra)") try:
else: if func.__name__ not in adm_cmds and func.__name__!="_": adm_cmds.append(func.__name__)
eval(f"self.{command}(self.prefix,self.cmd,self.pm,self.line,self.admin)") except NameError:
def echo(self,prefix,cmd,pm,line,admin): adm_cmds=[]
if func.__name__ not in adm_cmds and func.__name__!="_": adm_cmds.append(func.__name__)
def _(self,*args, **kwargs):
if(func.__name__=="help"):
self.admin_commands=adm_cmds
#func.admin_commands=adm_cmds
if not self.admin:
self.err_perm()
else:
# return func(self)
return func(self,self.prefix,self.line,self.pm,self._line,self.admin,self.mesg)
return _
def cmd(func,*args, **kwargs):
global cmds
try:
if func.__name__ not in cmds and func.__name__!="_": cmds.append(func.__name__)
except NameError:
cmds=[]
if func.__name__ not in cmds and func.__name__!="_": cmds.append(func.__name__)
def _(self,*args, **kwargs):
if(func.__name__=="help"):
self.commands=cmds
#func.commands=cmds
if(func.__name__ not in self.config.cmd.disabled):
return func(self,self.prefix,self.line,self.pm,self._line,self.admin,self.mesg)
return _
def preq_cmd(self): #command prequisites / triggers
cmd=self.line
if cmd=="help" or cmd.startswith("help "):
command="help"
elif cmd.startswith("echo "):
command="echo"
elif cmd=="dbg" or cmd.startswith("dbg "):
command="dbg"
elif cmd=="dbg2" or cmd.startswith("dbg2 "):
command="dbg2"
else:return
if command not in self.config.cmd.disabled:
eval(f"self.{command}()")
@adm
def quit(self,prefix,cmd,pm,line,admin,mesg):
if admin and (cmd=="q" or cmd=="quit"):
self.util.quit()
elif is_adm and (cmd.startswith("q ") or cmd.startswith("quit ")):
self.util.quit(cmd.split(" ",1)[1])
@adm
def dbg2(self,prefix,cmd,pm,line,admin,mesg):
mesg(dir(self))
@adm
def dbg(self,prefix,cmd,pm,line,admin,mesg):
"""temporary debug command, subject to change A LOT""";
mesg(dir())
@cmd
def echo(self,prefix,cmd,pm,line,admin,mesg):
"""simple echo command""" """simple echo command"""
self.util.mesg(cmd.split(" ",1)[1]) mesg(cmd.split(" ",1)[1])
def help(self,prefix,cmd,pm,line,admin,extra): @cmd
mesg=self.mesg def help(self,prefix,cmd,pm,line,admin,mesg):
prefixes="\""+"\", \"".join(extra[0])+"\"" global adm_cmds
enabled_commands=extra[1] global cmds
admin_commands=", ".join(extra[2]) disabled_commands=self.config.cmd.disabled
try: topic=extra[3] admin_commands,commands=[],[]
for i in ["exec","eval","reload"]:
if i not in adm_cmds:
adm_cmds.append(i)
for i in adm_cmds:
if i not in disabled_commands:
admin_commands.append(i)
for i in cmds:
if i not in admin_commands and i not in disabled_commands:
commands.append(i)
prefixes="\""+"\", \"".join(self.config.cmd.prefixes)+"\""
admin_commands=", ".join(admin_commands)
try: topic=cmd.split(" ",1)[1]
except IndexError: topic=None except IndexError: topic=None
try: self_nick=extra[4] try: self_nick=self.self_nick
except IndexError: self_nick=None except IndexError: self_nick=None
abs_topics={ abs_topics={
"prefixes":f"available prefixes are {prefixes} or \"{self_nick}\"" "prefixes":f"available prefixes are {prefixes} or \"{self_nick}\""
} }
if topic==None: if topic==None:
mesg(f"available topics: "+", ".join(enabled_commands+list(abs_topics.keys()))) mesg(f"available topics: "+", ".join(list(abs_topics.keys())))
mesg(f"available commands: "+", ".join(commands))
if admin: if admin:
mesg(f"admin commands: {admin_commands}") mesg(f"admin commands: {admin_commands}")
else: else:
try: mesg(f"{topic}: "+eval(f"self.{topic}.__doc__")) try: mesg(f"{topic}: "+eval(f"self.{topic}.__doc__"))
# except Exception as e: except (TypeError,AttributeError) as e:
except (TypeError,AttributeError):
# mesg(str( e.__class__.__name__ )) # mesg(str( e.__class__.__name__ ))
if topic in abs_topics: if topic in abs_topics:
mesg(f"{topic}: "+abs_topics[topic]) mesg(f"{topic}: "+abs_topics[topic])
else: else:
mesg(f"no help available for \"{topic}\"...") mesg(f"no help available for \"{topic}\"...")
except Exception as e: mesg(str(e.__class__)+" "+str(e)) except Exception as e: mesg(str(e.__class__)+" "+str(e))
def reload(self,prefix,cmd,pm,line,admin):
mesg=self.mesg
if admin:
mesg("reloading...")
self.util.reload()
mesg("reloaded!")
else:
err_perm()

View File

@ -23,5 +23,8 @@ class config:
hostmasks=["jan6!jan6@mischievous.deity"] hostmasks=["jan6!jan6@mischievous.deity"]
class cmd: class cmd:
prefixes=["6","'"] prefixes=["6","'"]
enabled_commands=["help","echo"] #disabled commands, won't run via normal means
admin_commands=["eval","exec","quit","reload"] disabled=[]
#admin-only override,
#useful for testing broken commands which should still be normal-user accessible
admin_only=[]

View File

@ -5,12 +5,12 @@ from commands import Command
import sys, importlib import sys, importlib
def stuff(bot,sock): def stuff(bot,sock):
config=Config config=Config
util=Util(sock,config) util=Util(config,sock)
command=Command(sock,config) command=Command(config)
server=bot.server server=bot.server
send=util.send send=util.send
quit=util.quit def mesg(msg: str,t=None):util.mesg(msg,t)
mesg=util.mesg # mesg=util.mesg
server_caps=[] server_caps=[]
wanted_caps=config.capabilities wanted_caps=config.capabilities
chan=config.server.channel #autojoin channel chan=config.server.channel #autojoin channel
@ -18,16 +18,16 @@ def stuff(bot,sock):
mode="init" mode="init"
def configure(): def configure():
config=importlib.reload(sys.modules["config"]).config config=importlib.reload(sys.modules["config"]).config
command=importlib.reload(sys.modules["commands"]).Command(sock,config) util=Util(config,sock)
util=Util(sock,config) command=importlib.reload(sys.modules["commands"]).Command(config)
command.util=util
prefixes=config.cmd.prefixes prefixes=config.cmd.prefixes
admin_accounts=config.admin.accounts admin_accounts=config.admin.accounts
admin_users=config.admin.hostmasks admin_users=config.admin.hostmasks
enabled_commands=config.cmd.enabled_commands admin_only=config.cmd.admin_only
admin_commands=config.cmd.admin_commands return command,command.util,config,util,prefixes,admin_accounts,admin_users,admin_only
return command,config,util,prefixes,admin_accounts,admin_users,enabled_commands,admin_commands
command,config,util,prefixes,admin_accounts,admin_users,enabled_commands,admin_commands=configure() command,command.util,config,util,prefixes,admin_accounts,admin_users,admin_only=configure()
send(irctokens.build("NICK", [config.self.nick]).format()) send(irctokens.build("NICK", [config.self.nick]).format())
send(irctokens.build("USER", [config.self.username,"0","*",config.self.realname]).format()) send(irctokens.build("USER", [config.self.username,"0","*",config.self.realname]).format())
@ -90,38 +90,42 @@ def stuff(bot,sock):
elif cmd.startswith(self_nick): elif cmd.startswith(self_nick):
cmd=cmd.replace(self_nick, '', 1) cmd=cmd.replace(self_nick, '', 1)
command.prefix=self_nick command.prefix=self_nick
prefix=command.prefix
except IndexError: except IndexError:
continue #skip to next command continue #skip to next command
cmd="echo IndexError or something" cmd="echo IndexError or something"
prefix=prefix or None
cmd=cmd.strip() cmd=cmd.strip()
try:is_adm=line.tags["account"] in admin_accounts or line.source in admin_users try:is_adm=line.tags["account"] in admin_accounts or line.source in admin_users
except KeyError:is_adm=line.source in admin_users except KeyError:is_adm=line.source in admin_users
command.line=line command.util.target=target
command._line=line
command.pm=is_pm command.pm=is_pm
command.cmd=cmd command.line=cmd
command.admin=is_adm command.admin=is_adm
command.config=config command.config=config
#handle special commands (requiring extra args 'n stuff) command.self_nick=self_nick
if cmd=="help": command.prefix=prefix
command.exec_cmd("help",[prefixes,enabled_commands,admin_commands]) if is_adm and cmd.startswith("reload"):
elif cmd.startswith("help "): command, command.util, config, util, prefixes, admin_accounts, admin_users, admin_only=configure()
topic=cmd.split(" ",1)[1] util.target=target
command.exec_cmd("help",[prefixes,enabled_commands,admin_commands,topic,self_nick]) command._line=line
elif is_adm and (cmd=="q" or cmd=="quit"): command.pm=is_pm
quit() command.line=cmd
elif is_adm and (cmd.startswith("q ") or cmd.startswith("quit")): command.admin=is_adm
quit(cmd.split(" ",1)[1]) command.config=config
elif is_adm and cmd.startswith("reload"): command.self_nick=self_nick
command,config,util,prefixes,admin_accounts,admin_users,enabled_command,admin_commands=configure() command.prefix=prefix
command.util.target=target
mesg("reloaded") mesg("reloaded")
elif cmd.startswith("eval "): elif cmd.startswith("eval ") and "eval" not in config.cmd.disabled:
if(is_adm): if(is_adm):
try: try:
result=eval(cmd[len("eval "):].strip() or "None") result=eval(cmd[len("eval "):].strip() or "None")
except Exception as e: except Exception as e:
mesg("Error: "+str(e)) mesg("Error: "+str(e))
else: mesg("Error: you're not authorized to eval") else: mesg("Error: you're not authorized to eval")
elif cmd.startswith("exec "): elif cmd.startswith("exec ") and "exec" not in config.cmd.disabled:
if(is_adm): if(is_adm):
try: try:
result=exec(cmd[len("exec "):].strip() or "None") result=exec(cmd[len("exec "):].strip() or "None")
@ -130,6 +134,4 @@ def stuff(bot,sock):
else: mesg("Error: you're not authorized to exec") else: mesg("Error: you're not authorized to exec")
#handle normal commands #handle normal commands
else: command.preq_cmd()
if cmd.startswith("echo "):
command.exec_cmd("echo")

View File

@ -1,6 +1,6 @@
import irctokens import irctokens
class Util: class Util:
def __init__(self,sock,config): def __init__(self,config,sock):
self.sock=sock self.sock=sock
self.config=config self.config=config
self.target="" self.target=""
@ -18,5 +18,5 @@ class Util:
msg=str(msg).partition("\n")[0] msg=str(msg).partition("\n")[0]
if len(msg)>=900: if len(msg)>=900:
msg=msg[:900] msg=msg[:900]
mesg("message too long!") self.mesg("message too long!")
self.send(irctokens.build("PRIVMSG", [t,str(msg)]).format()) self.send(irctokens.build("PRIVMSG", [t,str(msg)]).format())