Configuration Access

The following class diagram shows the implementation of MusicDBs configuration and state management. Only the more important methods are shown in the diagram. For a list of all methods see the related documentation of the class.

digraph hierarchy { size="5,5" node[shape=record,style=filled,fillcolor=gray95] edge[dir=back, arrowtail=empty] csv [label = "{CSVFile||+ Read()\l+ Write()\l}"] config [label = "{Config||+ Load()\l+ Reload()\l+ Save()\l+ OptionAvailable()\l+ Get()\l+ Set()\l}"] musicdb [label = "{MusicDBConfig||- GetDirectory()\l- GetFile()\l}"] extern [label = "{ExternConfig||}"] mdbstate [label = "{MDBState||+ GetFilterlist()\l}"] config -> musicdb config -> extern config -> mdbstate csv -> mdbstate [arrowtail=open] }

Base Configuration Classes

ini Files

This module handles the reading and writing of ini-files. The definition of names is shown in the ini file example below.

[section]
option = value
class musicdb.lib.cfg.config.Config(filename=None)[source]
AllowNoneValue(allow=True)[source]

This method enables the possibility to configure (read) a None value. In case a value has the string "None", the Get() method returns None. The upper case N is important!

Default behavior of this class is to return the string "None" as regular string.

Parameters

allow (bool) – if True none values are allowed, otherwise the string "None" gets returned as a string

Returns

None

Example

[test]
option = None
cfg = Config("test.ini")

x = cfg.Get(str, "test", "option")
print(type(x))  # str

cfg.AllowNoneValue()

x = cfg.Get(str, "test", "option")
print(type(x))  # NoneType
Get(datatype, section, option, default=None, islist=False)[source]

This method reads a value from the configuration. The values in the file are all stored as string. Using the datatype parameter will convert that string into a python data type.

The default parameter can be used to define a value that shall be returned in case the option does not exist. This value can be of a different type than defined by the datatype parameter.

If the value of an option is "None", and none type is allowed by calling AllowNoneValue(), None gets returned.

If the islist parameter is set to True, the read value gets interpreted as comma separated list and split. A list of the striped values (without leading or trailing spaces) gets returned casted to the data type given by the datatype parameter.

Parameters
  • datatype – The data type of the value. This can be bool, int, float or str.

  • section (str) – Name of the section to read from

  • option (str) – Name of the option to read

  • default – Default value in case the option does not exist

  • islist (bool) – Interpret the value as a comma separated list

Returns

The value of an option

Example

[test]
integer = 1000
list = 13, 23, 42
cfg = Config("test.ini")

x = cfg.Get(int, "test", "integer")
print(x)    # 1000

x = cfg.Get(int, "test", "list", [], True)
print(x)    # [13, 23, 42]

x = cfg.Get(int, "test", "noneexisting", 1337)
print(x)    # 1337
Load(path=None)[source]

This method loads a configuration file. If the path parameter is not None, the path given while instantiating the class will be overwritten. If the file was already loaded, it gets reloaded.

Parameters

path (str) – Absolute path to an ini file

Returns

Nothing

Raises

AssertionError – If internal path variable and parameter is None. (No path given)

OptionAvailable(section, option)[source]

This method can be used to check if an option exists in the configuration file.

Parameters
  • section (str) – Name of the section

  • option (str) – Name of the option

Returns

True if the option exists, otherwise False

Reload()[source]

This method just calls Load() without a path argument.

Save()[source]

This method saves all set values back to the configuration file.

Changing configuration can be prevented by setting the file attributes to read only.

If writing fails not because of missing write permission, an exception gets raised.

Set(section, option, value)[source]

This method sets an option. The value gets casted to a string. If the section or option does not exist, it will be created.

After setting the option, the Save() method gets called to store the changes. This is necessary because there is no reliable destructor in python to.

Parameters
  • section (str) – Section to write at

  • option (str) – Name of the option to set

  • value – Value to store

Returns

Nothing

csv Files

This module handles the reading and writing of csv-files.

class musicdb.lib.cfg.csv.CSVFile(path)[source]

This class reads Comma Separated Value (CSV) files as used by MusicDB.

The class does not cache the files content. Every read access accesses the actual file. Writing does the file update.

The csv files this class works with must have the following dialect:

  • first line is a header line

  • delimiter: ,

  • escapechar: \

  • quotechar: "

  • quoting: csv.QUOTE_NONNUMERIC

  • line break: \n

It is allowed to modify the CSV files with external programs, but not guaranteed that MusicDB will not overwrite the changes. It is recommended to only read the files outside of MusicDB. Do not change the layout of the files!

Parameters

path (str) – Absolute path of the csv file the class works with

Read()[source]

