Development
Project layout, linting rules, translation workflow, and what CI checks on every push.
Project layout
src/ Plugin package (installed to Plugins/Extensions/E2EmbyClient)
├── plugin.py Plugin entry point / menu registration
├── EmbySetup.py Configuration schema and setup screens
├── EmbyRestClient.py Emby REST API client
├── EmbyHome.py Home screen
├── EmbyLibraryScreen.py Library grid screen
├── EmbyGridList.py / EmbyList.py List/grid widgets
├── EmbyMovieItemView.py, EmbySeriesItemView.py,
│ EmbyEpisodeItemView.py, EmbyBoxSetItemView.py Detail screens per item type
├── EmbyPlayer.py Playback screen (seek, tracks, subtitles, skip intro, up next)
├── EmbyItemFunctionButtons.py Play/watched/favorite/etc. action buttons
├── EmbyUpNextScreen.py, EmbySkipIntroScreen.py Playback overlays
├── EmbyThemeMusic.py Theme music playback
├── EmbyNotification.py In-app notifications
├── HelperFunctions.py, Variables.py, Globals.py Shared utilities/constants
├── keymap.xml, setup.xml Enigma2 keymap and setup definitions
└── locale/ Translations (.po/.mo)
meta/ Debian control files used by build.sh
CI/ Linting/build helper scripts used in CI
po/ Translation update scripts
Building locally
build.sh copies src/ and meta/ into a temp directory, regenerates translations, stamps the version from the current git revision, and packs everything into a Debian-style .ipk with ar. See Installation — build the .ipk yourself for the exact steps.
The version string embedded in the package looks like:
<base-version>+git<revision-count>+<short-hash>+<short-hash-10>-r0
so every build can be traced back to the exact commit it came from.
Linting
Two linters run in CI on every push and pull request (see .github/workflows):
- Ruff — configured in
pyproject.toml(120-char line length,E/F/Wrule sets). Run it locally with:ruff check src - Pylint — run against the same source tree in its own workflow.
Import sorting uses isort with the black profile and 120-character lines, also configured in pyproject.toml.
Continuous integration
Besides the two linters, the workflow set includes:
- compile.yml — byte-compiles the plugin to catch syntax errors before they reach a box.
- autotag.yml — automated tagging on the repository.
- buildbot.yml — build automation for the project.
Translations
Translatable strings live in po/ as .po files, compiled to .mo for runtime use. The project currently ships Bulgarian (bg) and German (de) locales alongside the English source strings.
After changing any translatable string in the Python source:
- Run
python setup_translate.py(or the platform-specific script inpo/, e.g.updateallpo-multiOS.sh) to regenerate the.pot/.potemplate. - Update the translated strings in the relevant
.pofile(s). - Regenerate the compiled
.mofiles — this also happens automatically as part ofbuild.sh.
Copy an existing .po file (e.g. po/de.po) to a new locale code, translate its entries, and it will be picked up the next time the .po/.mo update scripts run.
OpenEmbedded / feed integration
The BitBake recipe enigma2-plugin-extensions-e2embyclient.bb targets both oe-alliance-core and openpli-oe-core style feeds (see the commented alternative inherit line in the recipe). It builds directly from the main branch on GitHub via SRCREV = "${AUTOREV}", and declares python3-pillow and python3-requests as runtime dependencies.
Contributing
- Keep changes scoped and run Ruff/Pylint locally before opening a pull request — CI will otherwise fail on the same checks.
- Match the existing code style (tabs for indentation in
src/, 120-character line length). - If you add or change any user-facing string, update the translation template as described above.
- Open issues and pull requests on GitHub.