Compare commits

...

6 commits

5 changed files with 225 additions and 5 deletions

104
.gitignore vendored Normal file
View file

@ -0,0 +1,104 @@
# 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/
*.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/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
# Translations
*.mo
*.pot
# Django stuff:
*.log
.static_storage/
.media/
local_settings.py
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# 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/

47
mmmpd
View file

@ -8,6 +8,9 @@ import datetime
import time
import logging
import mpd
from ipo import ipo, opi, p
# pylint: disable=no-member
NAME = "Mattermost MPD now playing status"
VERSION = "1.0.1"
@ -30,7 +33,7 @@ MPD_STATE_PAUSE = "pause"
# ----------------
def set_status(emoji, text, expires_datetime):
LOGGER.info(f"Custom status expiring {expires_datetime or 'never'}: :{emoji}: {text}")
LOGGER.info("Custom status expiring %s: :%s: %s", expires_datetime or "never", emoji, text)
subprocess.run([
"mmcli", "customstatus",
"--until", expires_datetime.isoformat() if expires_datetime else "",
@ -48,15 +51,47 @@ def clear_status():
# ---------
def song_string(song_info):
artist = song_info.get("artist") or "Unknown artist"
title = song_info.get("title") or "Unknown song"
return f"{artist} {title}"
if song_info.get("title") is None:
artist = song_info.get("artist") or ""
title = re.sub(
r"\.[a-z0-9]+$",
"",
os.path.basename(song_info.get("file"))
) or "Unknown song"
else:
artist = song_info.get("artist") or "Unknown artist"
title = song_info.get("title") or "Unknown song"
string = f"{artist}{' ' if artist else ''}{title}"
if len(string) > 102:
string = (ipo(string) |
p(re.sub)(r"\bOrchestr[ea]\b", r"Orch.") |
p(re.sub)(r"\bFestival\b", r"Fest.") |
p(re.sub)(r"\bSymphon(y|ic)\b", r"Symph.") |
p(re.sub)(r"\bHarmon(y|ic)\b", r"Harm.") |
p(re.sub)(r"\bPhilharmon(y|ic)\b", r"Phil.") |
p(re.sub)(r"\ballegro\b", r"all.", flags=re.IGNORECASE) |
p(re.sub)(r"\bandante\b", r"and.", flags=re.IGNORECASE) |
p(re.sub)(r"\badagio\b", r"adg.", flags=re.IGNORECASE) |
p(re.sub)(r"\bma non troppo\b", r"m.n.t.", flags=re.IGNORECASE) |
p(re.sub)(r"\bviolin\b", r"vln.", flags=re.IGNORECASE) |
p(re.sub)(r"\bpiano\b", r"pno.", flags=re.IGNORECASE) |
p(re.sub)(r"\bmolto\b", r"mlt.", flags=re.IGNORECASE) |
p(re.sub)(r"\bespressivo\b", r"essprs.", flags=re.IGNORECASE) |
p(re.sub)(r"\bsostenuto\b", r"sost.", flags=re.IGNORECASE) |
p(re.sub)(r"\b[Nn]o(?:\. ?| )([0-9])", r"№\1") |
p(re.sub)(r"in ([A-Za-z]) ?sharp", r"in \1♯") |
p(re.sub)(r"in ([A-Za-z]) ?flat", r"in \1♭") |
p(re.sub)(r"in ([A-Z]([#b♭♯])?) ?major", lambda x: f"in {x[1].upper()}", flags=re.IGNORECASE) |
p(re.sub)(r"in ([A-Z]([#b♭♯])?) ?minor", lambda x: f"in {x[1].lower()}", flags=re.IGNORECASE) |
p(re.sub)(r"\band\b", r"&") |
opi)
return string
def formatted_status(mpd_client):
status = mpd_client.status()
state = status.get("state")
LOGGER.debug(f"Player state: {state!r}")
LOGGER.debug("Player state: %r", state)
if state not in (MPD_STATE_PLAY, MPD_STATE_PAUSE):
return None
@ -136,6 +171,8 @@ def main(mpd_host_string, mpd_port):
set_status_from_mpd(mpd_client)
try:
loop(mpd_client, set_status_from_mpd)
except KeyboardInterrupt:
pass
finally:
clear_status()

12
requirements.txt Normal file
View file

@ -0,0 +1,12 @@
#
# This file is autogenerated. To update, run:
# tools/update_requirements.sh
#
ipo==0.0.4 \
--hash=sha256:0658a14ca4ea2f843675465cde329ac51e9ff40db2b7158c8d23b195a25e3175 \
--hash=sha256:d89d2ea327b874cdbf56b5b2a22e1c10ea46a705da849457b65503e9f158a0c4
# via mmmpd (setup.py)
python-mpd2==3.0.5 \
--hash=sha256:4b96fb5fc02d5c42cec4038689d726820d11bb8de42a28e89872872476d31cee \
--hash=sha256:6f1bffd93b9a32fc018a9bbf3487505b52e0d757ec34066905c60a912d492384
# via mmmpd (setup.py)

51
setup.py Executable file
View file

@ -0,0 +1,51 @@
#!/usr/bin/env python3
import setuptools
# with open("README.md", "r") as fh:
# long_description = fh.read()
setuptools.setup(
name="mmmpd",
version="1.0",
author="Midgard",
author_email="midgard@zeus.ugent.be",
description="Create a “now playing” custom status in Mattermost. Depends on https://git.zeus.gent/midgard/mmcli being in your path as mmcli",
# long_description=long_description,
# long_description_content_type="text/markdown",
url="https://git.zeus.gent/midgard/mmmpd",
project_urls={
"Source": "https://git.zeus.gent/midgard/mmmpd",
"Bug tracker": "https://git.zeus.gent/midgard/mmmpd/-/issues",
},
classifiers=[
"Programming Language :: Python :: 3",
"License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
"Operating System :: OS Independent",
"Natural Language :: English",
"Environment :: Console",
# "Development Status :: 1 - Planning",
#"Development Status :: 2 - Pre-Alpha",
#"Development Status :: 3 - Alpha",
#"Development Status :: 4 - Beta",
#"Development Status :: 5 - Production/Stable",
"Development Status :: 6 - Mature",
# "Development Status :: 7 - Inactive",
"Intended Audience :: End Users/Desktop",
"Topic :: Utilities",
],
packages=setuptools.find_packages(),
python_requires=">=3.6",
install_requires=[
"python-mpd2",
# "mmcli @ git+https://git.zeus.gent/midgard/mmcli",
"ipo"
],
)

16
tools/update_requirements.sh Executable file
View file

@ -0,0 +1,16 @@
#!/bin/sh
cd "`dirname "$0"`"/..
if [ ! -f venv/bin/pip-compile ]; then
venv/bin/pip install pip-tools
fi
cat <<EOF > requirements.txt
#
# This file is autogenerated. To update, run:
# tools/update_requirements.sh
#
EOF
venv/bin/pip-compile --quiet --generate-hashes --annotate --no-header --output-file="-" >> requirements.txt
echo "Updated requirements.txt"