This method reads the file and returns its a table represented as a list of dictionaries. The dictionary has a key for each column in the header of the file. So each entry in the list represents one row of the file, and each entry in the dictionary represents one cell or column in that row.

Example

name, id
a, 1
b, 2
c, 3
table = csv.Read()
print(table)
[
    {'name': 'a', 'id': 1},
    {'name': 'b', 'id': 2},
    {'name': 'c', 'id': 3}
]
Returns

A list of dictionaries with one entry or each cell. When the file does not exist, None gets returned.

Raises

StopIteration – When the CSV file is empty

Write(table, header=None)[source]

Write rows into the csv file. The first row will be the header of the table.

If there is no header given, the keys of the first dictionary will be used. The header also filters the values to store.

If the table is empty, a header is required.

Example

[
    {'name': 'a', 'id': 1, 'temp': 'x'},
    {'name': 'b', 'id': 2, 'temp': 'y'},
    {'name': 'c', 'id': 3, 'temp': 'z'}
]
print(table)
csv.Write(table, ["name", "id"])

# When using
#csv.Write(table)
# also the temp values would be stored
name, id
a, 1
b, 2
c, 3
Parameters
  • table (list) – A list with dictionaries of values for each column

  • header (list) – The header of the CSV file. Each entry must also be a key in the table dictionary! If None, then all keys of the dictionaries will be used.

Returns

None

Raises
  • TypeError – when table is not a list

  • ValueError – when the table list has not at least one entry and there is no header specified

  • TypeError – when the table list elements are not dictionaries

  • TypeError – when header is not a list and not None

MusicDB Configuration File

Detail of the MusicDB Configuration can be found under MusicDB Configuration.

All sections and options can be accessed by their names: MusicDBConfig(...).section.option.

Details of the configurations possible for MusicDB can be found in MusicDB Configuration.

To create a new entry for the MusicDB Configuration the following steps must be done:

  1. Set the section and option in the configuration file as well as in the template in the share directory

  2. In case a new section shall be created, create an empty class for this section inside this module

  3. Read the option in the constructor of the MusicDBConfig class

For example, the following option shall be added:

[newmod]
enable = True

The option must be read inside the MusicDBConfig __init__ method. The read value must be written into an attribute named as the option, inside an instance of the dummy class named liked the section:

self.newmod = SECTION()
self.newmod.enable = self.Get(bool, "newmod", "enable", False)

Now, the new option is available in the configuration object created using this class:

cfg = MusicDBConfig("musicdb.ini")
if cfg.newmod.enable:
    print("newmod enabled!")
class musicdb.lib.cfg.musicdb.MusicDBConfig(path='/etc/musicdb.ini')[source]

This class provides the access to the MusicDB configuration file.

By default, the configuration will be read from /etc/musicdb.ini.

Parameters

path (str) – Optional alternative configuration path. Default is /etc/musicdb.ini

GetDirectory(section, option, default)[source]

This method gets a string from the configuration file and checks if it is an existing directory. If not it prints a warning. The “invalid” path will be returned anyway, because it may be OK that the directory does not exist yet.

Parameters
  • section (str) – Section of an ini-file

  • option (str) – Option inside the section of an ini-file

  • default (str) – Default directory path if option is not set in the file

Returns

The value of the option set in the config-file or the default value.

GetFile(section, option, default)[source]

This method gets a string from the configuration file and checks if it is an existing file. If not it prints a warning. The “invalid” path will be returned anyway, because it may be OK that the file does not exist yet.

Parameters
  • section (str) – Section of an ini-file

  • option (str) – Option inside the section of an ini-file

  • default (str) – Default file path if option is not set in the file

Returns

The value of the option set in the config-file or the default value.

WebUI Configuration File

This module takes care of the WebUI configuration.

The following sections and keys are available:

[meta]
version=3

[WebUI]
videomode=disabled
lyrics=enabled

[MainMenu]
showstreamplayer=False
showsystemstatus=True

[ArtistsView]
showrelease=True

[GenreSelectionView]
showother=True

[Stream]
url=http://127.0.0.1:8000/stream
username=
password=

[debug]
blurartwork=false
[meta]->version (integer):

Version of the configuration scheme

[WebUI]->videomode (string: "enabled", "disabled"):

Defines if the video mode should be present in the WebUI or not. This includes, but is not limited to, the buttons of the main menu

[WebUI]->lyrics (string: "enabled", "disabled"):

Defines if lyrics should be present in the WebUI or not. This includes, but is not limited to, the lyrics state buttons in the Song Lists of the albums

[MainMenu]->showstreamplayer (boolean):

If True, then the MusicDB audio stream player is shown in the main menu. This player can them be used to connect to the audio stream from the WebUI.

