From e49142ea6f5c57ca775eb92010dbb1960c784cea Mon Sep 17 00:00:00 2001 From: Valentin Korenjak Date: Sat, 21 Mar 2026 22:52:32 +0100 Subject: [PATCH] =?UTF-8?q?Implementacija=20obve=C5=A1=C4=8Danja=20preko?= =?UTF-8?q?=20ntfy.sh=20#12?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 3 ++- projector.py | 39 ++++++++++++++++++++++++++++++++++++++- settings.json | 14 ++++++++++++++ settings.json.sample | 4 +++- tools/add_song.py | 28 ++++++++++++++++++++++++++++ web/server.py | 8 ++++++++ 6 files changed, 93 insertions(+), 3 deletions(-) create mode 100644 settings.json diff --git a/.gitignore b/.gitignore index 1e519f7..07adabe 100644 --- a/.gitignore +++ b/.gitignore @@ -10,4 +10,5 @@ songs.db __pycache__/ # Datoteke dnevnikov (logs) -*.log \ No newline at end of file +*.log +settings.json diff --git a/projector.py b/projector.py index 4d5052b..0aeddfb 100755 --- a/projector.py +++ b/projector.py @@ -71,7 +71,9 @@ class SongProjector: "font_bold": True, "show_song_info": True, "split_by_stanza": False, # TODO: mogoče nekoč (prelom po kitici namesto po višini) - "db_update_url": "" + "db_update_url": "", + "ntfy_topic": "", + "installation_label": "Projekcija: DEFAULT" } if not os.path.exists(SETTINGS_PATH): @@ -633,6 +635,41 @@ class SongProjector: subprocess.Popen(args) self.root.after(200, self.exit_program) + + # ------------------------------------------------------ + # Pošiljanje ntfy obvestil + # ------------------------------------------------------ + def send_ntfy_notification(self, song_id, title, lyrics): + """ + Pošlje obvestilo o spremembi besedila preko ntfy.sh. + """ + topic = self.settings.get("ntfy_topic", "").strip() + if not topic: + return + + label = self.settings.get("installation_label", "Projekcija") + # ntfy.sh headers must be ASCII. We'll use base64 encoding for the title to support non-ASCII characters. + import base64 + encoded_label = "=?UTF-8?B?" + base64.b64encode(label.encode('utf-8')).decode('utf-8') + "?=" + + message = f"{song_id}\n{title}\n{lyrics}" + + try: + url = f"https://ntfy.sh/{topic}" + req = urllib.request.Request( + url, + data=message.encode('utf-8'), + method='POST', + headers={ "Title": encoded_label, + "Priority": "high", + "Tags": "loudspeaker" } + ) + # Uporabimo kratek timeout, da ne blokiramo aplikacije + with urllib.request.urlopen(req, timeout=5) as response: + pass + except Exception as e: + print(f"Napaka pri pošiljanju ntfy obvestila: {e}") + # ---------------------------------------------------------- # Zagon aplikacije # ---------------------------------------------------------- diff --git a/settings.json b/settings.json new file mode 100644 index 0000000..b24776a --- /dev/null +++ b/settings.json @@ -0,0 +1,14 @@ +{ + "font_name": "Noto Sans", + "bg_color": "#000000", + "fg_color": "#FFFFFF", + "font_size": 32, + "screen_width_percent": 60, + "font_bold": false, + "show_song_info": true, + "split_by_stanza": false, + "web_port": 5000, + "db_update_url": "", + "ntfy_topic": "Projekcija-besedil-popravki", + "installation_label": "planika test" +} diff --git a/settings.json.sample b/settings.json.sample index 36cd9f6..f2b81cd 100644 --- a/settings.json.sample +++ b/settings.json.sample @@ -8,5 +8,7 @@ "show_song_info": true, "split_by_stanza": false, "web_port": 5000, - "db_update_url": "" + "db_update_url": "", + "ntfy_topic": "", + "installation_label": "Projekcija" } diff --git a/tools/add_song.py b/tools/add_song.py index 5e3d4a0..d020ea0 100755 --- a/tools/add_song.py +++ b/tools/add_song.py @@ -4,6 +4,7 @@ import sqlite3 import json import os +import urllib.request DB_PATH = 'songs.db' SETTINGS_PATH = 'settings.json' @@ -34,6 +35,29 @@ conn.commit() # POMOŽNE FUNKCIJE # --------------------------------------------------------------------------- +def send_ntfy_notification(song_id, title, lyrics): + """ + Pošlje obvestilo o spremembi besedila preko ntfy.sh. + """ + topic = settings.get("ntfy_topic", "").strip() + if not topic: + return + + label = settings.get("installation_label", "Projekcija") + message = f"{song_id}\n{title}\n{lyrics}" + + try: + url = f"https://ntfy.sh/{topic}" + req = urllib.request.Request( + url, + data=message.encode('utf-8'), + method='POST' + ) + with urllib.request.urlopen(req, timeout=5) as response: + pass + except Exception as e: + print(f"Napaka pri pošiljanju ntfy obvestila: {e}") + def get_next_free_id(start: int = 792) -> int: """Vrne prvo prosto številko pesmi, ki je ≥ start (privzeto 792).""" next_id = start @@ -125,6 +149,7 @@ def dodaj_pesem(): cursor.execute("INSERT OR REPLACE INTO songs (id, title, lyrics) VALUES (?,?,?)", (song_id, title, full_lyrics)) conn.commit() + send_ntfy_notification(song_id, title, full_lyrics) print("Pesem uspešno shranjena!") def uredi_pesem(): @@ -162,6 +187,7 @@ def uredi_pesem(): cursor.execute("UPDATE songs SET title = ?, lyrics = ? WHERE id = ?", (new_title, new_lyrics, song_id)) conn.commit() + send_ntfy_notification(song_id, new_title, new_lyrics) print("Pesem uspešno posodobljena!") def prestavi_pesem(): @@ -200,6 +226,7 @@ def prestavi_pesem(): (new_id, vir[0], vir[1])) cursor.execute("DELETE FROM songs WHERE id = ?", (old_id,)) conn.commit() + send_ntfy_notification(new_id, vir[0], vir[1]) print("Pesem uspešno prestavljena!") def izbrisi_pesem(): @@ -320,6 +347,7 @@ def uvozi_bazo(): # -- shranjevanje pesmi --------------------------------------------- cursor.execute("INSERT OR REPLACE INTO songs (id, title, lyrics) VALUES (?,?,?)", (song_id, title, lyrics)) + send_ntfy_notification(song_id, title, lyrics) conn.commit() print("\nUvoz pesmi uspešen!") diff --git a/web/server.py b/web/server.py index a641da3..b7c1998 100644 --- a/web/server.py +++ b/web/server.py @@ -241,12 +241,20 @@ def update_song(): _projector_app.song_number = str(new_id) _projector_app.load_song() + # Pošlji ntfy obvestilo + if hasattr(_projector_app, 'send_ntfy_notification'): + _projector_app.send_ntfy_notification(new_id, title, lyrics) + return jsonify({'status': 'ok', 'new_id': new_id}) # Obstoječa pesem _projector_app.cursor.execute("UPDATE songs SET title=?, lyrics=? WHERE id=?", (title, lyrics, song_id)) _projector_app.conn.commit() + # Pošlji ntfy obvestilo + if hasattr(_projector_app, 'send_ntfy_notification'): + _projector_app.send_ntfy_notification(song_id, title, lyrics) + # Osvežimo trenutno pesem, če je to ta, ki smo jo pravkar uredili if str(_projector_app.song_number_last) == str(song_id): _projector_app.song_number = str(song_id)