feat(notify): value-first emoji rows
ci / docker (push) Successful in 24s
test / komodo-deploy-script (push) Successful in 26s
test / komodo-deploy-script (pull_request) Successful in 16s

Switch the summary to the layout jblu picked: each counter renders as
"emoji value label", grouped two per line and joined by a middle dot.

    Scanned 42 torrents in 12s

    🗑️ 7 removed  ·  👻 4 orphaned
    ⏭️ 5 ignored  ·  🐣 3 premature

    🛡️ 10 protected  ·  🌐 20 public

- the value leads, so the numbers are the first thing the eye lands on
- html style now bolds the values instead of the labels
- "Non-protected" reads as "public", matching the non_protected_tag
- use_emoji now defaults to true; false gives the plain variant
- dry runs read "7 would be removed"
This commit is contained in:
trex Bot committed 2026-11-03 15:10:03 -06:00
1 parent 5d9da0d22b
commit dfce115fd8
5 files changed
+90 -51

No files matched your search

+20 -15
View File
@@ -155,7 +155,7 @@ def get_notify_options(self):
priority = po.get("priority")
return {
"style": style,
"use_emoji": bool(po.get("use_emoji", False)),
"use_emoji": bool(po.get("use_emoji", True)),
"include_hostname": bool(po.get("include_hostname", False)),
"notify_on_empty": bool(po.get("notify_on_empty", True)),
"priority": None if priority is None else int(priority),
@@ -214,7 +214,10 @@ def debug_torrent_list(self):
def _stat_row(pairs, style, use_emoji):
"""Render one line of ``Label value`` pairs joined by a middle dot.
"""Render one line of ``emoji value label`` pairs joined by a middle dot.
The value leads and the label trails, so the numbers are the first thing
the eye lands on even though the font is proportional.
Args:
pairs: Sequence of ``(emoji_key, label, value)`` tuples.
@@ -222,31 +225,33 @@ def _stat_row(pairs, style, use_emoji):
use_emoji: Prefix each pair with its emoji marker.
Returns:
A single line of text, e.g. ``Removed 7 \u00b7 Orphaned 4``.
A single line of text, e.g.
``\U0001F5D1\uFE0F 7 removed \u00b7 \U0001F47B 4 orphaned``.
"""
parts = []
for key, label, value in pairs:
emoji = NOTIFY_EMOJI.get(key, "") if use_emoji else ""
prefix = f"{emoji} " if emoji else ""
if style == "html":
parts.append(f"{prefix}<b>{label}</b> {value}")
parts.append(f"{prefix}<b>{value}</b> {label}")
else:
parts.append(f"{prefix}{label} {value}")
parts.append(f"{prefix}{value} {label}")
return ROW_SEPARATOR.join(parts)
def build_summary(self, style=DEFAULT_NOTIFY_STYLE, use_emoji=False,
def build_summary(self, style=DEFAULT_NOTIFY_STYLE, use_emoji=True,
include_hostname=False):
"""Build the ``(title, body)`` pair used by every notifier.
Result-first layout: the title states what happened, the body gives the
scanned total, the actionable counters, then the tracker split. Counters
are grouped two-per-line and separated by a middle dot, because Pushover
renders a proportional font and space-padded columns do not line up.
are grouped two-per-line as ``emoji value label`` and separated by a middle
dot, because Pushover renders a proportional font and space-padded columns
do not line up.
Args:
style: ``"plain"`` for grouped text, ``"html"`` for Pushover HTML.
use_emoji: Prefix each row with an emoji marker.
use_emoji: Prefix each counter with an emoji marker.
include_hostname: Add a ``Host:`` line above the summary.
Returns:
@@ -286,19 +291,19 @@ def build_summary(self, style=DEFAULT_NOTIFY_STYLE, use_emoji=False,
lines.append(f"Scanned {total} {scanned_noun} in {stats['runtime']}")
lines.append("")
removed_label = "Removed" if delete_enabled else "Would remove"
removed_label = "removed" if delete_enabled else "would be removed"
lines.append(_stat_row([
("removed", removed_label, removed),
("orphaned", "Orphaned", stats["orphaned"]),
("orphaned", "orphaned", stats["orphaned"]),
], style, use_emoji))
lines.append(_stat_row([
("ignored", "Ignored", stats["ignored"]),
("premature", "Premature", stats["premature"]),
("ignored", "ignored", stats["ignored"]),
("premature", "premature", stats["premature"]),
], style, use_emoji))
lines.append("")
lines.append(_stat_row([
("protected", "Protected", stats["protected"]),
("non_protected", "Non-protected", stats["non_protected"]),
("protected", "protected", stats["protected"]),
("non_protected", "public", stats["non_protected"]),
], style, use_emoji))
return title, "\n".join(lines)