aboutsummaryrefslogtreecommitdiffstats
path: root/sb_builder/fmt.py
diff options
context:
space:
mode:
Diffstat (limited to 'sb_builder/fmt.py')
-rw-r--r--sb_builder/fmt.py61
1 files changed, 61 insertions, 0 deletions
diff --git a/sb_builder/fmt.py b/sb_builder/fmt.py
new file mode 100644
index 0000000..d43da2e
--- /dev/null
+++ b/sb_builder/fmt.py
@@ -0,0 +1,61 @@
+# sb-builder - formatting helpers
+# Copyright (C) 2026 Danilo M. <danix@danix.xyz>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License version 2 as
+# published by the Free Software Foundation.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License along
+# with this program; if not, write to the Free Software Foundation, Inc.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+"""Text formatting shared by the tabs."""
+
+import time
+
+NA = "n/a"
+ICON = {"starting": "…", "running": "▶", "ok": "✔", "failed": "✘",
+ "killed": "■", "lost": "?"}
+
+
+def fmt_bytes(n):
+ if n is None:
+ return NA
+ for unit in ("B", "KiB", "MiB", "GiB"):
+ if n < 1024:
+ return f"{n:.0f} {unit}" if unit == "B" else f"{n:.1f} {unit}"
+ n /= 1024
+ return f"{n:.1f} TiB"
+
+
+def fmt_duration(secs):
+ if secs is None:
+ return NA
+ d, r = divmod(int(secs), 86400)
+ h, r = divmod(r, 3600)
+ m, s = divmod(r, 60)
+ return f"{d}d {h}h" if d else f"{h}h {m}m" if h else f"{m}m {s}s"
+
+
+def fmt_age(ts):
+ return NA if ts is None else fmt_duration(time.time() - ts) + " ago"
+
+
+def fmt_time(ts):
+ return time.strftime("%m-%d %H:%M", time.localtime(ts))
+
+
+def job_title(j):
+ return " ".join([j["kind"], *j["args"]])
+
+
+def describe(j):
+ """One-line job summary: icon, kind and args, start time, duration."""
+ dur = None if "start" not in j else j.get("end", time.time()) - j["start"]
+ return (f"{ICON.get(j['status'], '?')} {job_title(j)} "
+ f"{fmt_time(j.get('start', j['created']))} {fmt_duration(dur)}")