@@ -0,0 +1,38 @@
|
||||
# Plymouth WESP (800×600)
|
||||
|
||||
Тема загрузки с той же пиксельной анимацией логотипа, что на `/starting`.
|
||||
|
||||
## Зависимости на устройстве
|
||||
|
||||
```bash
|
||||
sudo apt install plymouth plymouth-themes python3-pil
|
||||
```
|
||||
|
||||
## Из админки
|
||||
|
||||
**Система → Заставка загрузки (Plymouth) → «Установить тему Plymouth»** — рендер кадров, копирование темы, `sudo install_wesp_theme.sh`, `update-initramfs -u`.
|
||||
|
||||
Нужен **sudo без пароля** для скрипта установки или переменная:
|
||||
|
||||
```bash
|
||||
export WESP_PLYMOUTH_INSTALL_CMD='/usr/bin/sudo /path/to/wesp/scripts/plymouth/install_wesp_theme.sh'
|
||||
```
|
||||
|
||||
## Вручную
|
||||
|
||||
```bash
|
||||
cd /opt/wesp # каталог с wesp/
|
||||
python3 scripts/plymouth/build_frames.py --out data/plymouth-build
|
||||
cp install/plymouth/wesp/wesp.plymouth install/plymouth/wesp/wesp.script data/plymouth-build/
|
||||
sudo bash scripts/plymouth/install_wesp_theme.sh data/plymouth-build
|
||||
sudo reboot
|
||||
```
|
||||
|
||||
## Файлы
|
||||
|
||||
| Путь | Назначение |
|
||||
|------|------------|
|
||||
| `install/plymouth/wesp/wesp.script` | Plymouth Script (цикл кадров) |
|
||||
| `install/plymouth/wesp/wesp.plymouth` | Манифест темы |
|
||||
| `app/services/plymouth_frame_renderer.py` | Рендер PNG (Pillow) |
|
||||
| `data/plymouth-build/animation/*.png` | Сгенерированные кадры (~165 шт., 25 fps, 6 с) |
|
||||
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python3
|
||||
"""CLI: сгенерировать кадры Plymouth (800×600) из logo2.png."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
if str(ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
from app.services.plymouth_frame_renderer import ( # noqa: E402
|
||||
DURATION_MS_DEFAULT,
|
||||
PLYMOUTH_FPS,
|
||||
PLYMOUTH_HEIGHT,
|
||||
PLYMOUTH_WIDTH,
|
||||
render_all_frames,
|
||||
)
|
||||
|
||||
|
||||
def main() -> int:
|
||||
parser = argparse.ArgumentParser(description="Render WESP Plymouth animation frames")
|
||||
parser.add_argument(
|
||||
"--logo",
|
||||
type=Path,
|
||||
default=ROOT / "static" / "logo2.png",
|
||||
help="Path to logo2.png",
|
||||
)
|
||||
parser.add_argument(
|
||||
"--out",
|
||||
type=Path,
|
||||
default=ROOT / "data" / "plymouth-build",
|
||||
help="Output directory (animation/ inside)",
|
||||
)
|
||||
parser.add_argument("--width", type=int, default=PLYMOUTH_WIDTH)
|
||||
parser.add_argument("--height", type=int, default=PLYMOUTH_HEIGHT)
|
||||
parser.add_argument("--duration-ms", type=int, default=DURATION_MS_DEFAULT)
|
||||
parser.add_argument("--fps", type=int, default=PLYMOUTH_FPS)
|
||||
args = parser.parse_args()
|
||||
|
||||
if not args.logo.is_file():
|
||||
print(f"Logo not found: {args.logo}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
def progress(done: int, total: int) -> None:
|
||||
pct = int(100 * done / total) if total else 100
|
||||
print(f"\rFrames {done}/{total} ({pct}%)", end="", flush=True)
|
||||
|
||||
summary = render_all_frames(
|
||||
args.logo,
|
||||
args.out,
|
||||
width=args.width,
|
||||
height=args.height,
|
||||
duration_ms=args.duration_ms,
|
||||
fps=args.fps,
|
||||
progress_callback=progress,
|
||||
)
|
||||
print()
|
||||
print(summary)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env bash
|
||||
# Установка темы Plymouth WESP (нужен root).
|
||||
# Использование: install_wesp_theme.sh /path/to/built/theme
|
||||
set -euo pipefail
|
||||
|
||||
SRC="${1:-}"
|
||||
if [[ -z "${SRC}" || ! -d "${SRC}" ]]; then
|
||||
echo "Usage: $0 /path/to/theme-dir" >&2
|
||||
exit 2
|
||||
fi
|
||||
|
||||
if [[ "$(id -u)" -ne 0 ]]; then
|
||||
echo "Запустите от root (sudo)." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
THEME_ID="wesp"
|
||||
DEST="/usr/share/plymouth/themes/${THEME_ID}"
|
||||
PLYMOUTH_FILE="${DEST}/${THEME_ID}.plymouth"
|
||||
|
||||
if ! command -v plymouth >/dev/null 2>&1; then
|
||||
echo "plymouth не найден. Установите: apt install plymouth plymouth-themes" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -f "${SRC}/${THEME_ID}.plymouth" || ! -f "${SRC}/${THEME_ID}.script" ]]; then
|
||||
echo "В ${SRC} нет ${THEME_ID}.plymouth / ${THEME_ID}.script" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ ! -d "${SRC}/animation" ]] || [[ -z "$(ls -A "${SRC}/animation" 2>/dev/null || true)" ]]; then
|
||||
echo "Нет кадров в ${SRC}/animation — сначала сгенерируйте анимацию." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
install -d "${DEST}"
|
||||
rsync -a --delete "${SRC}/" "${DEST}/"
|
||||
|
||||
if command -v update-alternatives >/dev/null 2>&1; then
|
||||
update-alternatives --install \
|
||||
/usr/share/plymouth/themes/default.plymouth default.plymouth \
|
||||
"${PLYMOUTH_FILE}" 200
|
||||
update-alternatives --set default.plymouth "${PLYMOUTH_FILE}"
|
||||
elif command -v plymouth-set-default-theme >/dev/null 2>&1; then
|
||||
plymouth-set-default-theme -R "${THEME_ID}"
|
||||
else
|
||||
ln -sf "${PLYMOUTH_FILE}" /etc/alternatives/default.plymouth 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if command -v plymouth-set-default-theme >/dev/null 2>&1; then
|
||||
plymouth-set-default-theme "${THEME_ID}" 2>/dev/null || true
|
||||
fi
|
||||
|
||||
if command -v update-initramfs >/dev/null 2>&1; then
|
||||
echo "==> update-initramfs -u"
|
||||
update-initramfs -u
|
||||
else
|
||||
echo "update-initramfs не найден — пересоберите initramfs вручную." >&2
|
||||
fi
|
||||
|
||||
echo "Тема WESP установлена: ${DEST}"
|
||||
Reference in New Issue
Block a user