pyscrobbler special ¶
Self-hosted open source multimedia scrobbler.
adapters special ¶
Module to store the functions shared by the different adapters.
config ¶
Define the configuration of the main program.
Config ¶
Expose the configuration in a friendly way.
Public methods: get: Fetch the configuration value of the specified key. load: Load the configuration from the configuration YAML file. save: Saves the configuration in the configuration YAML file.
Attributes and properties: config_path (str): Path to the configuration file. data(dict): Program configuration.
__init__(self, config_path='~/.local/share/pyscrobbler/config.yaml') special ¶
Configure the attributes and load the configuration.
Source code in pyscrobbler/config.py
def __init__(
self, config_path: str = "~/.local/share/pyscrobbler/config.yaml"
) -> None:
"""Configure the attributes and load the configuration."""
super().__init__()
self.config_path = os.path.expanduser(config_path)
self.load()
get(self, key, default=None) ¶
Fetch the configuration value of the specified key.
If there are nested dictionaries, a dot notation can be used.
So if the configuration contents are:
self.data = { 'first': { 'second': 'value' }, }
self.data.get('first.second') == 'value'
Source code in pyscrobbler/config.py
def get(
self, key: str, default: Any = None
) -> Union[str, int, Dict[str, Any], List[Any]]:
"""Fetch the configuration value of the specified key.
If there are nested dictionaries, a dot notation can be used.
So if the configuration contents are:
self.data = {
'first': {
'second': 'value'
},
}
self.data.get('first.second') == 'value'
"""
original_key = key
config_keys = key.split(".")
value = self.data.copy()
for config_key in config_keys:
try:
value = value[config_key]
except KeyError as error:
if default is not None:
return default
raise ConfigError(
f"Failed to fetch the configuration {config_key} "
f"when searching for {original_key}"
) from error
return value
load(self) ¶
Load the configuration from the configuration YAML file.
Source code in pyscrobbler/config.py
def load(self) -> None:
"""Load the configuration from the configuration YAML file."""
try:
with open(os.path.expanduser(self.config_path), "r") as file_cursor:
try:
self.data = YAML().load(file_cursor)
except (ParserError, ScannerError) as error:
raise ConfigError(str(error)) from error
except FileNotFoundError as error:
raise ConfigError(
"The configuration file {self.config_path} could not be found."
) from error
save(self) ¶
Save the configuration in the configuration YAML file.
Source code in pyscrobbler/config.py
def save(self) -> None:
"""Save the configuration in the configuration YAML file."""
with open(os.path.expanduser(self.config_path), "w+") as file_cursor:
yaml = YAML()
yaml.default_flow_style = False
yaml.dump(self.data, file_cursor)
set(self, key, value) ¶
Set the configuration value of the specified key.
If there are nested dictionaries, a dot notation can be used.
So if you want to set the configuration:
self.data = { 'first': { 'second': 'value' }, }
self.data.set('first.second', 'value')
Source code in pyscrobbler/config.py
def set(self, key: str, value: Union[str, int]) -> None:
"""Set the configuration value of the specified key.
If there are nested dictionaries, a dot notation can be used.
So if you want to set the configuration:
self.data = {
'first': {
'second': 'value'
},
}
self.data.set('first.second', 'value')
"""
config_keys: List[str] = key.split(".")
last_key = config_keys.pop(-1)
# Initialize the dictionary structure
parent = self.data
for config_key in config_keys:
try:
parent = parent[config_key]
except KeyError:
parent[config_key] = {}
parent = parent[config_key]
# Set value
parent[last_key] = value
ConfigError ¶
Catch configuration errors.
entrypoints special ¶
Define the different ways to expose the program functionality.
Functions
load_logger: Configure the Logging logger.
load_config(config_path) ¶
Load the configuration from the file.
Source code in pyscrobbler/entrypoints/__init__.py
def load_config(config_path: str) -> Config:
"""Load the configuration from the file."""
log.debug(f"Loading the configuration from file {config_path}")
try:
config = Config(config_path)
except ConfigError as error:
log.error(f"Configuration Error: {str(error)}")
sys.exit(1)
except FileNotFoundError:
log.error(f"Error opening configuration file {config_path}")
sys.exit(1)
return config
load_logger(verbose=False) ¶
Configure the Logging logger.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
verbose | bool | Set the logging level to Debug. | False |
Source code in pyscrobbler/entrypoints/__init__.py
def load_logger(verbose: bool = False) -> None: # pragma no cover
"""Configure the Logging logger.
Args:
verbose: Set the logging level to Debug.
"""
logging.addLevelName(logging.INFO, "[\033[36m+\033[0m]")
logging.addLevelName(logging.ERROR, "[\033[31m+\033[0m]")
logging.addLevelName(logging.DEBUG, "[\033[32m+\033[0m]")
logging.addLevelName(logging.WARNING, "[\033[33m+\033[0m]")
if verbose:
logging.basicConfig(
stream=sys.stderr, level=logging.DEBUG, format=" %(levelname)s %(message)s"
)
else:
logging.basicConfig(
stream=sys.stderr, level=logging.INFO, format=" %(levelname)s %(message)s"
)
cli ¶
Command line interface definition.
model special ¶
Module to store the common business model of all entities.
Abstract Classes:
services ¶
Gather all the orchestration functionality required by the program to work.
Classes and functions that connect the different domain model objects with the adapters and handlers to achieve the program's purpose.
version ¶
Utilities to retrieve the information of the program version.
version_info() ¶
Display the version of the program, python and the platform.
Source code in pyscrobbler/version.py
def version_info() -> str:
"""Display the version of the program, python and the platform."""
info = {
"pyscrobbler version": __version__,
"python version": sys.version.replace("\n", " "),
"platform": platform.platform(),
}
return "\n".join(f"{k + ':' :>30} {v}" for k, v in info.items())