Create Thüringen branding edition on shared core
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
__pycache__/
|
||||
*.py[cod]
|
||||
*.egg-info/
|
||||
.pytest_cache/
|
||||
.venv/
|
||||
build/
|
||||
dist/
|
||||
.env
|
||||
@@ -0,0 +1,3 @@
|
||||
[submodule "vendor/synadm-tui"]
|
||||
path = vendor/synadm-tui
|
||||
url = https://git.blackwall.ipv64.de/pan/synadm-tui.git
|
||||
@@ -0,0 +1,19 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2026 synadm-tui contributors
|
||||
|
||||
This program is free software: you can redistribute it and/or modify it
|
||||
under the terms of the GNU General Public License as published by the Free
|
||||
Software Foundation, either version 3 of the License, or (at your option)
|
||||
any later version.
|
||||
|
||||
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. The complete license text is available at:
|
||||
https://www.gnu.org/licenses/gpl-3.0.txt
|
||||
|
||||
SPDX-License-Identifier: GPL-3.0-or-later
|
||||
@@ -0,0 +1,44 @@
|
||||
# synadm TUI – Thüringen Edition
|
||||
|
||||
Die Thüringen Edition ergänzt den unveränderten Anwendungskern von [`synadm-tui`](https://git.blackwall.ipv64.de/pan/synadm-tui) um das Thüringen-Thema, das Wappen und getrennte Release-Pakete.
|
||||
|
||||
Programmlogik, Navigation, Assistenten und Sicherheitsfunktionen werden nicht kopiert. Das Repository bindet einen geprüften `synadm-tui`-Stand als Git-Submodul ein; dadurch bleiben beide Editionen funktional identisch.
|
||||
|
||||
## Quellcode testen
|
||||
|
||||
```bash
|
||||
git clone --recurse-submodules https://git.blackwall.ipv64.de/pan/synadm-tui-thueringen.git
|
||||
cd synadm-tui-thueringen
|
||||
PYTHONPATH=vendor/synadm-tui python3 -m unittest discover -v
|
||||
PYTHONPATH=vendor/synadm-tui python3 -m synadm_tui_thueringen --version
|
||||
```
|
||||
|
||||
## Native Datei und Pakete bauen
|
||||
|
||||
```bash
|
||||
python3 -m pip install pyinstaller
|
||||
python3 scripts/build_native.py
|
||||
python3 scripts/build_packages.py
|
||||
cd dist/packages && sha256sum --check SHA256SUMS
|
||||
```
|
||||
|
||||
## Pakete ohne Runner veröffentlichen
|
||||
|
||||
```bash
|
||||
python3 scripts/publish_packages.py --tea-login Building --dry-run
|
||||
python3 scripts/publish_packages.py --tea-login Building
|
||||
```
|
||||
|
||||
DEB-Pakete werden in die Distribution `thueringen`, RPM-Pakete in die Gruppe `thueringen` veröffentlicht. Dadurch bleiben auch die Paketquellen von der Standard Edition getrennt.
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
- Linux x86-64 oder ARM64
|
||||
- Python 3.10+ für den Quellstart
|
||||
- PyInstaller für native Builds
|
||||
- `dpkg-deb` und `rpmbuild` für Systempakete
|
||||
- separat installiertes `synadm`, wahlweise über den integrierten Installationsassistenten
|
||||
|
||||
## Lizenz
|
||||
|
||||
GPL-3.0-or-later, siehe `LICENSE`.
|
||||
@@ -0,0 +1,29 @@
|
||||
[build-system]
|
||||
requires = ["setuptools>=68"]
|
||||
build-backend = "setuptools.build_meta"
|
||||
|
||||
[project]
|
||||
name = "synadm-tui-thueringen"
|
||||
version = "0.15"
|
||||
description = "Thüringen-Edition der Terminal-Oberfläche für synadm"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.10"
|
||||
license = { text = "GPL-3.0-or-later" }
|
||||
authors = [{ name = "synadm-tui contributors" }]
|
||||
dependencies = ["synadm-tui==0.15"]
|
||||
classifiers = [
|
||||
"Environment :: Console :: Curses",
|
||||
"Programming Language :: Python :: 3",
|
||||
]
|
||||
|
||||
[project.scripts]
|
||||
synadm-tui-thueringen = "synadm_tui_thueringen.cli:main"
|
||||
|
||||
[tool.setuptools.packages.find]
|
||||
include = ["synadm_tui_thueringen*"]
|
||||
|
||||
[tool.setuptools.package-data]
|
||||
synadm_tui_thueringen = ["assets/*.png", "assets/*.block.json"]
|
||||
|
||||
[tool.unittest]
|
||||
start-directory = "tests"
|
||||
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Regenerate the portable 256-color crest data."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
ASSETS = ROOT / "synadm_tui_thueringen" / "assets"
|
||||
PIXEL = re.compile(r"#([0-9A-Fa-f]{8})\s")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
process = subprocess.run(
|
||||
["convert", str(ASSETS / "thueringen-wappen.png"), "-filter", "Lanczos", "-resize", "18x20!", "txt:-"],
|
||||
check=True,
|
||||
text=True,
|
||||
stdout=subprocess.PIPE,
|
||||
)
|
||||
pixels = [match.group(1).lower() for line in process.stdout.splitlines() if (match := PIXEL.search(line))]
|
||||
if len(pixels) != 18 * 20:
|
||||
raise RuntimeError(f"360 Pixel erwartet, {len(pixels)} erhalten")
|
||||
target = ASSETS / "thuringia.block.json"
|
||||
target.write_text(
|
||||
json.dumps({"width": 18, "height": 20, "pixels": pixels}, separators=(",", ":")) + "\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
print(target)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,52 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build the Thüringen binary against the pinned synadm-tui core."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
import PyInstaller.__main__
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
CORE = Path(os.environ.get("SYNADM_TUI_CORE", ROOT / "vendor" / "synadm-tui")).resolve()
|
||||
|
||||
|
||||
def main() -> int:
|
||||
if not (CORE / "synadm_tui" / "app.py").is_file():
|
||||
raise SystemExit("synadm-tui-Core fehlt; git submodule update --init ausführen.")
|
||||
arguments = [
|
||||
str(ROOT / "scripts" / "standalone_entry.py"),
|
||||
"--name=synadm-tui-thueringen",
|
||||
"--onefile",
|
||||
"--clean",
|
||||
f"--paths={ROOT}",
|
||||
f"--paths={CORE}",
|
||||
f"--distpath={ROOT / 'dist'}",
|
||||
f"--workpath={ROOT / 'build' / 'pyinstaller'}",
|
||||
f"--specpath={ROOT / 'build'}",
|
||||
]
|
||||
for asset in (
|
||||
"retro-cyberspace.png",
|
||||
"hacker-terminal.png",
|
||||
"cyberspace.block.json",
|
||||
"hacker.block.json",
|
||||
):
|
||||
arguments.append(f"--add-data={CORE / 'synadm_tui' / 'assets' / asset}:synadm_tui/assets")
|
||||
for asset in ("thueringen-wappen.png", "thuringia.block.json"):
|
||||
arguments.append(
|
||||
f"--add-data={ROOT / 'synadm_tui_thueringen' / 'assets' / asset}:synadm_tui_thueringen/assets"
|
||||
)
|
||||
PyInstaller.__main__.run(arguments)
|
||||
artifact = ROOT / "dist" / "synadm-tui-thueringen"
|
||||
checksum = hashlib.sha256(artifact.read_bytes()).hexdigest()
|
||||
(ROOT / "dist" / "SHA256SUMS").write_text(
|
||||
f"{checksum} synadm-tui-thueringen\n", encoding="utf-8"
|
||||
)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,34 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Build DEB and RPM packages by reusing the pinned core's packaging code."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
CORE = Path(os.environ.get("SYNADM_TUI_CORE", ROOT / "vendor" / "synadm-tui")).resolve()
|
||||
SPEC = importlib.util.spec_from_file_location("synadm_core_build_packages", CORE / "scripts" / "build_packages.py")
|
||||
if not SPEC or not SPEC.loader:
|
||||
raise SystemExit("Paketierungsmodul des synadm-tui-Core fehlt.")
|
||||
module = importlib.util.module_from_spec(SPEC)
|
||||
sys.modules[SPEC.name] = module
|
||||
SPEC.loader.exec_module(module)
|
||||
module.ROOT = ROOT
|
||||
module.DIST = ROOT / "dist"
|
||||
module.OUTPUT = module.DIST / "packages"
|
||||
module.HOMEPAGE = "https://git.blackwall.ipv64.de/pan/synadm-tui-thueringen"
|
||||
module.EDITIONS = (
|
||||
module.Edition(
|
||||
"synadm-tui-thueringen",
|
||||
"synadm-tui-thueringen",
|
||||
"Thüringen-Edition der synadm Terminal-Oberfläche",
|
||||
"Regionales Branding auf dem unveränderten Anwendungskern von synadm-tui.",
|
||||
),
|
||||
)
|
||||
|
||||
|
||||
raise SystemExit(module.main())
|
||||
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Publish Thüringen packages via the pinned core's secure uploader."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib.util
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parent.parent
|
||||
CORE = Path(os.environ.get("SYNADM_TUI_CORE", ROOT / "vendor" / "synadm-tui")).resolve()
|
||||
SPEC = importlib.util.spec_from_file_location("synadm_core_publish_packages", CORE / "scripts" / "publish_packages.py")
|
||||
if not SPEC or not SPEC.loader:
|
||||
raise SystemExit("Uploadmodul des synadm-tui-Core fehlt.")
|
||||
module = importlib.util.module_from_spec(SPEC)
|
||||
sys.modules[SPEC.name] = module
|
||||
SPEC.loader.exec_module(module)
|
||||
module.ROOT = ROOT
|
||||
module.PACKAGE_DIR = ROOT / "dist" / "packages"
|
||||
module.DEFAULT_DISTRIBUTION = "thueringen"
|
||||
module.DEFAULT_RPM_GROUP = "thueringen"
|
||||
|
||||
|
||||
raise SystemExit(module.main())
|
||||
@@ -0,0 +1,6 @@
|
||||
"""PyInstaller entry point for the Thüringen edition."""
|
||||
|
||||
from synadm_tui_thueringen.cli import main
|
||||
|
||||
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,3 @@
|
||||
"""Branding extension for the Thüringen edition of synadm TUI."""
|
||||
|
||||
__version__ = "0.15"
|
||||
@@ -0,0 +1,4 @@
|
||||
from .cli import main
|
||||
|
||||
|
||||
raise SystemExit(main())
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 49 KiB |
@@ -0,0 +1 @@
|
||||
{"width":18,"height":20,"pixels":["15678fff","1875a4ff","18729fff","1774a2ff","076899ff","106f9fff","1874a4ff","206c8bff","1b6e96ff","296e80ff","1f6f91ff","277087ff","1072a4ff","076796ff","1472a1ff","1775a4ff","1678a8ff","166891ff","1878a7ff","1c89c0ff","1c87beff","1e81b3ff","86a9bbff","4b90b2ff","1081c0ff","318893ff","66853eff","97a32bff","6c873bff","33858aff","3187b9ff","96b1bdff","3186b1ff","1e7bacff","217fb0ff","177bacff","1a739fff","1d85b4ff","0f80b0ff","267aa0ff","d4ceceff","759bafff","0083c1ff","566075ff","d03c06ff","dd470cff","ce3a05ff","5d4958ff","3f8cb0ff","dad2ceff","2290bfff","7c4546ff","cb3010ff","10719fff","1276a4ff","505c5cff","8d341cff","206887ff","0d7bb3ff","1d7babff","37607dff","902f1eff","9d1200ff","d92607ff","f32000ff","78494aff","0687c4ff","136995ff","64505bff","bc311bff","665a68ff","1178a9ff","176f93ff","5f7473ff","c69f9aff","8facbdff","3187b2ff","1281b8ff","275f84ff","4f6779ff","8a959bff","d5bdb8ff","e7c4baff","7c94a4ff","127cb0ff","a4abb1ff","636777ff","286e94ff","1386bcff","1877a7ff","1774a3ff","257993ff","5a8691ff","f7eeecff","d5d5d4ff","6f95a7ff","5fa2c1ff","4891b2ff","a2bdc9ff","f0f8f9ff","f4fbfbff","6c9cb2ff","91a4afff","94bacbff","0076b4ff","cdccccff","a1b3beff","096a9aff","1976a5ff","0b80bbff","186691ff","a34635ff","b93f25ff","ca4527ff","ea512eff","de4b2aff","d6482aff","d2482bff","e24422ff","795051ff","3281a8ff","a73f2cff","30698dff","549cbdff","5091b2ff","1272a2ff","106c9aff","83a6b8ff","74a3baff","145d86ff","a52006ff","e12300ff","e42500ff","e42500ff","e62500ff","e52800ff","f52100ff","744749ff","0086c8ff","375876ff","b0331bff","2a5d7fff","0e81b9ff","1976a4ff","0e6a99ff","9fb9c9ff","95b0bdff","006ea6ff","868d97ff","c6a39bff","c6aca7ff","ceaba2ff","ceb0aaff","bda39eff","cfa79dff","53829dff","4a8bacff","87b4c7ff","2e698bff","afa1a1ff","b4c1c7ff","3f7895ff","19749dff","257a9aff","1c78a3ff","89acbeff","eff3f3ff","e7e9e9ff","dadadaff","a4c8d7ff","ccdadeff","e0ebeeff","ebefeeff","4f91afff","5398b9ff","d0d1d0ff","097db2ff","93b7c7ff","4f8cabff","1d719aff","147093ff","7a4d37ff","d43b1fff","b6523cff","b6462fff","ae4f3eff","426b84ff","435f7aff","795554ff","c54a30ff","d75033ff","ce472bff","525769ff","1e6f9aff","605766ff","864943ff","0f86bfff","1777a7ff","1d728fff","5e5247ff","78412fff","37565eff","235e81ff","235171ff","9b2e1eff","ee2300ff","ef2900ff","ce1f00ff","d11c00ff","eb2200ff","e92600ff","a03a2bff","834441ff","346c8eff","1c84b7ff","1976a4ff","1e739dfd","1285bbff","107499ff","097eb7ff","4391b6ff","cdbbb7ff","e8b4a7ff","d4b4aeff","7f7b83ff","988b8dff","ddbdb6ff","dabab3ff","b19b9aff","1679abff","0e81b7ff","d4d4d3ff","8caabaff","0a6b9cfe","1974a1e3","2a80abff","cbc9ccfe","5d93aeff","1278acff","659fbbff","ecfcffff","bfd9e2ff","007bb9ff","579cbdff","fff5f0ff","fcfcfbff","b8d5dfff","107cafff","117bafff","6694acfe","458eb2ff","176f9ae6","1d688da4","237fadff","a1b4bdfc","4c8eb2ff","048acbff","236e97ff","cb462aff","da4a2bff","8b3f37ff","326281ff","845957ff","9a564dff","dc4f30ff","bf3d22ff","8d392eff","0a74a9fc","1382b9ff","23698ca7","304e5e37","1a79a9fe","097ab4fc","227490fe","34647dff","7a3e3fff","fc2300ff","dd2600ff","685059ff","1682b7ff","1181baff","156d9cff","ca1e00ff","fd2500ff","82423dfe","1785bafc","1e7ba9ff","2b4c5d3a","1286b400","24627f93","1683beff","4a7569f9","cc9579fe","e6b1a3ff","95817eff","266082ff","0b7bafff","1880b5ff","1d82b2ff","4289acff","d5b8b6ff","9e8170fe","1173a4f9","1a86bbff","22618297","0b8dbe00","12749e03","5d000006","1c678fb5","237895ff","64928dff","6799a4fc","298298fd","197fb5ff","d6ccc7ff","6e9ebbff","1b6a7cff","c9b596fd","e7e4dbfc","4d8d92ff","147eb0ff","22678bb9","41000007","12739d03","2b4a5b01","00ffff00","8d000003","1c5e8483","116e9df0","0e79b0ff","1883bbff","1e80b0ff","85a9bbff","4d92b6ff","147bacff","487e85ff","337686ff","1472aaf1","235d7a85","6f000004","00ffff00","2a4a5c01","244e6400","363e4101","00ffff00","0b85c900","39383926","265f7c84","1f6c92ca","1c74a1f0","0a6a99fe","1170a0fe","1e75a0f1","116999cb","145e8985","38362d27","1483b800","ff000000","2f404a01","244f6600"]}
|
||||
@@ -0,0 +1,11 @@
|
||||
"""Entry point for the Thüringen edition."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from synadm_tui.cli import main as core_main
|
||||
|
||||
from .theme import THURINGIA_EDITION, THURINGIA_THEME
|
||||
|
||||
|
||||
def main(argv: list[str] | None = None) -> int:
|
||||
return core_main(argv, edition=THURINGIA_EDITION, extra_themes=(THURINGIA_THEME,))
|
||||
@@ -0,0 +1,52 @@
|
||||
"""Thüringen profile and visual assets; application behavior comes from synadm-tui."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import curses
|
||||
from pathlib import Path
|
||||
|
||||
from synadm_tui.app import Theme
|
||||
from synadm_tui.edition import Edition
|
||||
|
||||
|
||||
ASSETS = Path(__file__).resolve().parent / "assets"
|
||||
|
||||
THURINGIA_CREST = (
|
||||
" .-============-.",
|
||||
" / * * * * \\",
|
||||
" | /\\_/\\ |",
|
||||
" | ___/ o o \\___ |",
|
||||
" | / |==^==| \\ |",
|
||||
" | /|===|\\ |",
|
||||
" \\ * * * * /",
|
||||
" '============'",
|
||||
)
|
||||
|
||||
THURINGIA_THEME = Theme(
|
||||
"thuringia",
|
||||
"Freistaat Thüringen",
|
||||
"THÜRINGEN",
|
||||
(
|
||||
(curses.COLOR_RED, -1),
|
||||
(curses.COLOR_WHITE, curses.COLOR_RED),
|
||||
(curses.COLOR_CYAN, -1),
|
||||
(curses.COLOR_RED, -1),
|
||||
(curses.COLOR_YELLOW, -1),
|
||||
(curses.COLOR_WHITE, -1),
|
||||
(curses.COLOR_BLUE, -1),
|
||||
(curses.COLOR_WHITE, curses.COLOR_BLUE),
|
||||
(curses.COLOR_RED, curses.COLOR_WHITE),
|
||||
),
|
||||
THURINGIA_CREST,
|
||||
"FREISTAAT THÜRINGEN // SYSTEM BEREIT",
|
||||
image_path=ASSETS / "thueringen-wappen.png",
|
||||
block_path=ASSETS / "thuringia.block.json",
|
||||
)
|
||||
|
||||
THURINGIA_EDITION = Edition(
|
||||
key="thuringia",
|
||||
name="Thüringen Edition",
|
||||
binary_name="synadm-tui-thueringen",
|
||||
default_theme="thuringia",
|
||||
theme_keys=("thuringia", "cyberspace", "matrix", "hacker", "high-contrast", "monochrome"),
|
||||
)
|
||||
@@ -0,0 +1 @@
|
||||
"""Tests for the Thüringen branding overlay."""
|
||||
@@ -0,0 +1,28 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import unittest
|
||||
|
||||
import synadm_tui
|
||||
from synadm_tui.app import App
|
||||
from synadm_tui.runner import SynadmRunner
|
||||
from synadm_tui_thueringen import __version__
|
||||
from synadm_tui_thueringen.theme import THURINGIA_EDITION, THURINGIA_THEME
|
||||
|
||||
|
||||
class EditionTests(unittest.TestCase):
|
||||
def test_core_and_overlay_versions_match(self) -> None:
|
||||
self.assertEqual(__version__, synadm_tui.__version__)
|
||||
|
||||
def test_theme_assets_are_external_and_complete(self) -> None:
|
||||
self.assertTrue(THURINGIA_THEME.image_path.is_file())
|
||||
self.assertTrue(THURINGIA_THEME.block_path.is_file())
|
||||
self.assertEqual(len(THURINGIA_THEME.palette), 9)
|
||||
|
||||
def test_core_accepts_external_edition(self) -> None:
|
||||
app = App(SynadmRunner("not-installed"), THURINGIA_EDITION, (THURINGIA_THEME,))
|
||||
self.assertEqual(app.theme.key, "thuringia")
|
||||
self.assertEqual(app.edition.binary_name, "synadm-tui-thueringen")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
+1
Submodule vendor/synadm-tui added at c1483aae71
Reference in New Issue
Block a user