Files
Das-OS/tools/make-banner-presets.py
dasandClaude Opus 5.5 a2bffc7fe9
build / build (push) Successful in 38m26s
Terminal: Das prompt, dprompt and dbanner (0.9.1)
- das-shell 0.1.0: the Das two-line bash prompt by default (replaces the
  PS1 of Void's skel .bashrc once), dprompt (Textual prompt builder with
  presets and live preview) and dbanner (SSH login banner editor: canvas
  tools, fields with values, widgets, das-banner service for cached ones,
  Das OS logo and tryzub pictures). Python tests in make test.
- das-server 0.3.0 depends on das-shell; the server installer mentions
  dprompt and dbanner; the desktop image includes it.
- run-qemu.sh forwards the guest's SSH to localhost:2222.
- Hardware fixes: Ventoy menu icon, boot menu titles "Das OS <version>".

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 09:17:10 +03:00

170 lines
6.8 KiB
Python

#!/usr/bin/env python3
"""Writes the ready-made dbanner designs to srcpkgs/das-shell/files/share/banner/presets.
The designs are drawn with the same Grid that the editor uses, so they stay
editable in dbanner. Run after changing this file or the pictures in
share/banner/art (tools/art/build.sh).
"""
import os
import sys
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
FILES = os.path.join(ROOT, "srcpkgs", "das-shell", "files")
sys.path.insert(0, os.path.join(FILES, "python"))
from das_shell import banner # noqa: E402
OUT = os.path.join(FILES, "share", "banner", "presets")
def art(name):
return banner.Grid.from_design(banner.load_file(os.path.join(FILES, "share", "banner", "art", name + ".json")))
def field(grid, x, y, width, text, fg=None, bold=False, bg=None, align="left", font=None):
f = {"x": x, "y": y, "width": width, "align": align, "text": text,
"style": grid.style_key(fg, bg, bold)}
if font:
f["font"] = font
return f
def builtin(name, **extra):
return dict({"type": "builtin", "name": name}, **extra)
def save(name, uk, en, grid, fields, widgets, vars_=None, position="below"):
d = {"name": name, "title": {"uk": uk, "en": en}, "local": False, "vars": vars_ or {},
"fields": fields, "widgets_position": position, "widgets": widgets}
d = grid.to_design(d)
banner.save(d, os.path.join(OUT, name + ".json"))
def das_classic():
# The frame of the banner on the author's home server
g = banner.Grid(39, 5)
frame = g.style_key("blue")
g.box(0, 0, 38, 4, "hash", frame)
red = g.style_key("red", None, True)
g.text(7, 2, "Server IP:", red)
g.text(7, 3, "Link:", red)
fields = [
field(g, 2, 1, 35, "-=:dAs:=- {title}", "white", True, align="center"),
field(g, 18, 2, 19, "{ip}", "cyan", True),
field(g, 13, 3, 24, "{url}", "cyan", True),
]
widgets = [builtin("uptime"), builtin("disks"), builtin("memory"), builtin("docker"),
builtin("services"), builtin("updates")]
save("das-classic", "Das класичний: рамка з #, назва, IP, посилання", "Das classic: # frame, name, IP, link",
g, fields, widgets, {"title": "Das OS", "url": "https://das.org.ua/"})
def double():
w = 64
g = banner.Grid(w, 10)
cyan = g.style_key("cyan", None, True)
g.box(0, 0, w - 1, 9, "double", cyan)
g.text(1, 7, "─" * (w - 2), g.style_key("bright_black"))
fields = [
field(g, 2, 1, w - 4, "{hostname}", "bright_white", True, align="center", font="small"),
field(g, 2, 5, w - 4, "{title}", "yellow", True, align="center"),
field(g, 2, 6, w - 4, "{url}", "cyan", align="center"),
field(g, 2, 8, w - 4, "IP {ip} · {os} · {kernel}", "white", align="center"),
]
widgets = [builtin("uptime"), builtin("load"), builtin("memory"), builtin("disks"), builtin("services")]
save("double", "Подвійна рамка з великим ім'ям сервера", "Double frame with the server name in big letters",
g, fields, widgets, {"title": "Das OS Server", "url": ""})
def info_column(g, x, y, width, label_fg, value_fg, rows):
fields = []
for i, (label, value) in enumerate(rows):
if label is None:
fields.append(field(g, x, y + i, width, value, label_fg))
continue
fields.append(field(g, x, y + i, 9, label, label_fg, True))
fields.append(field(g, x + 9, y + i, width - 9, value, value_fg))
return fields
def blocks():
logo = art("das-logo")
g = banner.Grid(76, max(logo.height, 12))
g.stamp(0, 0, logo)
x = logo.width + 4
fields = [field(g, x, 0, 76 - x, "{user}@{hostname}", "bright_cyan", True)]
fields += info_column(g, x, 1, 76 - x, "bright_blue", "white", [
(None, "─" * 30),
("[[ОС|OS]]", "{os}"),
("[[Ядро|Kernel]]", "{kernel}"),
("[[Працює|Uptime]]", "{uptime}"),
("CPU", "{cpu}"),
("[[Пам'ять|Memory]]", "{mem}"),
("IP", "{ips}"),
("[[Вхід|Users]]", "{users}"),
])
fields.append(field(g, x, 10, 76 - x, "{url}", "yellow"))
save("blocks", "Логотип Das OS і відомості про систему", "Das OS logo and system facts",
g, fields, [builtin("disks")], {"url": ""})
def dashboard():
w = 70
g = banner.Grid(w, 3)
g.box(0, 0, w - 1, 2, "rounded", g.style_key("bright_blue"))
fields = [field(g, 2, 1, w - 4, "{hostname} · {ip} · {url}", "bright_white", True, align="center")]
widgets = [builtin(n) for n in ("uptime", "load", "memory", "disks", "network", "docker", "updates",
"weather", "smart", "services", "fail2ban", "snapshots", "lastlog")]
save("dashboard", "Панель: усі віджети під заголовком", "Dashboard: every widget under a header",
g, fields, widgets, {"url": "", "city": "Kyiv"})
def minimal():
g = banner.Grid(70, 1)
fields = [field(g, 0, 0, 70, "{hostname} · {ip} · [[працює|up]] {uptime} · {load}", "bright_cyan", True)]
save("minimal", "Мінімальний: один рядок", "Minimal: one line", g, fields, [])
def ukraine():
shield = art("trident-shield")
g = banner.Grid(80, shield.height)
g.stamp(0, 0, shield)
x = shield.width + 4
blue, yellow = "bright_blue", "bright_yellow"
fields = [
field(g, x, 1, 80 - x, "{hostname}", yellow, True, font="small"),
field(g, x, 6, 80 - x, "[[Слава Україні!|Glory to Ukraine!]]", blue, True),
]
fields += info_column(g, x, 8, 80 - x, blue, yellow, [
("IP", "{ip}"),
("[[Сайт|Site]]", "{url}"),
("[[Працює|Uptime]]", "{uptime}"),
("[[Пам'ять|Memory]]", "{mem}"),
("[[ОС|OS]]", "{os}"),
])
save("ukraine", "Тризуб: малий герб України і дані сервера", "Tryzub: Ukrainian coat of arms and server facts",
g, fields, [builtin("disks"), builtin("services")], {"url": ""})
def tryzub_small():
# A compact one for small screens: the small tryzub, a few lines of text
tz = art("trident-small")
g = banner.Grid(60, tz.height)
g.stamp(0, 0, tz)
x = tz.width + 3
fields = [
field(g, x, 2, 60 - x, "{hostname}", "bright_yellow", True),
field(g, x, 3, 60 - x, "{ip}", "bright_blue", True),
field(g, x, 5, 60 - x, "[[Працює|Uptime]]: {uptime}", "white"),
field(g, x, 6, 60 - x, "{url}", "bright_blue"),
]
save("tryzub", "Малий тризуб з іменем і IP", "Small tryzub with name and IP", g, fields,
[builtin("disks")], {"url": ""})
if __name__ == "__main__":
os.makedirs(OUT, exist_ok=True)
for make in (das_classic, double, blocks, dashboard, minimal, ukraine, tryzub_small):
make()