From 1d440ac7c8ec5ecf60ad189d3e1de12205d49944 Mon Sep 17 00:00:00 2001 From: nojhan Date: Wed, 19 Feb 2025 10:18:27 +0100 Subject: [PATCH 1/4] feat(MessageBox): replace vertical layout with boxes - fix: test and send use argparse. --- src/clibard/clibard.py | 46 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 5 deletions(-) diff --git a/src/clibard/clibard.py b/src/clibard/clibard.py index 0f1fb8f..44310a2 100755 --- a/src/clibard/clibard.py +++ b/src/clibard/clibard.py @@ -3,9 +3,10 @@ import copy import signal import datetime +import humanize import collections -import humanize +import rich from rich.console import Console import dbus @@ -149,6 +150,14 @@ class Message: "body": 242, } + # 🚨🚩🚧🛎 🛈 🏲 🏴📌📳🗨 🗩 🗬 🗭 🗮 🗯 🧭⚠⚲✎ � ❓❔︖🯄 + self.icons = { + "low": "🛈 ", + "normal": "🗨 ", + "critical": "🚨", + "unknown": "🯄 ", + } + self._style = {} for k in self.color: self._style[k] = f"color({self.color[k]})" @@ -235,6 +244,33 @@ class MessageParagraph(Message): return len(hdate) + len(self.app) + len(self.summary) + len(self.body) + 6 +class MessageBox(Message): + def print_on(self, console = None, end = ""): + hdate = self.date.strftime("%Y-%m-%d %H:%M") + if console != None: + # Automated black or white foreground. + if Color.ansi_lightness(self.color[self.urgency]) >= 50: + fg = "black" + else: + fg = "white" + summ_color = f"{fg} on color({self.color[self.urgency]})" + body_color = f"color({self.color['summary_'+self.urgency]})" + title = f"{self.icons[self.urgency]} ─[{summ_color}]{self.summary}[/]─ {self.app}" + # title = f"[{summ_color}]{self.summary}[/]─ {self.app}" + box = rich.panel.Panel( + f"[{body_color}]{self.body}[/]", + title=title, + title_align="left", + # subtitle = self.icons[self.urgency], + # subtitle_align = "left", + border_style=f"color({self.color[self.urgency]})", + safe_box = False, + ) + console.print(box) + + return len(hdate) + len(self.app) + len(self.summary) + len(self.body) + 6 + + class Broker: def __init__(self, max_msg = 100, bounds = "", msg_cls = Message): @@ -382,8 +418,8 @@ if __name__ == "__main__": if asked.layout[0] == "h": broker = HorizontalBroker(bounds = "><") elif asked.layout[0] == "v": - broker = VerticalBroker(bounds = "><") - notifs = test_messages(int(sys.argv[2])) + broker = VerticalBroker(bounds = "><", msg_cls=MessageBox) + notifs = test_messages(int(asked.test)) for notif in notifs: broker.receive(None, notif) print("\n", end="") @@ -391,7 +427,7 @@ if __name__ == "__main__": elif asked.send: import os import time - notifs = test_messages(int(sys.argv[2])) + notifs = test_messages(int(asked.send)) for notif in notifs: m = Message(notif) os.system(f"""notify-send "{m.summary}" "{m.body}" -u {m.urgency}""") @@ -402,5 +438,5 @@ if __name__ == "__main__": broker.run() elif asked.layout[0] == "v": - broker = VerticalBroker() + broker = VerticalBroker(msg_cls=MessageBox) broker.run() From 7b80153d154b0b552971631d56eb05915cb56a4e Mon Sep 17 00:00:00 2001 From: nojhan Date: Wed, 19 Feb 2025 10:39:36 +0100 Subject: [PATCH 2/4] feat(MessageBox): use a hashed color for summaries --- src/clibard/clibard.py | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/clibard/clibard.py b/src/clibard/clibard.py index 44310a2..cb8baa8 100755 --- a/src/clibard/clibard.py +++ b/src/clibard/clibard.py @@ -209,6 +209,19 @@ class Message: self.last_color = f"{self.style(key)}" + def auto_fg(self, bg): + # Automated black or white foreground. + if Color.ansi_lightness(bg) >= 50: + return "black" + else: + return "white" + + def hash_color(self, text, colors = None): + if not colors: + return hash(text) % 256 + else: + return colors[hash(text) % len(colors)] + class MessageLine(Message): def print_on(self, console = None, end = ""): @@ -248,15 +261,17 @@ class MessageBox(Message): def print_on(self, console = None, end = ""): hdate = self.date.strftime("%Y-%m-%d %H:%M") if console != None: - # Automated black or white foreground. - if Color.ansi_lightness(self.color[self.urgency]) >= 50: - fg = "black" - else: - fg = "white" - summ_color = f"{fg} on color({self.color[self.urgency]})" + # summ_color = f"{self.auto_fg(FIXME)} on color({self.color[self.urgency]})" body_color = f"color({self.color['summary_'+self.urgency]})" - title = f"{self.icons[self.urgency]} ─[{summ_color}]{self.summary}[/]─ {self.app}" + + bg = self.hash_color(self.summary) + sfg = f"{self.auto_fg(bg)} on color({bg})" + sfgi = f"color({bg})" + summ = f"─[{sfgi}][/][{sfg}]{self.summary}[/][{sfgi}][/]─" + + title = f"{self.icons[self.urgency]} {summ} {self.app}" # title = f"[{summ_color}]{self.summary}[/]─ {self.app}" + box = rich.panel.Panel( f"[{body_color}]{self.body}[/]", title=title, From ddfe1c6eb6044a115862bbdc98eef439e2ca0f82 Mon Sep 17 00:00:00 2001 From: nojhan Date: Thu, 13 Mar 2025 16:30:25 +0100 Subject: [PATCH 3/4] feat(box): color based on the hash of the app Instead of based on the urgency. --- src/clibard/clibard.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/clibard/clibard.py b/src/clibard/clibard.py index cb8baa8..8613bbe 100755 --- a/src/clibard/clibard.py +++ b/src/clibard/clibard.py @@ -272,13 +272,15 @@ class MessageBox(Message): title = f"{self.icons[self.urgency]} {summ} {self.app}" # title = f"[{summ_color}]{self.summary}[/]─ {self.app}" + bs = self.hash_color(self.app) + box = rich.panel.Panel( f"[{body_color}]{self.body}[/]", title=title, title_align="left", # subtitle = self.icons[self.urgency], # subtitle_align = "left", - border_style=f"color({self.color[self.urgency]})", + border_style=f"color({bs})", safe_box = False, ) console.print(box) From 3e58cde2fe919e985a8df2fa56fd4aa75097895e Mon Sep 17 00:00:00 2001 From: nojhan Date: Wed, 8 Apr 2026 08:29:12 +0200 Subject: [PATCH 4/4] refactor: move to uv instead of poetry --- README.md | 2 ++ pyproject.toml | 33 ++++++++++++++++++++++++--------- src/clibard/clibard.py | 6 +++++- 3 files changed, 31 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index b3fe9a6..db495ef 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,8 @@ The CLI bard relies on your terminal using a font patched with the "Powerline" characters. The recommended fonts are the ones from the [Nerd font project](https://www.nerdfonts.com/). +You may also need to install the `libgirepository-2.0-dev` on your system. + Usage ===== diff --git a/pyproject.toml b/pyproject.toml index b959cb2..3ca614c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,15 +1,30 @@ -[tool.poetry] +[project] name = "clibard" version = "0.1.0" description = "See all your notifications in the terminal" -authors = ["nojhan "] +authors = [ + { name = "nojhan", email = "nojhan@nojhan.net" }, +] readme = "README.md" -[tool.poetry.dependencies] -python = "^3.11" -faker = "^0.7.4" -humanize = "^4.11" -rich = "^13.9" -dbus-python = "^1.3" -PyGObject = "^3.50" # You may need to install the system package for libgirepository1.0-dev +requires-python = ">3.11" +dependencies = [ + "faker>=0.7.4", + "humanize>=4.11", + "rich>=13.9", + "dbus-python>=1.3", + "PyGObject>=3.50", # You may need to install the system package for libgirepository-2.0-dev +] + +[project.scripts] +clibard = "clibard.clibard:main" + + +[build-system] +requires = ["setuptools>=68", "wheel"] +build-backend = "setuptools.build_meta" + +[tool.setuptools.packages.find] +where = ["src"] +include = ["clibard"] diff --git a/src/clibard/clibard.py b/src/clibard/clibard.py index 8613bbe..45d05c8 100755 --- a/src/clibard/clibard.py +++ b/src/clibard/clibard.py @@ -414,7 +414,7 @@ def test_messages(nb = 7): return notifs -if __name__ == "__main__": +def main(): import sys import argparse @@ -457,3 +457,7 @@ if __name__ == "__main__": elif asked.layout[0] == "v": broker = VerticalBroker(msg_cls=MessageBox) broker.run() + + +if __name__ == "__main__": + main()