From 1170c807ba42d79aa0ab2b5f390aaf2c3ef963ea Mon Sep 17 00:00:00 2001 From: Edward Tirado Jr Date: Sun, 16 Feb 2025 20:55:41 -0600 Subject: [PATCH] Initial commit --- .gitignore | 155 +++++++++++++++++++++++++++++++++ README.md | 17 ++++ config.ini.example | 3 + fonts/Narifah-EaBWz.otf | Bin 0 -> 45616 bytes main.py | 132 ++++++++++++++++++++++++++++ requirements.txt | 2 + start.sh | 3 + systemd/mopidy-display.service | 15 ++++ 8 files changed, 327 insertions(+) create mode 100644 .gitignore create mode 100644 README.md create mode 100644 config.ini.example create mode 100644 fonts/Narifah-EaBWz.otf create mode 100644 main.py create mode 100644 requirements.txt create mode 100755 start.sh create mode 100644 systemd/mopidy-display.service diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..67c399d --- /dev/null +++ b/.gitignore @@ -0,0 +1,155 @@ +config.ini + +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintainted in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + diff --git a/README.md b/README.md new file mode 100644 index 0000000..34dc725 --- /dev/null +++ b/README.md @@ -0,0 +1,17 @@ +# Mopidy Display for Pimoni Pirate Audio + + +Shows playing track and album art from Mopidy on Pimoni Pirate Audio screen. Supports getting data from external mopidy server. + +![display example](https://i.imgur.com/F0jGexo.jpg) + +Uses the [Narifa](https://www.fontspace.com/narifah-font-f72202) font + +## Controls +A button: Volume down + +X button: Volume up + +B button: Previous Track + +Y button: Next Track diff --git a/config.ini.example b/config.ini.example new file mode 100644 index 0000000..e3f277f --- /dev/null +++ b/config.ini.example @@ -0,0 +1,3 @@ +[pirate-display] +mopidy_host = 192.168.1.123 +mopidy_web_port = 6680 diff --git a/fonts/Narifah-EaBWz.otf b/fonts/Narifah-EaBWz.otf new file mode 100644 index 0000000000000000000000000000000000000000..a25bed827eeb9124de50d4b98cb8f105f01e757c GIT binary patch literal 45616 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