From edf37e485aa0988f17cb4f030fc4d5d686dfb9ec Mon Sep 17 00:00:00 2001 From: Artem Synytsyn Date: Wed, 13 Nov 2024 22:45:59 +0200 Subject: [PATCH 1/3] Add Discord notifier plugin --- app/plugins/discord_notifier/__init__.py | 27 +++++ .../discord_notifier/discord_notifier.py | 101 ++++++++++++++++++ requirements.txt | 1 + 3 files changed, 129 insertions(+) create mode 100644 app/plugins/discord_notifier/__init__.py create mode 100644 app/plugins/discord_notifier/discord_notifier.py diff --git a/app/plugins/discord_notifier/__init__.py b/app/plugins/discord_notifier/__init__.py new file mode 100644 index 0000000..a1c58d8 --- /dev/null +++ b/app/plugins/discord_notifier/__init__.py @@ -0,0 +1,27 @@ +""" +Discord Notifier Plugin +====================== +Notify members about tools and doors usage statistics in Discord + +How to use? +----------- +1. Setup WebHooks for your channel. +HOWTO: https://support.discord.com/hc/en-us/articles/228383668-Intro-to-Webhooks +2. Create new branch in settings, e.g: + "PLUGINS": { + "slack_notifier": { + "SLACK_DOOR_CHANNEL": "#prismo-door-channel", + "SLACK_TOKEN": "xoxb-this-is-not-areal-slack-token", + "SLACK_TOOL_CHANNEL": "#prismo-debug" + }, + "discord_notifier": { + "DISCORD_DOOR_EVENT_WEBHOOK": "https://discord.com/api/webhooks/your-webhook" + }, +""" +from flask import Flask + +from .discord_notifier import DiscordNotifierPlugin + + +def init_plugin(app: Flask): + DiscordNotifierPlugin(app.app_context()) diff --git a/app/plugins/discord_notifier/discord_notifier.py b/app/plugins/discord_notifier/discord_notifier.py new file mode 100644 index 0000000..f1499f6 --- /dev/null +++ b/app/plugins/discord_notifier/discord_notifier.py @@ -0,0 +1,101 @@ +import sqlite3 +from discord import SyncWebhook + +# pylint: disable=consider-using-f-string + +class DiscordNotifierPlugin: + def __init__(self, app_context): + try: + self.app_context = app_context + self.logger = self.app_context.app.logger + self.ee = self.app_context.app.ee # Event emitter, used for event-based communication + self.config = self.app_context.app.config["PRISMO"]["PLUGINS"]["discord_notifier"] + self.db_uri = self.app_context.app.config["DATABASE_URI"] + self.ee.add_listener('access-log-entry-added', self.access_log_entry_added) + self.app_context.app.logger.info("Discord Notifier Plugin initialized") + except Exception as e: + self.logger.error("Error in DiscordNotifierPlugin.__init__: %s", e) + raise e + + def get_user_name(self, user_key): + """ + Get user name and id based on user key info + """ + connection = sqlite3.connect(self.db_uri) + cursor = connection.cursor() + + cursor.execute("SELECT name from users WHERE key = ?", + (user_key,), + ) + connection.commit() + result = cursor.fetchone() + + connection.close() + if result: + return result[0] + + return None + + def get_device_name(self, device_id): + """ + Get device name based on its ID + """ + connection = sqlite3.connect(self.db_uri) + cursor = connection.cursor() + + cursor.execute("SELECT name from devices WHERE id = ?", + (device_id,), + ) + connection.commit() + result = cursor.fetchone() + + connection.close() + if result: + return result[0] + + return None + + def get_device_type(self, device_id): + """ + Get device name based on its ID + """ + connection = sqlite3.connect(self.db_uri) + cursor = connection.cursor() + + cursor.execute("SELECT type from devices WHERE id = ?", + (device_id,), + ) + connection.commit() + result = cursor.fetchone() + + connection.close() + if result: + return result[0] + + return None + + def access_log_entry_added(self, event): + try: + if event["operation"] == "unlock": + user_name = self.get_user_name(event["user_key"]) + device_name = self.get_device_name(event["device_id"]) + device_type = self.get_device_type(event["device_id"]) + self.logger.info("Access log entry added") + self.logger.info("User name: %s", user_name) + if device_type == "tool": + self.logger.info("Device name: %s", device_name) + text_message = "🔩**%s** was unlocked by **%s**" % (device_name, user_name) + webhook = SyncWebhook.from_url(self.config["DISCORD_TOOL_EVENT_WEBHOOK"]) + webhook.send(text_message) + + elif device_type == "door": + self.logger.info("Door opened: %s", device_name) + text_message = "🔐**%s** was opened by **%s**" % (device_name, user_name) + webhook = SyncWebhook.from_url(self.config["DISCORD_DOOR_EVENT_WEBHOOK"]) + webhook.send(text_message) + else: + self.logger.error("Unknown reader type! %s", device_type) + + except Exception as e: + self.logger.error("Error in DiscordNotifierPlugin.access_log_entry_added: %s", e) + raise e diff --git a/requirements.txt b/requirements.txt index f8623e7..18a0922 100644 --- a/requirements.txt +++ b/requirements.txt @@ -17,3 +17,4 @@ intelhex pyserial rshell esptool +discord From 7c4a796408abe11dac545d66e451536d1a3fb2e6 Mon Sep 17 00:00:00 2001 From: Artem Synytsyn Date: Thu, 26 Jun 2025 14:38:38 +0300 Subject: [PATCH 2/3] Ignore R0801 warning - similar lines in code --- .github/workflows/pylint.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/pylint.yml b/.github/workflows/pylint.yml index f7da68b..86521f7 100644 --- a/.github/workflows/pylint.yml +++ b/.github/workflows/pylint.yml @@ -20,7 +20,7 @@ jobs: pip install -r requirements.txt - name: Analysing the code with pylint run: | - pylint app --disable=C0116,C0114,C0115,C0411,E0401,W0611,W0622,W0719,C0103,W1514,R0903,R1732,R0914 + pylint app --disable=C0116,C0114,C0115,C0411,E0401,W0611,W0622,W0719,C0103,W1514,R0903,R1732,R0914,R0801 - name: Analysing the code with pycodestyle run: | pycodestyle app From 94f75f1ffe81f9e0829a73158a7d4e74b353539a Mon Sep 17 00:00:00 2001 From: Artem Synytsyn Date: Thu, 26 Jun 2025 14:41:59 +0300 Subject: [PATCH 3/3] Fix blank lines --- app/plugins/discord_notifier/discord_notifier.py | 1 + 1 file changed, 1 insertion(+) diff --git a/app/plugins/discord_notifier/discord_notifier.py b/app/plugins/discord_notifier/discord_notifier.py index f1499f6..ad25f83 100644 --- a/app/plugins/discord_notifier/discord_notifier.py +++ b/app/plugins/discord_notifier/discord_notifier.py @@ -3,6 +3,7 @@ # pylint: disable=consider-using-f-string + class DiscordNotifierPlugin: def __init__(self, app_context): try: