"""All constants for Music Assistant."""
-__version__ = "0.2.5"
+__version__ = "0.2.6"
REQUIRED_PYTHON_VER = "3.8"
# configuration keys/attributes
import json
import logging
import os
+import pathlib
import shutil
from typing import Any, List
from music_assistant.helpers.datetime import utc_timestamp
from music_assistant.helpers.encryption import _decrypt_string, _encrypt_string
from music_assistant.helpers.typing import MusicAssistant
-from music_assistant.helpers.util import create_task, merge_dict, try_load_json_file
+from music_assistant.helpers.util import create_task, try_load_json_file
from music_assistant.helpers.web import api_route
from music_assistant.models.config_entry import ConfigEntry, ConfigEntryType
from music_assistant.models.player import PlayerControlType
from music_assistant.models.provider import ProviderType
from passlib.hash import pbkdf2_sha256
+RESOURCES_DIR = (
+ pathlib.Path(__file__).parent.resolve().parent.resolve().joinpath("resources")
+)
+
LOGGER = logging.getLogger("config_manager")
DEFAULT_PLAYER_CONFIG_ENTRIES = [
"""Initialize class."""
self._data_path = data_path
self._stored_config = {}
- self._translations = {}
+ self._strings = {}
self.loading = False
self.mass = mass
if not os.path.isdir(data_path):
async def setup(self):
"""Async initialize of module."""
- self._translations = await self._fetch_translations()
+ self._strings = await self._fetch_strings()
@api_route("config/{conf_base}")
def base_items(self, conf_base: str) -> dict:
"""Return the config that is actually stored on disk."""
return self._stored_config
- @property
- def translations(self):
- """Return all translations."""
- return self._translations
+ @api_route("strings")
+ def all_strings(self):
+ """Return all strings for all languages."""
+ return self._strings
+
+ @api_route("strings/{language}")
+ def language_strings(self, language: str):
+ """Return all strings for given language."""
+ return self._strings[language]
def get_provider_config(self, provider_id: str, provider_type: ProviderType = None):
"""Return config for given provider."""
self.loading = False
@staticmethod
- async def _fetch_translations() -> dict:
- """Build a list of all translations."""
- base_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
- # get base translations
- translations_file = os.path.join(base_dir, "translations.json")
- res = try_load_json_file(translations_file)
- if res is not None:
- translations = res
- else:
- translations = {}
- # append provider translations but do not overwrite keys
- modules_path = os.path.join(base_dir, "providers")
- # load modules
- for dir_str in os.listdir(modules_path):
- dir_path = os.path.join(modules_path, dir_str)
- translations_file = os.path.join(dir_path, "translations.json")
- if not os.path.isfile(translations_file):
+ async def _fetch_strings() -> dict:
+ """Build a list of all strings/translations."""
+ strings = {}
+ for _file in os.listdir(RESOURCES_DIR.joinpath("strings")):
+ if not _file.endswith(".json"):
continue
- res = try_load_json_file(translations_file)
- if res is not None:
- translations = merge_dict(translations, res)
- return translations
+ language = _file.replace(".json", "")
+ lang_file = RESOURCES_DIR.joinpath("strings", _file)
+ strings[language] = try_load_json_file(lang_file)
+ return strings
def __load(self):
"""Load stored config from file."""
RESOURCES_DIR = (
pathlib.Path(__file__).parent.resolve().parent.resolve().joinpath("resources")
)
-ALERT_ANNOUNCE_FILE = str(RESOURCES_DIR.joinpath("alert_announce.flac"))
-ALERT_FINISH_FILE = str(RESOURCES_DIR.joinpath("alert_finish.flac"))
+ALERT_ANNOUNCE_FILE = str(RESOURCES_DIR.joinpath("announce.flac"))
+ALERT_FINISH_FILE = str(RESOURCES_DIR.joinpath("silence.flac"))
class PlayerManager:
+++ /dev/null
-{
- "en": {
- "desc_spotify_username": "Username for your Spotify account",
- "desc_spotify_password": "Password for your Spotify account"
- },
- "nl": {
- "desc_spotify_username": "Gebruikersnaam van jouw Spotify account",
- "desc_spotify_password": "Wachtwoord van jouw Spotify account"
- }
-}
\ No newline at end of file
+++ /dev/null
-{
- "en": {
- "Universal Group player": "Universal Group Player",
- "group_player_count": "Number of group players",
- "group_player_count_desc": "Select how many Universal group players should be created.",
- "group_player_players": "Players in group",
- "group_player_players_desc": "Select the players that should be part of this group.",
- "group_player_master": "Group master",
- "group_player_master_desc": "Select the player that should act as group master."
- },
- "nl": {
- "Universal Group player": "Universele groep speler",
- "group_player_count": "Aantal groep spelers",
- "group_player_count_desc": "Selecteer hoeveel groep spelers er aangemaakt moeten worden.",
- "group_player_players": "Groepsspelers",
- "group_player_players_desc": "Selecteer de spelers die deel uitmaken van deze groep.",
- "group_player_master": "Groepsbeheerder",
- "group_player_master_desc": "Selecteer de speler die dient als groepsbeheerder."
- }
-}
\ No newline at end of file
--- /dev/null
+{
+ "enabled": "Enabled",
+ "name": "Name",
+ "username": "Username",
+ "password": "Password",
+ "enable_player": "Enable this player",
+ "custom_name": "Custom name",
+ "max_sample_rate": "Maximum sample rate",
+ "volume_normalisation": "Enable Volume normalisation",
+ "target_volume": "Target Volume level",
+ "desc_player_name": "Set a custom name for this player.",
+ "crossfade_duration": "Enable crossfade",
+ "group_delay": "Correction of groupdelay",
+ "security": "Security",
+ "app_tokens": "App tokens",
+ "power_control": "Power Control",
+ "volume_control": "Volume Control",
+
+ "desc_sample_rate": "Set the maximum sample rate this player can handle.",
+ "desc_volume_normalisation": "Enable R128 volume normalisation to play music at an equally loud volume.",
+ "desc_target_volume": "Set the preferred target volume level in LUFS. The R128 default is -22 LUFS.",
+ "desc_crossfade": "Enable crossfading of Queue tracks by setting a crossfade duration in seconds.",
+ "desc_enable_provider": "Enable this provider.",
+ "desc_base_username": "Username to access this Music Assistant server.",
+ "desc_base_password": "A password to protect this Music Assistant server. Can be left blank but this is extremely dangerous if this server is reachable from outside.",
+ "desc_group_delay": "Only used on grouped playback. Adjust the delay of the grouped playback on this player",
+ "desc_power_control": "Use an external device as power control for this player.",
+ "desc_volume_control": "Use an external device as volume control for this player.",
+
+ "Universal Group player": "Universal Group Player",
+ "group_player_count": "Number of group players",
+ "group_player_count_desc": "Select how many Universal group players should be created.",
+ "group_player_players": "Players in group",
+ "group_player_players_desc": "Select the players that should be part of this group.",
+ "group_player_master": "Group master",
+ "group_player_master_desc": "Select the player that should act as group master.",
+
+ "desc_spotify_username": "Username for your Spotify account",
+ "desc_spotify_password": "Password for your Spotify account"
+}
\ No newline at end of file
--- /dev/null
+{
+ "enabled": "Ingeschakeld",
+ "name": "Naam",
+ "username": "Gebruikersnaam",
+ "password": "Wachtwoord",
+ "enable_player": "Deze speler inschakelen",
+ "custom_name": "Aangepaste name",
+ "max_sample_rate": "Maximale sample rate",
+ "volume_normalisation": "Volume normalisering inschakelen",
+ "target_volume": "Doel volume",
+ "desc_player_name": "Stel een aangepaste naam in voor deze speler.",
+ "crossfade_duration": "Crossfade inschakelen",
+ "security": "Beveiliging",
+ "app_tokens": "App tokens",
+ "group_delay": "Correctie van groepsvertraging",
+ "power_control": "Power Control",
+ "volume_control": "Volume Control",
+
+ "desc_sample_rate": "Stel de maximale sample rate in die deze speler aankan.",
+ "desc_volume_normalisation": "R128 volume normalisatie inschakelen om muziek altijd op een gelijk volume af te spelen.",
+ "desc_target_volume": "Selecteer het gewenste doelvolume in LUFS. De R128 standaard is -22 LUFS.",
+ "desc_crossfade": "Crossfade inschakelen door het instellen van een crossfade duur in seconden.",
+ "desc_enable_provider": "Deze provider inschakelen.",
+ "desc_base_username": "Gebruikersnaam waarmee deze server beveiligd moet worden.",
+ "desc_base_password": "Wachtwoord waarmee deze server beveiligd moet worden. Mag worden leeggelaten maar dit is extreem gevaarlijk indien je besluit de server extern toegankelijk te maken.",
+ "desc_group_delay": "Gebruikt bij afspelen in groep. Pas de vertraging aan voor deze player.",
+ "desc_power_control": "Gebruik een extern apparaat als aan/uit control voor deze speler.",
+ "desc_volume_control": "Gebruik een extern apparaat als volume control voor deze speler.",
+
+ "Universal Group player": "Universele groep speler",
+ "group_player_count": "Aantal groep spelers",
+ "group_player_count_desc": "Selecteer hoeveel groep spelers er aangemaakt moeten worden.",
+ "group_player_players": "Groepsspelers",
+ "group_player_players_desc": "Selecteer de spelers die deel uitmaken van deze groep.",
+ "group_player_master": "Groepsbeheerder",
+ "group_player_master_desc": "Selecteer de speler die dient als groepsbeheerder.",
+
+ "desc_spotify_username": "Gebruikersnaam van jouw Spotify account",
+ "desc_spotify_password": "Wachtwoord van jouw Spotify account"
+}
\ No newline at end of file
+++ /dev/null
-{
- "en": {
- "enabled": "Enabled",
- "name": "Name",
- "username": "Username",
- "password": "Password",
- "enable_player": "Enable this player",
- "custom_name": "Custom name",
- "max_sample_rate": "Maximum sample rate",
- "volume_normalisation": "Enable Volume normalisation",
- "target_volume": "Target Volume level",
- "desc_player_name": "Set a custom name for this player.",
- "crossfade_duration": "Enable crossfade",
- "group_delay": "Correction of groupdelay",
- "security": "Security",
- "app_tokens": "App tokens",
- "power_control": "Power Control",
- "volume_control": "Volume Control",
-
- "desc_sample_rate": "Set the maximum sample rate this player can handle.",
- "desc_volume_normalisation": "Enable R128 volume normalisation to play music at an equally loud volume.",
- "desc_target_volume": "Set the preferred target volume level in LUFS. The R128 default is -22 LUFS.",
- "desc_crossfade": "Enable crossfading of Queue tracks by setting a crossfade duration in seconds.",
- "desc_enable_provider": "Enable this provider.",
- "desc_base_username": "Username to access this Music Assistant server.",
- "desc_base_password": "A password to protect this Music Assistant server. Can be left blank but this is extremely dangerous if this server is reachable from outside.",
- "desc_group_delay": "Only used on grouped playback. Adjust the delay of the grouped playback on this player",
- "desc_power_control": "Use an external device as power control for this player.",
- "desc_volume_control": "Use an external device as volume control for this player."
- },
- "nl": {
- "enabled": "Ingeschakeld",
- "name": "Naam",
- "username": "Gebruikersnaam",
- "password": "Wachtwoord",
- "enable_player": "Deze speler inschakelen",
- "custom_name": "Aangepaste name",
- "max_sample_rate": "Maximale sample rate",
- "volume_normalisation": "Volume normalisering inschakelen",
- "target_volume": "Doel volume",
- "desc_player_name": "Stel een aangepaste naam in voor deze speler.",
- "crossfade_duration": "Crossfade inschakelen",
- "security": "Beveiliging",
- "app_tokens": "App tokens",
- "group_delay": "Correctie van groepsvertraging",
- "power_control": "Power Control",
- "volume_control": "Volume Control",
-
- "desc_sample_rate": "Stel de maximale sample rate in die deze speler aankan.",
- "desc_volume_normalisation": "R128 volume normalisatie inschakelen om muziek altijd op een gelijk volume af te spelen.",
- "desc_target_volume": "Selecteer het gewenste doelvolume in LUFS. De R128 standaard is -22 LUFS.",
- "desc_crossfade": "Crossfade inschakelen door het instellen van een crossfade duur in seconden.",
- "desc_enable_provider": "Deze provider inschakelen.",
- "desc_base_username": "Gebruikersnaam waarmee deze server beveiligd moet worden.",
- "desc_base_password": "Wachtwoord waarmee deze server beveiligd moet worden. Mag worden leeggelaten maar dit is extreem gevaarlijk indien je besluit de server extern toegankelijk te maken.",
- "desc_group_delay": "Gebruikt bij afspelen in groep. Pas de vertraging aan voor deze player.",
- "desc_power_control": "Gebruik een extern apparaat als aan/uit control voor deze speler.",
- "desc_volume_control": "Gebruik een extern apparaat als volume control voor deze speler."
- }
-}