forked from viewit/KX-Bridge-Release
feat: add send image option to notifs
This commit is contained in:
@@ -185,7 +185,8 @@ def list_notification_urls() -> list[dict]:
|
||||
if url:
|
||||
events_str = cfg.get("notifications", f"events_{idx}", fallback="finished,failed,cancelled")
|
||||
events = [e.strip() for e in events_str.split(",") if e.strip()]
|
||||
result.append({"url": url, "events": events})
|
||||
include_image = cfg.get("notifications", f"image_{idx}", fallback="false").strip().lower() in ("1", "true", "yes")
|
||||
result.append({"url": url, "events": events, "include_image": include_image})
|
||||
idx += 1
|
||||
return result
|
||||
|
||||
|
||||
@@ -913,8 +913,8 @@ class KobraXBridge:
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
def _notify(self, event: str, filename: str = ""):
|
||||
urls = [e["url"] for e in self._notification_urls if event in e.get("events", [])]
|
||||
if not urls:
|
||||
matching = [e for e in self._notification_urls if event in e.get("events", [])]
|
||||
if not matching:
|
||||
return
|
||||
printer_name = self._state.get("printer_name", "KX-Bridge")
|
||||
titles = {
|
||||
@@ -927,10 +927,10 @@ class KobraXBridge:
|
||||
}
|
||||
title = titles.get(event, "KX-Bridge")
|
||||
if event == "progress":
|
||||
pct = int(self._state.get("progress", 0) * 100)
|
||||
curr = self._state.get("curr_layer", 0)
|
||||
pct = int(self._state.get("progress", 0) * 100)
|
||||
curr = self._state.get("curr_layer", 0)
|
||||
total = self._state.get("total_layers", 0)
|
||||
rem = self._state.get("remain_time", 0)
|
||||
rem = self._state.get("remain_time", 0)
|
||||
rem_str = f"{rem // 3600}h {(rem % 3600) // 60}m" if rem else ""
|
||||
parts = [f"{pct}%"]
|
||||
if total:
|
||||
@@ -945,14 +945,37 @@ class KobraXBridge:
|
||||
if filename and printer_name:
|
||||
body = f"{filename}\n{printer_name}"
|
||||
|
||||
urls_plain = [e["url"] for e in matching if not e.get("include_image")]
|
||||
urls_image = [e["url"] for e in matching if e.get("include_image")]
|
||||
jpeg_bytes = self.camera_cache.latest_jpeg if urls_image else b""
|
||||
|
||||
def _send():
|
||||
import apprise, os, tempfile
|
||||
try:
|
||||
import apprise
|
||||
ap = apprise.Apprise()
|
||||
for url in urls:
|
||||
ap.add(url)
|
||||
ap.notify(title=title, body=body)
|
||||
log.info(f"Benachrichtigung '{event}' gesendet ({len(urls)} URL(s))")
|
||||
if urls_plain:
|
||||
ap = apprise.Apprise()
|
||||
for u in urls_plain:
|
||||
ap.add(u)
|
||||
ap.notify(title=title, body=body)
|
||||
if urls_image:
|
||||
ap2 = apprise.Apprise()
|
||||
for u in urls_image:
|
||||
ap2.add(u)
|
||||
attach = None
|
||||
tmppath = None
|
||||
if jpeg_bytes:
|
||||
with tempfile.NamedTemporaryFile(suffix=".jpg", delete=False) as f:
|
||||
f.write(jpeg_bytes)
|
||||
tmppath = f.name
|
||||
attach = apprise.AppriseAttachment()
|
||||
attach.add(tmppath)
|
||||
ap2.notify(title=title, body=body, attach=attach)
|
||||
if tmppath:
|
||||
try:
|
||||
os.unlink(tmppath)
|
||||
except Exception:
|
||||
pass
|
||||
log.info(f"Benachrichtigung '{event}' gesendet ({len(matching)} URL(s))")
|
||||
except Exception as e:
|
||||
log.warning(f"Benachrichtigung fehlgeschlagen: {e}")
|
||||
|
||||
@@ -3905,11 +3928,13 @@ class KobraXBridge:
|
||||
if not url:
|
||||
continue
|
||||
events = [e for e in entry.get("events", []) if e in valid_events]
|
||||
entries.append({"url": url, "events": events})
|
||||
include_image = bool(entry.get("include_image", False))
|
||||
entries.append({"url": url, "events": events, "include_image": include_image})
|
||||
cfg.add_section("notifications")
|
||||
for i, entry in enumerate(entries, 1):
|
||||
cfg.set("notifications", f"url_{i}", entry["url"])
|
||||
cfg.set("notifications", f"events_{i}", ",".join(entry["events"]))
|
||||
cfg.set("notifications", f"image_{i}", "true" if entry["include_image"] else "false")
|
||||
self._notification_urls = entries
|
||||
elif not cfg.has_section("notifications"):
|
||||
cfg.add_section("notifications")
|
||||
|
||||
@@ -894,7 +894,7 @@ function drawChart(id,_,series){
|
||||
var _notifRows=[];
|
||||
var _NOTIF_EVENTS=['started','finished','failed','cancelled','paused','progress'];
|
||||
function notifRenderList(entries){
|
||||
_notifRows=entries.map(function(e){return {url:e.url||'',events:e.events||[]};});
|
||||
_notifRows=entries.map(function(e){return {url:e.url||'',events:e.events||[],include_image:!!e.include_image};});
|
||||
notifRefreshDOM();
|
||||
}
|
||||
function notifRefreshDOM(){
|
||||
@@ -912,6 +912,9 @@ function notifRefreshDOM(){
|
||||
+'<input type="checkbox" data-notif-idx="'+idx+'" data-notif-ev="'+ev+'" '+checked
|
||||
+' onchange="notifToggleEvent('+idx+',\''+ev+'\')" style="width:auto;margin:0"> '+lbl+'</label>';
|
||||
}).join(' ');
|
||||
var imgCheck='<label style="display:inline-flex;align-items:center;gap:3px;font-size:11px;cursor:pointer;margin-left:4px;padding-left:8px;border-left:1px solid var(--border)" title="'+(T.settings_notif_send_image||'Send image')+'">'
|
||||
+'<input type="checkbox" '+(row.include_image?'checked':'')+' onchange="notifToggleImage('+idx+')" style="width:auto;margin:0"> '
|
||||
+'📷 '+(T.settings_notif_send_image||'Image')+'</label>';
|
||||
return '<div style="background:var(--raised);border-radius:6px;padding:8px;margin-bottom:6px">'
|
||||
+'<div style="display:flex;gap:6px;align-items:center;margin-bottom:6px">'
|
||||
+'<input type="text" value="'+_escHtml(row.url)+'" placeholder="discord://… telegram://… gotify://…"'
|
||||
@@ -919,14 +922,14 @@ function notifRefreshDOM(){
|
||||
+'<button onclick="notifTest('+idx+')" style="background:var(--raised2,var(--raised));border:1px solid var(--border);color:var(--txt);border-radius:4px;cursor:pointer;padding:2px 8px;font-size:11px" id="notif-test-btn-'+idx+'">'+(T.settings_notif_test||'Test')+'</button>'
|
||||
+'<button onclick="notifRemoveRow('+idx+')" style="background:none;border:none;color:var(--err);cursor:pointer;font-size:16px;line-height:1" title="remove">✕</button>'
|
||||
+'</div>'
|
||||
+'<div style="display:flex;flex-wrap:wrap;gap:8px">'+evChecks+'</div>'
|
||||
+'<div style="display:flex;flex-wrap:wrap;gap:8px;align-items:center">'+evChecks+imgCheck+'</div>'
|
||||
+'<div id="notif-test-status-'+idx+'" style="font-size:11px;margin-top:4px"></div>'
|
||||
+'</div>';
|
||||
}).join('');
|
||||
}
|
||||
function _escHtml(s){return (s||'').replace(/&/g,'&').replace(/</g,'<').replace(/>/g,'>').replace(/"/g,'"');}
|
||||
function notifAddRow(){
|
||||
_notifRows.push({url:'',events:['finished','failed']});
|
||||
_notifRows.push({url:'',events:['finished','failed'],include_image:false});
|
||||
notifRefreshDOM();
|
||||
}
|
||||
function notifRemoveRow(idx){
|
||||
@@ -942,9 +945,12 @@ function notifToggleEvent(idx,ev){
|
||||
var pos=evs.indexOf(ev);
|
||||
if(pos>=0)evs.splice(pos,1);else evs.push(ev);
|
||||
}
|
||||
function notifToggleImage(idx){
|
||||
if(_notifRows[idx])_notifRows[idx].include_image=!_notifRows[idx].include_image;
|
||||
}
|
||||
function notifCollect(){
|
||||
return _notifRows.filter(function(r){return r.url.trim();}).map(function(r){
|
||||
return {url:r.url.trim(),events:r.events};
|
||||
return {url:r.url.trim(),events:r.events,include_image:!!r.include_image};
|
||||
});
|
||||
}
|
||||
function notifTest(idx){
|
||||
|
||||
@@ -260,5 +260,6 @@
|
||||
"settings_notif_interval_lbl": "Wiederholungsintervall",
|
||||
"settings_notif_min_unit": "Min.",
|
||||
"settings_notif_layers_unit": "Layer",
|
||||
"settings_notif_zero_off": "(0 = aus)"
|
||||
"settings_notif_zero_off": "(0 = aus)",
|
||||
"settings_notif_send_image": "Bild"
|
||||
}
|
||||
|
||||
@@ -260,5 +260,6 @@
|
||||
"settings_notif_interval_lbl": "Repeat interval",
|
||||
"settings_notif_min_unit": "min",
|
||||
"settings_notif_layers_unit": "layers",
|
||||
"settings_notif_zero_off": "(0 = off)"
|
||||
"settings_notif_zero_off": "(0 = off)",
|
||||
"settings_notif_send_image": "Image"
|
||||
}
|
||||
|
||||
@@ -260,5 +260,6 @@
|
||||
"settings_notif_interval_lbl": "Intervalo de repetición",
|
||||
"settings_notif_min_unit": "min",
|
||||
"settings_notif_layers_unit": "capas",
|
||||
"settings_notif_zero_off": "(0 = off)"
|
||||
"settings_notif_zero_off": "(0 = off)",
|
||||
"settings_notif_send_image": "Imagen"
|
||||
}
|
||||
|
||||
@@ -260,5 +260,6 @@
|
||||
"settings_notif_interval_lbl": "重复间隔",
|
||||
"settings_notif_min_unit": "分钟",
|
||||
"settings_notif_layers_unit": "层",
|
||||
"settings_notif_zero_off": "(0 = 关闭)"
|
||||
"settings_notif_zero_off": "(0 = 关闭)",
|
||||
"settings_notif_send_image": "图片"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user