music-assistant: 2.8.7 -> 2.9.4
something tried to use sched_setscheduler on startup, so @resources must be allowed. Could be torch but since that is a general requirement we cannot make this conditional. Changelog: https://github.com/music-assistant/server/releases/tag/2.9.0 Changelog: https://github.com/music-assistant/server/releases/tag/2.9.1 Changelog: https://github.com/music-assistant/server/releases/tag/2.9.2 Changelog: https://github.com/music-assistant/server/releases/tag/2.9.3 Changelog: https://github.com/music-assistant/server/releases/tag/2.9.4 Diff: https://github.com/music-assistant/server/compare/2.8.7...2.9.4
This commit is contained in:
@@ -171,6 +171,7 @@ in
|
||||
DevicePolicy = "closed";
|
||||
LockPersonality = true;
|
||||
# breaks pyopenssl's cffi calls, used in remote access feature
|
||||
# not compatible with llvmlite which is required by numba -> librosa
|
||||
MemoryDenyWriteExecute = false;
|
||||
ProcSubset = "pid";
|
||||
ProtectClock = true;
|
||||
@@ -194,7 +195,7 @@ in
|
||||
SystemCallArchitectures = "native";
|
||||
SystemCallFilter = [
|
||||
"@system-service"
|
||||
"~@privileged @resources"
|
||||
"~@privileged"
|
||||
"mbind"
|
||||
]
|
||||
++ lib.optionals useYTMusic [
|
||||
|
||||
@@ -43,7 +43,7 @@ index 0ac8a70f..5d74e25b 100644
|
||||
"""Set up the YTMusic provider."""
|
||||
logging.getLogger("yt_dlp").setLevel(self.logger.level + 10)
|
||||
- await self._install_packages()
|
||||
self._cookie = self.config.get_value(CONF_COOKIE)
|
||||
self._cookie = str(self.config.get_value(CONF_COOKIE))
|
||||
self._po_token_server_url = (
|
||||
self.config.get_value(CONF_PO_TOKEN_SERVER_URL) or DEFAULT_PO_TOKEN_SERVER_URL
|
||||
@@ -1103,8 +1102,6 @@ async def _install_packages(self) -> None:
|
||||
|
||||
@@ -8,13 +8,13 @@
|
||||
|
||||
buildPythonPackage rec {
|
||||
pname = "music-assistant-frontend";
|
||||
version = "2.17.146";
|
||||
version = "2.17.186";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchPypi {
|
||||
pname = "music_assistant_frontend";
|
||||
inherit version;
|
||||
hash = "sha256-VU2SXL6SLFiKntmJJtCabBOYOeImYFPHYxvMPmnhmEc=";
|
||||
hash = "sha256-dNGzXDRZuQLRkMY0erjJZE4h26yFP4Fdn9a3K6T0RvM=";
|
||||
};
|
||||
|
||||
build-system = [ setuptools ];
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
ffmpeg_7-headless,
|
||||
nixosTests,
|
||||
replaceVars,
|
||||
writableTmpDirAsHomeHook,
|
||||
providers ? [ ],
|
||||
}:
|
||||
|
||||
@@ -15,10 +16,10 @@ let
|
||||
music-assistant-frontend = prev.callPackage ./frontend.nix { };
|
||||
|
||||
music-assistant-models = final.music-assistant-models.overridePythonAttrs (oldAttrs: {
|
||||
version = "1.1.115";
|
||||
version = "1.1.129";
|
||||
|
||||
src = oldAttrs.src.override {
|
||||
hash = "sha256-oEXL0B8JNH4PcltpES375ov7QGs+gtYKlMGr1B7BlKY=";
|
||||
hash = "sha256-6gVHlFTt/bsj4nUGPS6HDUQ7zczpfos75U6l4Yk9W6k=";
|
||||
};
|
||||
});
|
||||
}
|
||||
@@ -39,14 +40,14 @@ assert
|
||||
|
||||
pythonPackages.buildPythonApplication rec {
|
||||
pname = "music-assistant";
|
||||
version = "2.8.7";
|
||||
version = "2.9.4";
|
||||
pyproject = true;
|
||||
|
||||
src = fetchFromGitHub {
|
||||
owner = "music-assistant";
|
||||
repo = "server";
|
||||
tag = version;
|
||||
hash = "sha256-m91q/8XYoZ5Azu79fKD0euRCuf29w3vj5cxdFheDsmI=";
|
||||
hash = "sha256-PiSBghhlxknijRqghkO8wn1CB2XqaJrjrvGNvZUlNbo=";
|
||||
};
|
||||
|
||||
patches = [
|
||||
@@ -82,6 +83,11 @@ pythonPackages.buildPythonApplication rec {
|
||||
];
|
||||
|
||||
postPatch = ''
|
||||
# Undo Python 3.14 only syntax
|
||||
substituteInPlace music_assistant/controllers/streams/controller.py \
|
||||
--replace-fail "except BrokenPipeError, ConnectionResetError, ConnectionError:" "except (BrokenPipeError, ConnectionResetError, ConnectionError):" \
|
||||
--replace-fail "except BrokenPipeError, ConnectionResetError:" "except (BrokenPipeError, ConnectionResetError):"
|
||||
|
||||
substituteInPlace pyproject.toml \
|
||||
--replace-fail "0.0.0" "${version}" \
|
||||
--replace-fail "==" ">="
|
||||
@@ -110,6 +116,7 @@ pythonPackages.buildPythonApplication rec {
|
||||
"mashumaro"
|
||||
"orjson"
|
||||
"xmltodict"
|
||||
"zeroconf"
|
||||
];
|
||||
|
||||
pythonRemoveDeps = [
|
||||
@@ -140,6 +147,7 @@ pythonPackages.buildPythonApplication rec {
|
||||
ifaddr
|
||||
librosa
|
||||
mashumaro
|
||||
modern-colorthief
|
||||
music-assistant-frontend
|
||||
music-assistant-models
|
||||
mutagen
|
||||
@@ -151,6 +159,8 @@ pythonPackages.buildPythonApplication rec {
|
||||
pyjwt
|
||||
python-slugify
|
||||
shortuuid
|
||||
torch
|
||||
torchaudio
|
||||
unidecode
|
||||
xmltodict
|
||||
zeroconf
|
||||
@@ -175,18 +185,36 @@ pythonPackages.buildPythonApplication rec {
|
||||
with pythonPackages;
|
||||
[
|
||||
pytestCheckHook
|
||||
writableTmpDirAsHomeHook
|
||||
]
|
||||
++ lib.concatAttrValues optional-dependencies
|
||||
++ (lib.concatMap (provider: providerPackages.${provider} python.pkgs) [
|
||||
++ (lib.concatMap (provider: providerPackages.${provider} pythonPackages) [
|
||||
"acoustid_lookup"
|
||||
"audible"
|
||||
"dlna"
|
||||
"fastmcp_server"
|
||||
"jellyfin"
|
||||
"mpd"
|
||||
"msx_bridge"
|
||||
"opensubsonic"
|
||||
"sendspin"
|
||||
"smart_fades"
|
||||
"snapcast"
|
||||
"sonic_analysis"
|
||||
"sonic_similarity"
|
||||
"tidal"
|
||||
"wiim"
|
||||
"ytmusic"
|
||||
]);
|
||||
|
||||
preCheck = ''
|
||||
export NUMBA_CACHE_DIR=$(mktemp -d)
|
||||
|
||||
# required for smart_fades tests
|
||||
mkdir -p $HOME/.cache/torch/hub/checkpoints/
|
||||
cp ${pythonPackages.beat-this.passthru.small0Ckpt} $HOME/.cache/torch/hub/checkpoints/beat_this-small0.ckpt
|
||||
'';
|
||||
|
||||
disabledTestPaths = [
|
||||
# no multicast support in build sandbox:
|
||||
# "OSError: [Errno 19] No such device"
|
||||
@@ -194,9 +222,12 @@ pythonPackages.buildPythonApplication rec {
|
||||
# provider is missing dependencies
|
||||
"tests/providers/apple_music"
|
||||
"tests/providers/bandcamp"
|
||||
"tests/providers/hue_entertainment"
|
||||
"tests/providers/kion_music"
|
||||
"tests/providers/nicovideo"
|
||||
"tests/providers/qqmusic"
|
||||
"tests/providers/yandex_music"
|
||||
"tests/providers/yandex_ynison"
|
||||
"tests/providers/zvuk_music"
|
||||
# mocking music_assistant.providers.airplay.pairing.AirPlayPairing does not work
|
||||
"tests/providers/airplay/test_player.py::test_start_pairing__pin_decision"
|
||||
|
||||
@@ -1,8 +1,27 @@
|
||||
# Do not edit manually, run ./update-providers.py
|
||||
|
||||
{
|
||||
version = "2.8.7";
|
||||
version = "2.9.4";
|
||||
builtins = [
|
||||
"builtin"
|
||||
"coverartarchive"
|
||||
"fanarttv"
|
||||
"itunes_artwork"
|
||||
"local_audio"
|
||||
"loudness_analysis"
|
||||
"lrclib"
|
||||
"musicbrainz"
|
||||
"sendspin"
|
||||
"sync_group"
|
||||
"theaudiodb"
|
||||
"universal_player"
|
||||
"wikipedia"
|
||||
];
|
||||
providers = {
|
||||
acoustid_lookup =
|
||||
ps: with ps; [
|
||||
pyacoustid
|
||||
];
|
||||
airplay =
|
||||
ps: with ps; [
|
||||
srptools
|
||||
@@ -65,6 +84,10 @@
|
||||
];
|
||||
fanarttv = ps: [
|
||||
];
|
||||
fastmcp_server =
|
||||
ps: with ps; [
|
||||
fastmcp
|
||||
];
|
||||
filesystem_local = ps: [
|
||||
];
|
||||
filesystem_nfs = ps: [
|
||||
@@ -89,10 +112,14 @@
|
||||
ps: with ps; [
|
||||
pyheos
|
||||
];
|
||||
hue_entertainment = ps: [
|
||||
]; # missing hue-entertainment
|
||||
ibroadcast = ps: [
|
||||
]; # missing ibroadcastaio
|
||||
internet_archive = ps: [
|
||||
];
|
||||
itunes_artwork = ps: [
|
||||
];
|
||||
itunes_podcasts = ps: [
|
||||
];
|
||||
jellyfin =
|
||||
@@ -101,6 +128,8 @@
|
||||
];
|
||||
kion_music = ps: [
|
||||
]; # missing yandex-music
|
||||
lastfm_recommendations = ps: [
|
||||
];
|
||||
lastfm_scrobble =
|
||||
ps: with ps; [
|
||||
pylast
|
||||
@@ -109,16 +138,40 @@
|
||||
ps: with ps; [
|
||||
liblistenbrainz
|
||||
];
|
||||
local_audio =
|
||||
ps: with ps; [
|
||||
sounddevice
|
||||
];
|
||||
loudness_analysis = ps: [
|
||||
];
|
||||
lrclib = ps: [
|
||||
];
|
||||
motherearthradio = ps: [
|
||||
];
|
||||
mpd =
|
||||
ps: with ps; [
|
||||
python-mpd2
|
||||
];
|
||||
msx_bridge =
|
||||
ps: with ps; [
|
||||
pydantic
|
||||
];
|
||||
musicbrainz = ps: [
|
||||
];
|
||||
musiccast =
|
||||
ps: with ps; [
|
||||
aiomusiccast
|
||||
];
|
||||
nicovideo = ps: [
|
||||
]; # missing niconico.py-ma
|
||||
musicme = ps: [
|
||||
];
|
||||
neteasecloudmusic = ps: [
|
||||
];
|
||||
nicovideo =
|
||||
ps: with ps; [
|
||||
pydantic
|
||||
]; # missing niconico.py-ma
|
||||
nts = ps: [
|
||||
];
|
||||
nugs = ps: [
|
||||
];
|
||||
opensubsonic =
|
||||
@@ -147,6 +200,8 @@
|
||||
];
|
||||
qobuz = ps: [
|
||||
];
|
||||
qqmusic = ps: [
|
||||
]; # missing qqmusic-api-python
|
||||
radiobrowser =
|
||||
ps: with ps; [
|
||||
radios
|
||||
@@ -158,13 +213,26 @@
|
||||
async-upnp-client
|
||||
rokuecp
|
||||
];
|
||||
samsung_wam = ps: [
|
||||
]; # missing pywam
|
||||
sendspin =
|
||||
ps: with ps; [
|
||||
ps:
|
||||
with ps;
|
||||
[
|
||||
aiosendspin
|
||||
av
|
||||
];
|
||||
]
|
||||
++ aiosendspin.optional-dependencies.server;
|
||||
siriusxm = ps: [
|
||||
]; # missing sxm
|
||||
smart_fades =
|
||||
ps: with ps; [
|
||||
beat-this
|
||||
nnaudio
|
||||
threadpoolctl
|
||||
];
|
||||
smart_playlist = ps: [
|
||||
];
|
||||
snapcast =
|
||||
ps: with ps; [
|
||||
bidict
|
||||
@@ -173,6 +241,20 @@
|
||||
];
|
||||
somafm = ps: [
|
||||
];
|
||||
sonic_analysis =
|
||||
ps: with ps; [
|
||||
huggingface-hub
|
||||
pyyaml
|
||||
threadpoolctl
|
||||
torchlibrosa
|
||||
transformers
|
||||
];
|
||||
sonic_similarity =
|
||||
ps: with ps; [
|
||||
huggingface-hub
|
||||
transformers
|
||||
usearch
|
||||
];
|
||||
sonos =
|
||||
ps: with ps; [
|
||||
aiosonos
|
||||
@@ -220,8 +302,20 @@
|
||||
ps: with ps; [
|
||||
aiovban
|
||||
];
|
||||
webdav = ps: [
|
||||
];
|
||||
wiim =
|
||||
ps: with ps; [
|
||||
wiim
|
||||
];
|
||||
wikipedia = ps: [
|
||||
];
|
||||
yandex_music = ps: [
|
||||
]; # missing yandex-music
|
||||
]; # missing yandex-music, ya-passport-auth
|
||||
yandex_smarthome = ps: [
|
||||
]; # missing ya-passport-auth
|
||||
yandex_ynison = ps: [
|
||||
]; # missing ya-passport-auth
|
||||
yousee = ps: [
|
||||
];
|
||||
ytmusic =
|
||||
@@ -232,6 +326,7 @@
|
||||
ytmusicapi
|
||||
]; # missing deno
|
||||
zvuk_music = ps: [
|
||||
]; # missing zvuk-music
|
||||
];
|
||||
# missing zvuk-music
|
||||
};
|
||||
}
|
||||
|
||||
@@ -33,9 +33,13 @@ TEMPLATE = """# Do not edit manually, run ./update-providers.py
|
||||
{%- for provider in providers | sort(attribute='domain') %}
|
||||
{{ provider.domain }} = {% if provider.available %}ps: with ps;{% else %}ps:{% endif %} [
|
||||
{%- for requirement in provider.available | sort %}
|
||||
{{ requirement }}
|
||||
{{ requirement }}
|
||||
{%- endfor %}
|
||||
];{% if provider.missing %} # missing {{ ", ".join(provider.missing) }}{% endif %}
|
||||
]
|
||||
{%- for requirement in provider.extra_list_deps | sort %}
|
||||
++ {{ requirement }}
|
||||
{%- endfor %}
|
||||
;{% if provider.missing %} # missing {{ ", ".join(provider.missing) }}{% endif %}
|
||||
{%- endfor %}
|
||||
};
|
||||
}
|
||||
@@ -62,6 +66,9 @@ PACKAGE_MAP = {
|
||||
|
||||
|
||||
EXTRA_DEPS = {
|
||||
# Those providers cannot guard pydantic behind TYPE_CHECKING
|
||||
"msx_bridge": ["pydantic"],
|
||||
"nicovideo": ["pydantic"],
|
||||
"ytmusic": [
|
||||
# https://github.com/music-assistant/server/blob/2.5.8/music_assistant/providers/ytmusic/__init__.py#L120
|
||||
"bgutil-ytdlp-pot-provider",
|
||||
@@ -70,6 +77,11 @@ EXTRA_DEPS = {
|
||||
}
|
||||
|
||||
|
||||
EXTRA_LIST_DEPS = {
|
||||
"sendspin": ["aiosendspin.optional-dependencies.server"],
|
||||
}
|
||||
|
||||
|
||||
def run_sync(cmd: List[str]) -> None:
|
||||
print(f"$ {' '.join(cmd)}")
|
||||
process = run(cmd)
|
||||
@@ -194,6 +206,7 @@ class Provider:
|
||||
domain: str
|
||||
available: list[str] = field(default_factory=list)
|
||||
missing: list[str] = field(default_factory=list)
|
||||
extra_list_deps: list[str] = field(default_factory=list)
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.domain == other.domain
|
||||
@@ -207,7 +220,7 @@ async def resolve_providers(manifests) -> tuple[Set, Set]:
|
||||
providers = set()
|
||||
for manifest in manifests:
|
||||
provider = Provider(manifest.domain)
|
||||
requirements = manifest.requirements + EXTRA_DEPS.get(manifest.domain, [])
|
||||
requirements = manifest.requirements
|
||||
for requirement in requirements:
|
||||
# allow substituting requirement specifications that packaging cannot parse
|
||||
if requirement in PACKAGE_MAP:
|
||||
@@ -228,6 +241,12 @@ async def resolve_providers(manifests) -> tuple[Set, Set]:
|
||||
version = await get_package_version(attr)
|
||||
if version not in requirement.specifier:
|
||||
errors.append(f"{requirement} not satisfied by version {version}")
|
||||
if manifest.domain in EXTRA_DEPS:
|
||||
for requirement in EXTRA_DEPS[manifest.domain]:
|
||||
provider.available.append(requirement)
|
||||
if manifest.domain in EXTRA_LIST_DEPS:
|
||||
for requirement in EXTRA_LIST_DEPS[manifest.domain]:
|
||||
provider.extra_list_deps.append(requirement)
|
||||
providers.add(provider)
|
||||
if errors:
|
||||
print("\n - ", end="")
|
||||
|
||||
Reference in New Issue
Block a user