diff options
-rw-r--r-- | .github/workflows/pythonapp.yml | 26 | ||||
-rw-r--r-- | .pre-commit-config.yaml | 31 | ||||
-rw-r--r-- | README.MD | 42 | ||||
-rw-r--r-- | config.py | 4 | ||||
-rw-r--r-- | config.yml.example | 2 | ||||
-rw-r--r-- | main.py | 23 | ||||
-rw-r--r-- | pyproject.toml | 20 | ||||
-rw-r--r-- | requirements.txt | 4 |
8 files changed, 134 insertions, 18 deletions
diff --git a/.github/workflows/pythonapp.yml b/.github/workflows/pythonapp.yml new file mode 100644 index 0000000..e3af4e8 --- /dev/null +++ b/.github/workflows/pythonapp.yml @@ -0,0 +1,26 @@ +name: Python application + +on: [push] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v1 + - name: Set up Python 3.8 + uses: actions/setup-python@v1 + with: + python-version: 3.8 + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: Lint with flake8 + run: | + pip install flake8 + # stop the build if there are Python syntax errors or undefined names + flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide + flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..0f05fc8 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,31 @@ +# See https://pre-commit.com for more information +# See https://pre-commit.com/hooks.html for more hooks +repos: +- repo: https://github.com/pre-commit/pre-commit-hooks + rev: v3.3.0 + hooks: + - id: check-docstring-first + - id: check-executables-have-shebangs + - id: check-yaml + files: config.yml + - id: debug-statements + - id: end-of-file-fixer + - id: fix-encoding-pragma + - id: mixed-line-ending + args: + - "--fix=lf" + - id: trailing-whitespace + +- repo: https://github.com/psf/black + rev: 20.8b1 + hooks: + - id: black + +- repo: https://gitlab.com/pycqa/flake8 + rev: 3.8.4 + hooks: + - id: flake8 + args: + - "--max-complexity=10" + - "--max-line-length=127" + - "--ignore=E501,E203" diff --git a/README.MD b/README.MD new file mode 100644 index 0000000..0642003 --- /dev/null +++ b/README.MD @@ -0,0 +1,42 @@ +## XMPP Retired MUC Bot +The repository houses a simple bot build to redirect joining user of MUC room A to room b. + +### requirements +The easiest way to setup a clean Python project environment is to use a virtual environment inside the cloned +repository directory. The following bash lines install the `python-virtualenv` module, create the virtual environment +using Python3 and finally install all dependencies listed in the requirements file. + +```bash +# Debian +apt install python-virtualenv + +# Arch +pacman -S python-virtualenv + +# create a venv folder inside the cloned repository +mkdir venv +virtualenv -p python3 venv/ + +source ./venv/bin/activate +pip install -r requirements.txt +``` + +### configuration +The configuration effort is quite low and should be for the most part be self-explanatory. +The message section features the message templates the bot will use to reply to message / group messages. To further +customize the user experience some variables are available, to for example directly tag the user. + +The room section lists the room a / b the bot connects, redirects to. +The key is the room the bot tries to join and the value is the redirect target. + +### pre-commit framework +This project utilizes the [pre-commit](https://pre-commit.com/) framework to automate various small hick-ups that tend +to happen prior to committing. + +To use the framework it is necessary to follow these steps: +```bash +# install the pre-commit hook +pre-commit install + +# to test your staged files manually run +pre-commit run @@ -51,9 +51,7 @@ class Config: print(err, file=sys.stderr) sys.exit(err.errno) - def get( - self, key: str = None, default: (str, int) = None - ) -> (dict, str, int, None): + def get(self, key: str = None, default: (str, int) = None) -> (dict, str, int, None): """method to retrieve the whole config data, a single value or the optional default value""" # if a special key is request, return only that value if key is not None: diff --git a/config.yml.example b/config.yml.example index 8687db7..13746a4 100644 --- a/config.yml.example +++ b/config.yml.example @@ -24,5 +24,5 @@ features: direct_invite: false # what to do with the user in the retired room - #kick_user: false + kick_user: false ban_user: false @@ -15,7 +15,7 @@ class RetiredMucBot(ClientXMPP): # passthrough the config obj self.config = config - + self.rooms = None self.nick = nick self.messages = self.config.get("messages") @@ -61,16 +61,16 @@ class RetiredMucBot(ClientXMPP): """ # do not process our own messages - ourself = self.plugin['xep_0045'].get_our_jid_in_room(msg.get_mucroom()) - if msg['from'] == ourself: + ourself = self.plugin["xep_0045"].get_our_jid_in_room(msg.get_mucroom()) + if msg["from"] == ourself: return # ever other messages will be answered statically - if msg['type'] in ('normal', 'chat'): + if msg["type"] in ("normal", "chat"): self.send_message( - mto=msg['from'], - mbody=self.messages['direct_msg'].format(nick=self.nick), - mtype=msg['type'], + mto=msg["from"], + mbody=self.messages["direct_msg"].format(nick=self.nick), + mtype=msg["type"], ) def notify_user(self, presence): @@ -89,11 +89,11 @@ class RetiredMucBot(ClientXMPP): new_room = self.rooms[presence.get_from().bare] self.send_message( mto=presence.get_from().bare, - mbody=self.messages['grp_msg'].format(user_nick=user_nick, new_room=new_room), + mbody=self.messages["grp_msg"].format(user_nick=user_nick, new_room=new_room), mtype="groupchat", ) - if self.functions['direct_invite']: + if self.functions["direct_invite"]: jid = presence["muc"].get_jid().bare self.invite_user(jid, new_room) @@ -106,7 +106,7 @@ class RetiredMucBot(ClientXMPP): self.plugin["xep_0045"].invite( room=jid, jid=room, - reason='redirection due to retirement', + reason="redirection due to retirement", ) @@ -121,11 +121,10 @@ if __name__ == "__main__": # init the bot and register used slixmpp plugins xmpp = RetiredMucBot(login["jid"], login["password"], login["nick"], config) - #xmpp.register_plugin("xep_0004") # Data Forms xmpp.register_plugin("xep_0030") # Service Discovery xmpp.register_plugin("xep_0045") # Multi-User Chat xmpp.register_plugin("xep_0085") # Chat State Notifications - xmpp.register_plugin('xep_0092') # Software Version + xmpp.register_plugin("xep_0092") # Software Version xmpp.register_plugin("xep_0199") # XMPP Ping xmpp.register_plugin("xep_0249") # Direct MUC Invite diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..e834e5c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,20 @@ +[tool.black] +line-length = 120 +target-version = ['py37', 'py38'] +include = '\.pyi?$' +exclude = ''' +( + /( + \.eggs # exclude a few common directories in the + | \.git # root of the project + | \.hg + | \.mypy_cache + | \.tox + | \.venv + | _build + | buck-out + | build + | dist + )/ # the root of the project +) +''' diff --git a/requirements.txt b/requirements.txt index 3587248..d79ce00 100644 --- a/requirements.txt +++ b/requirements.txt @@ -5,7 +5,7 @@ attrs==20.2.0 cffi==1.14.3 chardet==3.0.4 idna==2.10 -multidict==4.7.6 +multidict==5.0.0 pyasn1==0.4.8 pyasn1-modules==0.2.8 pycares==3.1.1 @@ -13,4 +13,4 @@ pycparser==2.20 ruamel.yaml==0.16.12 ruamel.yaml.clib==0.2.2 slixmpp==1.5.2 -yarl==1.5.1 +yarl==1.6.2 |