1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
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)}")
|