fix functions breaking on clients without clid

This commit is contained in:
Lukas Mahler 2021-09-30 08:48:30 +02:00
parent 35c64cea14
commit 55776e31cd
3 changed files with 110 additions and 65 deletions

137
myTS3.py
View File

@ -4,7 +4,7 @@ TBD
__author__ = "Lukas Mahler"
__version__ = "0.0.0"
__date__ = "27.09.2021"
__date__ = "30.09.2021"
__email__ = "m@hler.eu"
__status__ = "Development"
@ -29,25 +29,28 @@ class TSbot:
start the event loop function.
"""
# Initialize from config
self.host = conf["Connection"]["host"]
self.port = conf["Connection"]["port"]
self.sid = conf["Connection"]["sid"]
self.user = conf["Authentication"]["user"]
self.pwd = conf["Authentication"]["pwd"]
self.allowed_sgids = conf["Allowed"]["sgids"]
self.nickname = conf["Misc"]["nickname"]
self.whitelisted = conf["Misc"]["whitelisted"]
# Initialize self
self.gecko = gecko.GeckoAPI()
self.log = log
self.myid = None
self.running = True
self.intro = "<Keep this chat open to use commands>"
self.last_crypto_update = time.time() - 1800
self.started = time.time()
self.last_crypto_update = self.started - 1800
self.pipeOut(f"Trying to connect to: {self.host}:{self.port}")
# Starting the Connection
with ts3.query.TS3Connection(self.host, self.port) as self.bot:
try:
self.bot.login(client_login_name=self.user, client_login_password=self.pwd)
@ -62,7 +65,7 @@ class TSbot:
self.pipeOut(f"Successfully connected as: {self.nickname}")
# Start the Bot
# Start the Bot loop
self.loop()
def loop(self):
@ -74,7 +77,7 @@ class TSbot:
The loop can be stopped setting self.running to False
"""
# Find my client id
# Find the instances client id
me = self.bot.clientfind(pattern=self.nickname)
if len(me) == 1:
self.myid = me[0]["clid"]
@ -119,6 +122,8 @@ class TSbot:
self.lookupcommand(".btc", self.myid)
self.lookupcommand(".dot", self.myid)
else:
pass
try:
# This method blocks, but we must sent the keepalive message at
@ -128,6 +133,8 @@ class TSbot:
except ts3.query.TS3TimeoutError:
pass
# try else!
else:
event_type = event.event
self.pipeOut(f"Got Event | length={len(event[0])} | {event_type}")
@ -142,6 +149,7 @@ class TSbot:
else:
self.pipeOut(event[0])
displayname = "Unresolved"
continue # can't resolve no clid
self.pipeOut(f"Client [{displayname}] connected.")
@ -249,8 +257,13 @@ class TSbot:
clients = self.bot.clientlist()
clients = [client["clid"] for client in clients if client["client_type"] != "1"]
else:
clients = self.bot.clientfind(pattern=usr)
clients = [client["clid"] for client in clients]
try:
clients = self.bot.clientfind(pattern=usr)
clients = [client["clid"] for client in clients]
except ts3.query.TS3QueryError as e:
self.pipeOut(f"Couldnt execute poke, no client found using pattern {usr},"
f"returned error:\n{e}", lvl="ERROR")
return
# Ping them
if len(clients) > 0:
@ -331,8 +344,12 @@ class TSbot:
"""
Check if the given client-uid is a query client.
"""
try:
client = self.bot.clientinfo(clid=clid)
except ts3.query.TS3QueryError as e:
self.pipeOut(f"given clid {clid} returned error:\n{e}", lvl="ERROR")
return True
client = self.bot.clientinfo(clid=clid)
if client[0]["client_type"] == "1":
self.pipeOut(f"[{clid}] ISQUERY: True")
return True
@ -344,39 +361,40 @@ class TSbot:
"""
Check if the given client-databaseid is an admin.
"""
try:
groups = self.bot.servergroupsbyclientid(cldbid=cldbid)
except ts3.query.TS3QueryError as e:
self.pipeOut(e, lvl="ERROR")
return False
groups = self.bot.servergroupsbyclientid(cldbid=cldbid)
# [print(group["sgid"]) for group in groups]
for group in groups:
# 6 Server Admin/ 13 Operator / 15 Root
# if (group["sgid"] == "6") or (group["sgid"] == "13") or (group["sgid"] == "15"):
if group["sgid"] == "15":
self.pipeOut(f"[{cldbid}] ISADMIN: True")
return True
else:
continue
self.pipeOut(f"[{cldbid}] ISADMIN: False")
return False
self.pipeOut(" ".join(groups), lvl="DEBUG")
if self.allowed_sgids in groups:
self.pipeOut(f"[{cldbid}] ISADMIN: True")
return True
else:
self.pipeOut(f"[{cldbid}] ISADMIN: False")
return False
def lookupcommand(self, msg, invkr_id):
"""
Every message starting with '.' gets passed and evaluated in this function.
Commands in this function are sorted alphabetically.
Command Parameter 1 Parameter 2
---------------------------------------------------------
.admin
.annoy target message
.kickall message
.test
.btc / .eth
.dot / .ada
.info clid
.list channel/clients
.follow
.rename nickname
.stop / .quit / .q
.info clid
.kickall message
.list channel/clients
.pingall message
.admin
.rename nickname
.roll
.stop / .quit / .q
.test
"""
@ -385,7 +403,10 @@ class TSbot:
parameter = commandstring[1:]
self.pipeOut(f"command: {command} | parameter: {parameter} | invkr_id: {invkr_id}")
if command == ".annoy":
if command == ".admin":
self.notifyAdmin()
elif command == ".annoy":
try:
target = parameter[0]
msg = parameter[1]
@ -395,13 +416,6 @@ class TSbot:
self.bot.sendtextmessage(targetmode=1, target=invkr_id, msg=err)
pass
elif command == ".kickall":
self.kickall("test") # TODO
elif command == ".test":
cid = self.createChannel("Test")
self.bot.sendtextmessage(targetmode=1, target=invkr_id, msg=cid)
elif command == ".btc" or command == ".eth":
channelname = f"[cspacerC1]BTC: {self.gecko.getSymbol('Bitcoin', decimal=0)} | " \
f"ETH: {self.gecko.getSymbol('ethereum', decimal=0)}"
@ -418,8 +432,17 @@ class TSbot:
except ts3.query.TS3QueryError:
pass
elif command == ".follow":
# self.bot.clientmove(clid=self.myid,cid=129)
pass # TODO get channel id (cid) of parameter 1 client
elif command == ".info":
pass # TODO
# TODO implement more then just the runtime
msg = f"Runtime: {util.getRuntime(self.started)}"
self.bot.sendtextmessage(targetmode=1, target=invkr_id, msg=msg)
elif command == ".kickall":
self.kickall("test") # TODO
elif command == ".list":
try:
@ -429,21 +452,6 @@ class TSbot:
self.bot.sendtextmessage(targetmode=1, target=invkr_id, msg=err)
pass
elif command == ".follow":
pass # TODO
elif command == ".rename":
try:
self.nickname = parameter[0]
self.bot.clientupdate(client_nickname=self.nickname)
except IndexError:
err = "Please use the command like this: .rename NAME"
self.bot.sendtextmessage(targetmode=1, target=invkr_id, msg=err)
pass
elif command == ".stop" or command == ".quit" or command == ".q":
self.stop(invkr_id)
elif command == ".pingall":
try:
msg = parameter[0]
@ -453,8 +461,24 @@ class TSbot:
self.bot.sendtextmessage(targetmode=1, target=invkr_id, msg=err)
pass
elif command == ".admin":
self.notifyAdmin()
elif command == ".rename":
try:
self.nickname = parameter[0]
self.bot.clientupdate(client_nickname=self.nickname)
except IndexError:
err = "Please use the command like this: .rename NAME"
self.bot.sendtextmessage(targetmode=1, target=invkr_id, msg=err)
pass
elif command == ".roll":
pass # TODO needs permission for everyone + targemode implementation
elif command == ".stop" or command == ".quit" or command == ".q":
self.stop(invkr_id)
elif command == ".test":
cid = self.createChannel("Test")
self.bot.sendtextmessage(targetmode=1, target=invkr_id, msg=cid)
else:
err = f"Unknown Command: [{command}]"
@ -465,7 +489,6 @@ class TSbot:
Generate printable clientinfo from clid.
"""
usrd = {}
info = self.bot.clientinfo(clid=clid)
usrd = info.__dict__
@ -495,7 +518,7 @@ def main():
sys.excepthook = util.unhandledException
# Load toml config
conf = util.getconf("prod.toml")
conf = util.getConf("prod.toml")
# Start the Bot Instance
TSbot(conf, log)

View File

@ -7,6 +7,9 @@ sid = 1
user = "exampleuser"
pwd = "password"
[Allowed]
sgids = ["1"]
[Misc]
nickname = "myTS3-Bot"
whitelisted = false

View File

@ -4,7 +4,7 @@ TBD
__author__ = "Lukas Mahler"
__version__ = "0.0.0"
__date__ = "27.09.2021"
__date__ = "30.09.2021"
__email__ = "m@hler.eu"
__status__ = "Development"
@ -14,6 +14,8 @@ import sys
import shutil
import os.path
import logging
import time
from datetime import timedelta
from logging.handlers import RotatingFileHandler
# Custom
@ -32,18 +34,18 @@ def unhandledException(exc_type, exc_value, exc_traceback):
log.critical("Uncaught exception", exc_info=(exc_type, exc_value, exc_traceback))
def getconf(fname):
def getConf(fname):
"""
"""
if fname.endswith(".toml"):
if os.path.isfile(fname):
try:
data = toml.load(fname)
return data
config = toml.load(fname)
checkConf(config)
return config
except ValueError as e:
log.critical(e)
# log.critical("The provided '.toml' seems to be invalid.")
log.critical(f"The provided '.toml' is probably invalid, returned error:\n{e}")
exit(1)
else:
log.critical(f"Couldn't locate the '.toml' file [{fname}].")
@ -51,12 +53,29 @@ def getconf(fname):
shutil.copy("src/template.toml", fname)
exit(1)
else:
log.critical("The provided config file is not a '.toml' file.")
log.critical(f"The provided config file [{fname}] is not a '.toml' file.")
log.info("Creating a new '.toml' file from template, please edit and restart.")
shutil.copy("src/template.toml", "prod.toml")
exit(1)
def getRuntime(started):
"""
"""
elapsed = time.time() - started
runtime = str(timedelta(seconds=elapsed))
return runtime
def checkConf(config):
"""
TODO check if keys exist
"""
pass
def setupLogger(logpath, lvl="DEBUG"):
"""
Create a rotating log in a log folder
@ -66,7 +85,7 @@ def setupLogger(logpath, lvl="DEBUG"):
log = logging.getLogger()
if not os.path.exists(logpath):
os.makedirs(logpath)
handler = RotatingFileHandler(logpath + r"/myTS3.log", encoding='utf-8', maxBytes=5*1024*1024, backupCount=10)
handler = RotatingFileHandler(logpath + r"/myTS3.log", encoding='utf-8', maxBytes=1*1024*1024, backupCount=10)
logformat = logging.Formatter("%(asctime)s %(levelname)8s %(message)s", "%Y-%m-%d %H:%M:%S")
handler.setFormatter(logformat)
log.addHandler(handler)