Repository navigation
Development and Testing
How to work on TinyPPI: get the code onto a box, run the tests, regenerate generated files, and prepare a release. For the code structure see Architecture.
git clone https://github.com/CE-Repo/script.tinyppi.git
cd script.tinyppiRequirements on the development machine: Python 3.10 or later (the code uses
X | Y type unions) and pytest for the unit tests.
-
Copy the add-on folder to the box, replacing the installed copy:
rsync -av --delete --exclude .git --exclude tests --exclude tools \ ./ root@coreelec:/storage/.kodi/addons/script.tinyppi/ -
Restart Kodi (
systemctl restart kodi) — the service and its cached modules only reload with a new interpreter. Script-only changes take effect on the next launch, but anything running in the service (overlay, splash, dashboard) needs the restart. -
Watch the log:
tail -f /storage/.kodi/temp/kodi.log | grep TinyPPI
Useful switches while developing:
| Switch | Where | Effect |
|---|---|---|
FORCE_DEBUG = True |
resources/lib/core/log.py |
Writes TinyPPI's debug lines at INFO level, without enabling Kodi's debug log. |
_ALLOW_NON_COREELEC = True |
resources/lib/ui/overlay.py |
Lets the overlay open on a non-CoreELEC Kodi (desktop testing). Never commit it. |
The add-on's code runs outside Kodi: tests/stubs stands in for xbmc,
xbmcgui, xbmcaddon and xbmcvfs.
python3 -m pip install pytest
python3 -m pytest tests| File | Covers |
|---|---|
unit/test_library.py |
The dashboard's library cache: one query for concurrent readers, no stale list after a drop, a scan's burst of notifications as one drop, the drops after playback stops, episodes, the continue row, marking |
unit/test_vs10_switcher.py |
VS10 switches from the dashboard: the last tap wins, a failed switch does not stop the next, the modes offered per source |
unit/test_server.py |
The HTTP server: fixed routes, security headers, the token for writing and for untrusted host names, the guessing lockout, connection caps, tokens and ports |
unit/test_access.py |
Which host names count as the home network; the lockout table |
unit/test_delta.py |
Delta frames of the event stream, applied as js/core.js applies them |
unit/test_artwork.py |
Artwork sources (Kodi's texture cache first) and types (from the bytes) |
unit/test_settings_definition.py |
resources/settings.xml against the five languages, the code and the skin: texts, defaults, dependencies, action buttons, color defaults and their translated names, opacity sliders, every setting read, every color property used |
unit/test_settings_logic.py |
Settings that only act with Dolby Vision or on Amlogic hardware, checked on their code paths; every color setting reaching its skin property; the color picker (HEX tile first, then the palette; color names numbered per family; every family light to dark, its neighbours alike in saturation; every tile distinct; older stored colors keep their color) |
unit/test_modules.py |
Every module imports; the small state holders behave |
The conftest.py fixture resets the stubs' settings, properties, InfoLabels,
conditions, log and JSON-RPC handler before every test.
tests/kodi runs TinyPPI in a real Kodi 22 under Xvfb and checks it
from outside — over JSON-RPC, over the dashboard's HTTP API, through a small
helper add-on inside Kodi (settings, Home-window properties), and on
screenshots.
| Run | Covers |
|---|---|
run_scan.py |
A library scan with an open films tab ends in about one re-read (with BASELINE_REF, compared with the same run on older code) |
run_functional.py |
Service, dashboard API and headers, access control, playback from the dashboard, the overlay (launch, toggle, handover), the VS10 dialog, codec logos, the remote (pause, seek, tracks, subtitles, chapters, volume), VS10 switching, watched / unwatched / resume, connection caps, the guessing lockout, the settings dialogs, the page in Chromium, a clean shutdown |
run_settings.py |
Every setting with an effect on a desktop Kodi, set live and measured: all colors and opacities, overlay, VS10 dialog, channel graphic, codec logos in all three modes, dashboard |
run_settings_dialog.py |
Every category of the settings dialog opens without errors |
- Kodi 22 for X11. Ubuntu 24.04 has no package;
build_kodi.shbuilds it from source into/opt/kodi(as root, about an hour). - Xvfb, ImageMagick, ffmpeg with libx264 and libx265 (installed by
build_kodi.sh). - Python 3 with Pillow.
- Optional: Node.js with the
playwrightpackage for the browser check (skipped without it). - An
/etc/coreelecfolder: the overlay and the VS10 dialog open on CoreELEC only, and this makes a desktop Kodi pass. Use a throwaway machine or container.
sudo tests/kodi/build_kodi.sh # once
sudo mkdir -p /etc/coreelec # once, on a test machine only
tests/kodi/run_all.shrun_all.sh makes the test media and a Kodi profile template (once), then runs
every suite on fresh profiles and exits non-zero on a failure. Runs can also be
started on their own, e.g. python3 tests/kodi/run_settings.py splash.
| Variable | Default | Purpose |
|---|---|---|
KODI_TEST_ROOT |
/opt/kodi-test |
Media, profiles, screenshots, results (results/*.json) |
KODI_BIN |
/opt/kodi/bin/kodi |
The Kodi to test |
KODI_TEST_DISPLAY |
:99 |
The Xvfb display |
BASELINE_REF |
(none) | A git ref to compare the scan run against, e.g. main
|
PYTHON |
python3 |
The Python run_all.sh uses (needs Pillow) |
Kodi's web server is switched on in the test profiles (port 8080, user kodi,
password kodi) and the dashboard runs on 8099; keep both ports free.
- the Amlogic driver (the VS10 sysfs writes fail on a desktop and are reported apart as expected),
- Dolby Vision side data (stock Kodi does not publish it, and
script.module.sidedataparses on aarch64 only), - the output format the codec logos show.
The Bar and Single button VS10 dialog layouts are generated from the shared
description in resources/lib/ui/dialog_layout.py; the Dialog layout is
maintained by hand.
python3 tools/gen_dialog_skins.py # writes script-tinyppi-dialog-bar.xml and -single.xml
python3 tools/gen_dialog_media.py # draws media/dialog/arrow-left.png and arrow-right.pngRun them from the repository root after changing dialog_layout.py, and commit
the results.
- Every source file starts with an SPDX header:
# SPDX-License-Identifier: AGPL-3.0-or-later # Copyright (c) 2026 U3knOwn
- Module and function docstrings explain why, not just what; comments are plain English sentences.
- Never let an exception escape into Kodi from the service: log it with the
module's
channel()logger and carry on. - No thread may outlive the service script, and no wait may be unbounded (Kodi waits for every thread at shutdown).
- Write window properties only when the value changed
(
set_changed_properties), and read InfoLabels inside aread_pass. - New user-visible text goes into all five
strings.pofiles, with the next free ID in the block of its area (see Translations);test_settings_definition.pyenforces it for settings. - New settings need a label, a help text, a default and, for colors, an opacity slider; the definition test checks this.
- Bump
versioninaddon.xml. - Replace the
<news>entry inaddon.xml— it holds the latest version only. - Run the unit tests (and ideally the Kodi 22 suite).
- Commit as "Bump version to x.y.z", tag, and publish the ZIP to the repository.
Issues and pull requests are welcome at https://github.com/CE-Repo/script.tinyppi. Please include tests for logic changes, keep pull requests focused, and describe how you verified the change (unit tests, Kodi 22 suite, or on which CoreELEC box).
User guide
- Installation
- Getting Started
- Launching and Keymaps
- The TinyPPI Overlay
- Dolby Vision Metadata View
- VS10 Output Modes
- Codec Logos
- Channel Layout Graphic
- IMAX Detection
- Colors and Themes
Web dashboard
Reference
Developers
Project