[MainMenu]->showsystemstatus (boolean):

If True, the MusicDB system status is shown in the main menu. It shows if the connection between the MusicDB Server and Icecast is up and if data gets streamed. These information are not mandatory to know but help you to quickly identify issues with the audio stream.

[ArtistsView]->showrelease (boolean):

If true, the release date of an album is shown next to its name. If false, the release date will not be shown. In any case, the albums of an artist are sorted by their release date.

[GenreSelectionView]->showother (boolean):

If true, the default genre “Other” will be listed.

[Stream]->url,username,password (strings):

Access data to the audio stream that gets managed by MusicDB. If the stream is not protected by the authentication methods of Icecast, no user name or password is required.

[debug]->blurartwork (boolean):

If true, all artworks are blurred. This is useful to avoid copyright violations on screenshots that shall be public available

class musicdb.lib.cfg.webui.WebUIConfig(path)[source]

This class holds the configuration for the WebUI.

Parameters

path – Absolute path to the WebUI configuration file

LoadConfig()[source]

This method loads the current WebUI configuration and returns them in a dictionary.

Returns

dict with the whole WebUI configuration

SaveConfig(cfg)[source]

This method saves the current WebUI configuration. It is important that the whole configuration is included in cfg.

Parameters

cfg (dict) – Dictionary with the whole configuration

Returns

Nothing

External Storage Configuration File

This class reads the configuration of an external music storage. All sections and options can be accessed by their names: ExternConfig(...).section.option. If values get changed, they will not be stored!

Example

[meta]
version = 1
cfg = ExternConfig("test.ini")
print(cfg.meta.version)
class musicdb.lib.cfg.extern.ExternConfig(filename)[source]

MusicDB State Files

This module takes care that the state of MusicDB will persist over several sessions. This is not done automatically by the MDBState class. Each read or write process to the files that hold the state will be triggered by the classes who manage the related information.

The state is stored in several files in a sub-directory state inside the MusicDB data directory. More details can be found in MusicDB Data Files and Directories.

All files inside the state directory are managed by the MDBState class. The content of those files should not be changed by any user because its content gets not validated.

class musicdb.lib.cfg.mdbstate.MDBState(path, musicdb=None)[source]

This class holds the MusicDB internal state.

The following table shows which method is responsible for which file in the MusicDB State Directory.

File Name

Read Method

Write Method

songqueue.csv

LoadSongQueue()

SaveSongQueue()

videoqueue.csv

LoadVideoQueue()

SaveVideoQueue()

artistblacklist.csv

LoadBlacklists()

SaveBlacklists()

albumblacklist.csv

LoadBlacklists()

SaveBlacklists()

songblacklist.csv

LoadBlacklists()

SaveBlacklists()

videoblacklist.csv

LoadBlacklists()

SaveBlacklists()

Additional this class allows to access the file state.ini in the MusicDB State Directory. The file can be accessed via Set() and Get(). The section meta is reserved for this MDBState class.

Another section is MusicDB that represents the state of the MusicDB WebUI (and possibly backend in future). One key is uimode that can be set via SetUIMode() and read via GetUIMode(). The value for this key is a string and can be "audio" or "video". The value represents if the user interface is in audio-mode to manage an audio stream or video-mode to present music videos.

The method GetFilterList() accesses a section albumfiler. Each key in this section represents a main genre (all characters lower case) tag and can have the value True or False. If a genre is not listed in this section, it is assumed to have the value False. As soon as the genre gets activated via the WebUIs genre selection interface, it appears in the albumfiler-list.

Parameters
  • path – Absolute path to the MusicDB state directory

  • musicdb – Instance of the MusicDB Database (can be None)

GetFilterList()[source]

This method returns a list of the activated genre The list consists of the names of the genres as configured by the user. That are the names returned by musicdb.lib.db.musicdb.MusicDatabase.GetAllTags().

The available genres get compared to the ones set in the state.ini file inside the MusicDB State directory. If a genre is not defined in the configuration file, its default value is False and so it is not active. Before the comparison, the state file gets reloaded so that external changes get applied directly.

See UpdateFilterList() for changing the state of the genres.

Example

filter = mdbstate.GetFilterList()
print(filter) # ['Metal','NDH']
# Metal and NDH are active, other available genres are not enabled.
Returns

A list of main genre names that are activated

GetUIMode()[source]

This method simply returns the content of [MusicDB]->uimode in the state.ini file. In case the value is invalid or not set, "audio" gets returned.

Valid strings are "audio" or "video"

Returns

A string "audio" or "video"

LoadBlacklists(songbllen, albumbllen, artistbllen, videobllen)[source]

