aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authornico <nico@magicbroccoli.de>2019-12-07 13:09:41 +0100
committernico <nico@magicbroccoli.de>2019-12-07 13:09:41 +0100
commit9080c719dc0252b43fd894d71cf7d410ae8b0cb6 (patch)
tree15263862c42503ff1c2103e08d6aacce273127b7
TeamSpeak datebased GroupAssigner
cleaned up working release + properly register for servernotify events + process only voice_clients + properly check if client is already a group member + logging
-rw-r--r--.gitignore138
-rw-r--r--config.json.sample9
-rw-r--r--config.py17
-rw-r--r--main.py72
-rw-r--r--requirements.txt1
5 files changed, 237 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..821dc45
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,138 @@
+# Created by .ignore support plugin (hsz.mobi)
+### Python template
+# Byte-compiled / optimized / DLL files
+__pycache__/
+*.py[cod]
+*$py.class
+
+# C extensions
+*.so
+
+# Distribution / packaging
+.Python
+build/
+develop-eggs/
+dist/
+downloads/
+eggs/
+.eggs/
+lib/
+lib64/
+parts/
+sdist/
+var/
+wheels/
+pip-wheel-metadata/
+share/python-wheels/
+*.egg-info/
+.installed.cfg
+*.egg
+MANIFEST
+
+# PyInstaller
+# Usually these files are written by a python script from a template
+# before PyInstaller builds the exe, so as to inject date/other infos into it.
+*.manifest
+*.spec
+
+# Installer logs
+pip-log.txt
+pip-delete-this-directory.txt
+
+# Unit test / coverage reports
+htmlcov/
+.tox/
+.nox/
+.coverage
+.coverage.*
+.cache
+nosetests.xml
+coverage.xml
+*.cover
+*.py,cover
+.hypothesis/
+.pytest_cache/
+
+# Translations
+*.mo
+*.pot
+
+# Django stuff:
+*.log
+local_settings.py
+db.sqlite3
+db.sqlite3-journal
+
+# Flask stuff:
+instance/
+.webassets-cache
+
+# Scrapy stuff:
+.scrapy
+
+# Sphinx documentation
+docs/_build/
+
+# PyBuilder
+target/
+
+# Jupyter Notebook
+.ipynb_checkpoints
+
+# IPython
+profile_default/
+ipython_config.py
+
+# pyenv
+.python-version
+
+# pipenv
+# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
+# However, in case of collaboration, if having platform-specific dependencies or dependencies
+# having no cross-platform support, pipenv may install dependencies that don't work, or not
+# install all needed dependencies.
+#Pipfile.lock
+
+# PEP 582; used by e.g. github.com/David-OConnor/pyflow
+__pypackages__/
+
+# Celery stuff
+celerybeat-schedule
+celerybeat.pid
+
+# SageMath parsed files
+*.sage.py
+
+# Environments
+.env
+.venv
+env/
+venv/
+ENV/
+env.bak/
+venv.bak/
+
+# Spyder project settings
+.spyderproject
+.spyproject
+
+# Rope project settings
+.ropeproject
+
+# mkdocs documentation
+/site
+
+# mypy
+.mypy_cache/
+.dmypy.json
+dmypy.json
+
+# Pyre type checker
+.pyre/
+
+# pycharm
+.idea
+
+# project specific
+config.json
+*.log
diff --git a/config.json.sample b/config.json.sample
new file mode 100644
index 0000000..2f2eedf
--- /dev/null
+++ b/config.json.sample
@@ -0,0 +1,9 @@
+{
+ "host": "localhost",
+ "port": 10011,
+ "user": "serveradmin",
+ "password": "super_secret-Password",
+ "server_id": 1337,
+
+ "gid" : 9999
+} \ No newline at end of file
diff --git a/config.py b/config.py
new file mode 100644
index 0000000..d0dc061
--- /dev/null
+++ b/config.py
@@ -0,0 +1,17 @@
+# -*- coding: utf-8 -*-
+import json
+
+with open("config.json", "r", encoding="utf-8") as file:
+ config = json.load(file)
+
+
+class Config(object):
+ # connection arguments
+ HOST = config['host']
+ PORT = config['port']
+ USER = config['user']
+ PW = config['password']
+ SID = config['server_id']
+
+ # assignment settings
+ GID = config['gid']
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..532e4af
--- /dev/null
+++ b/main.py
@@ -0,0 +1,72 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+import logging
+
+import ts3
+
+from config import Config
+
+
+def watcher(conn):
+ # Register for events
+ # https://yat.qa/ressourcen/server-query-notify/#server
+ conn.servernotifyregister(event="server")
+
+ while True:
+ conn.send_keepalive()
+
+ try:
+ event = conn.wait_for_event(timeout=60)
+
+ except ts3.query.TS3TimeoutError:
+ pass
+
+ else:
+ # only parse entering clients info
+ if event.event == "notifycliententerview":
+
+ # skip query clients -- query client = 1 , voice client = 0
+ if event[0]['client_type'] == '0':
+
+ # reasonid should be 0 not sure though
+ if event[0]["reasonid"] == "0":
+
+ user_grps = event.parsed[0]['client_servergroups'].split(sep=',')
+ gid = Config.GID
+
+ # only try to add nonmembers to group
+ if str(gid) not in user_grps:
+
+ cldbid = event.parsed[0]['client_database_id']
+
+ # https://yat.qa/ressourcen/server-query-kommentare/
+ # Usage: servergroupaddclient sgid={groupID} cldbid={clientDBID}
+ try:
+ cmd = conn.servergroupaddclient(sgid=gid, cldbid=cldbid)
+
+ if cmd.error['id'] != '0':
+ logger.info(cmd.data[0].decode("utf-8"))
+
+ # log process
+ logmsg = '{client_nickname}:{client_database_id} - added to {gid}'
+ logging.info(logmsg.format(**event[0], gid=gid))
+
+ except KeyError:
+ logger.error(str(event.parsed))
+ pass
+
+
+if __name__ == "__main__":
+ # logging
+ logger = logging.getLogger()
+ logger.setLevel(logging.INFO)
+
+ logf = logging.FileHandler('info.log')
+ logf.setFormatter(logging.Formatter("%(asctime)s - %(levelname)-8s - %(message)s"))
+
+ logger.addHandler(logf)
+
+ with ts3.query.TS3Connection(Config.HOST, Config.PORT) as ts3conn:
+ ts3conn.login(client_login_name=Config.USER, client_login_password=Config.PW)
+ ts3conn.use(sid=Config.SID)
+ watcher(ts3conn)
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000..ae7b420
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1 @@
+ts3>=1.0.11