This method returns a dictionary with the blacklist used by musicdb.mdbapi.randy.Randy. The blacklists are managed by the BlacklistInterface class. This method also handles the blacklist length by adding empty entries or cutting off exceeding ones.

Parameters
  • songbllen (int) – Number of entries the blacklist shall have

  • albumbllen (int) – Number of entries the blacklist shall have

  • artistbllen (int) – Number of entries the blacklist shall have

  • videobllen (int) – Number of entries the blacklist shall have

Returns

A dictionary with the blacklists as expected by musicdb.mdbapi.randy.Randy

LoadSongQueue()[source]

This method reads the song queue from the state directory.

The method returns the queue as needed inside musicdb.mdbapi.songqueue.SongQueue(): A list of dictionaries, each containing the entryid and songid as integers and israndom as boolean.

The UUIDs of the queue entries remain.

Returns

A stored song queue

LoadVideoQueue()[source]

This method reads the video queue from the state directory.

The method returns the queue as needed inside musicdb.mdbapi.videoqueue.VideoQueue(): A list of dictionaries, each containing the entryid and videoid as integers and israndom as boolean.

The UUIDs of the queue entries remain.

Returns

A stored video queue

ReadList(listname)[source]

Reads a list from the mdbstate directory. The listname argument defines which file gets read: config.directories.state + "/listname.csv".

This method should only be used by class internal methods. When a file can not be accessed, an empty list gets returned. So deleting a file is an option to reset an internal state of MusicDB.

Parameters

listname (str) – Name of the list to read without trailing .csv

Returns

A list of rows from the file. When reading the list fails, an empty list gets returned.

SaveBlacklists(blacklists)[source]

This method stores the blacklist in the related CSV files. The data structure of the dictionary is expected to be the same, musicdb.mdbapi.blacklist.BlacklistInterface uses.

Parameters

blacklist (dict) – A dictionary of blacklists.

Returns

Nothing

SaveSongQueue(queue)[source]

This method saves a song queue. The data structure of the queue must be exact as the one expected when the queue shall be loaded.

Parameters

queue (dictionary) – The song queue to save.

Returns

Nothing

SaveVideoQueue(queue)[source]

This method saves a video queue. The data structure of the queue must be exact as the one expected when the queue shall be loaded.

Parameters

queue (dictionary) – The video queue to save.

Returns

Nothing

SetUIMode(mode)[source]

Sets the UI mode in the state.ini file. Before writing the data mode gets checked if it contains a valid value. If mode is an invalid argument, an exception gets raised.

Parameters

mode (str) – "audio" or "video" mode

Returns

None

Raises
  • TypeError – When mode is not of type string

  • ValueError – When mode contains an invalid string

UpdateFilterList(genre, enable)[source]

Sets the enable-state of a genre to the value of the parameter enable.

The value is stored in the state.ini file under the category "albumfilter". See GetFilterList() for reading out the information.

Parameters
  • genre (str) – Name of a genre to enable or disable

  • enable (bool) – Enable or disable genre

Returns

Nothing

WriteList(listname, rows, header=None)[source]

This method write a list of rows into the related file. The listname argument defines which file gets written: config.directories.state + "/listname.csv".

When there is no header given (list of column names), the keys of the rows-dictionaries are used.

This method should only be used by class internal methods.

Parameters
  • listname (str) – Name of the list to read without trailing .csv

  • rows (list) – The list that shall be stored

  • header (list) – Optional list with column names as string.

Returns

True on success, otherwise False

WebSocket API Key File

This module takes care of the WebSocket API Key

The key will be stored in the MusicDB data directory inside the config sub directory.

class musicdb.lib.cfg.wsapikey.WebSocketAPIKey(config)[source]

This class manages the WebSocket API Key. Use the method Read() to get the API key.

If the key is missing, it will be generated. A new key gets also be set in the WebUI JavaScript configuration file config.js.

To generate a new key, delete the wsapikey.txt from the MusicDB Configuration Directory.

Parameters

config – Instance of the MusicDBConifg class

CreateIfMissing()[source]

This method creates a new WebSocket API Key if none has been created yet.

If the WebSocke API Key file exists nothing will be done. If it is missing, it will be created including a new WebSocket API Key.

It also updates a new generated WebUI config.js file. It is expected that the config.js file exists.

The WebUI JavaScript configuration must already exist. If that file already has a key, it will not be replaced. If no key exists yet (a dummy key WSAPIKEY is expected in place) the key will be set.

For creating the key, openssl is used:

openssl rand -base64 -out $path 32
Returns

True on success or if the key already exists, otherwise False

Read()[source]

Reads the WebSocket API Key and returns it as string. If it does not exist, it will be created via CreateIfMissing().

Raises an exception if the key file cannot be created.

Returns

The WebSocket API Key as string.