diff --git a/src/music_kraken/__main__.py b/src/music_kraken/__main__.py index 2d611ea..e967f94 100644 --- a/src/music_kraken/__main__.py +++ b/src/music_kraken/__main__.py @@ -1,6 +1,3 @@ -import music_kraken - - if __name__ == "__main__": import argparse @@ -50,6 +47,8 @@ if __name__ == "__main__": print("Setting logging-level to DEBUG") logging.getLogger().setLevel(logging.DEBUG) + import music_kraken + # getting the genre genre: str = arguments.genre if arguments.test: diff --git a/src/music_kraken/utils/config/__init__.py b/src/music_kraken/utils/config/__init__.py index a8c8cf7..498067f 100644 --- a/src/music_kraken/utils/config/__init__.py +++ b/src/music_kraken/utils/config/__init__.py @@ -1,2 +1,7 @@ from .logging import LOGGING_SECTION from .audio import AUDIO_SECTION + +from .config import read, write + +read() +write() diff --git a/src/music_kraken/utils/config/audio.py b/src/music_kraken/utils/config/audio.py index 11dd695..f4232bb 100644 --- a/src/music_kraken/utils/config/audio.py +++ b/src/music_kraken/utils/config/audio.py @@ -1,6 +1,6 @@ import logging -from .config import SingleAttribute, FloatAttribute, StringAttribute, IntAttribute, Section, Description, EmptyLine +from .base_classes import SingleAttribute, FloatAttribute, StringAttribute, IntAttribute, Section, Description, EmptyLine # Only the formats with id3 metadata can be used # https://www.audioranger.com/audio-formats.php @@ -40,8 +40,8 @@ class AudioSection(Section): def __init__(self): self.BITRATE = FloatAttribute( name="bitrate", - description="Streams the audio with this bitrate (kB/s). Can't get more bitrate than the audio source " - "though.", + description="Streams the audio with given bitrate [kB/s]. " + "Can't stream with a higher Bitrate, than the audio source provides.", value="125" ) @@ -102,9 +102,9 @@ ID3.1: {', '.join(_sorted_id3_1_formats)} ) self.attribute_list = [ - EmptyLine(), self.BITRATE, self.AUDIO_FORMAT, + EmptyLine(), Description(""" There are multiple fields, you can use for the path and file name: - genre diff --git a/src/music_kraken/utils/config/base_classes.py b/src/music_kraken/utils/config/base_classes.py new file mode 100644 index 0000000..48d5bfd --- /dev/null +++ b/src/music_kraken/utils/config/base_classes.py @@ -0,0 +1,101 @@ +from dataclasses import dataclass +from typing import Optional, List, Union + +COMMENT_PREFIX = "#" + + +def comment_string(uncommented: str) -> str: + unprocessed_lines = uncommented.split("\n") + + processed_lines: List[str] = [] + + for line in unprocessed_lines: + line: str = line.strip() + if line.startswith(COMMENT_PREFIX) or line == "": + processed_lines.append(line) + continue + + line = COMMENT_PREFIX + " " + line + processed_lines.append(line) + + return "\n".join(processed_lines) + + +@dataclass +class Attribute: + name: str + description: Optional[str] + value: Union[str, List[str]] + + @property + def description_as_comment(self): + return comment_string(self.description) + + @property + def object_from_value(self): + return self.value + + def __str__(self): + return f"{self.description_as_comment}\n{self.name}={self.value}" + + +class SingleAttribute(Attribute): + value: str + + +class StringAttribute(SingleAttribute): + @property + def object_from_value(self) -> str: + return self.value.strip() + + +class IntAttribute(SingleAttribute): + @property + def object_from_value(self) -> int: + if not self.value.isdigit(): + raise ValueError(f"The value of {self.name} needs to be an integer, not {self.value}") + + return int(self.value) + + +class FloatAttribute(SingleAttribute): + @property + def object_from_value(self) -> float: + if not self.value.isnumeric(): + raise ValueError(f"The value of {self.name} needs to be a number, not {self.value}") + + return float(self.value) + + +class ListAttribute(Attribute): + value: List[str] + + def __str__(self): + return f"{self.description_as_comment}\n" + \ + "\n".join(f"{self.name}={element}" for element in self.value) + + +@dataclass +class Description: + description: str + + def __str__(self): + return comment_string(self.description) + + +class EmptyLine(Description): + def __init__(self): + self.description = "" + + +class Section: + """ + A placeholder class + """ + attribute_list: List[Union[ + Attribute, + Description + ]] + + def __str__(self): + return "\n".join(attribute.__str__() for attribute in self.attribute_list) diff --git a/src/music_kraken/utils/config/config.py b/src/music_kraken/utils/config/config.py index a77a4b1..9eb9b53 100644 --- a/src/music_kraken/utils/config/config.py +++ b/src/music_kraken/utils/config/config.py @@ -1,90 +1,46 @@ -from dataclasses import dataclass -from typing import Optional, List, Union +from typing import Union, Tuple +import logging +import os -COMMENT_PREFIX = "# " +from ..path_manager import LOCATIONS +from .base_classes import Description, Attribute, Section, EmptyLine +from .audio import AUDIO_SECTION +from .logging import LOGGING_SECTION -@dataclass -class Attribute: - name: str - description: Optional[str] - value: Union[str, List[str]] - - @property - def description_as_comment(self): - lines = self.description.split("\n") - - return "\n".join(f"{COMMENT_PREFIX}{line}" for line in lines) - - @property - def object_from_value(self): - return self.value - - def __str__(self): - return f"{self.description_as_comment}\n{self.name}={self.value}" - - -class SingleAttribute(Attribute): - value: str - - -class StringAttribute(SingleAttribute): - @property - def object_from_value(self) -> str: - return self.value.strip() - - -class IntAttribute(SingleAttribute): - @property - def object_from_value(self) -> int: - if not self.value.isdigit(): - raise ValueError(f"The value of {self.name} needs to be an integer, not {self.value}") - - return int(self.value) - - -class FloatAttribute(SingleAttribute): - @property - def object_from_value(self) -> float: - if not self.value.isnumeric(): - raise ValueError(f"The value of {self.name} needs to be a number, not {self.value}") - - return float(self.value) - - -class ListAttribute(Attribute): - value: List[str] - - def __str__(self): - return f"{self.description_as_comment}\n" + \ - "\n".join(f"{self.name}={element}" for element in self.value) - - -@dataclass -class Description: - description: str - - def __str__(self): - lines = self.description.split("\n") - return "\n".join(f"{COMMENT_PREFIX}{line}" for line in lines) - - -class EmptyLine(Description): +class Config: def __init__(self): - self.description = "\n" + self.config_elements: Tuple[Union[Description, Attribute, Section], ...] = ( + Description("IMPORTANT: If you modify this file, the changes for the actual setting, will be kept as is.\n" + "The changes you make to the comments, will be discarded, next time you run music-kraken. " + "Have fun!"), + Description("Those are all Settings for the audio codec.\n" + "If you, for some reason wanna fill your drive real quickly, I mean enjoy HIFI music,\n" + "feel free to tinker with the Bitrate or smth. :)"), + AUDIO_SECTION, + Description("For all your Logging needs.\n" + "If you found a bug, and wan't to report it, please set the Logging level to 0,\n" + "reproduce the bug, and attach the logfile in the bugreport. ^w^"), + LOGGING_SECTION, + Description("🏳️‍⚧️🏳️‍⚧️ Protect trans youth. 🏳️‍⚧️🏳️‍⚧️"), + EmptyLine() + ) - def __str__(self): - return self.description + @property + def config_string(self) -> str: + return "\n\n".join(str(element) for element in self.config_elements) + + def write_to_config_file(self, path: os.PathLike): + with open(path, "w") as conf_file: + conf_file.write(self.config_string) -class Section: - """ - A placeholder class - """ - attribute_list: List[Union[ - Attribute, - Description - ]] +config = Config() - def __str__(self): - return "\n".join(attribute.__str__() for attribute in self.attribute_list) + +def read(): + pass + + +def write(): + config.write_to_config_file(LOCATIONS.CONFIG_FILE) diff --git a/src/music_kraken/utils/config/logging.py b/src/music_kraken/utils/config/logging.py index ac31ba4..d9491cc 100644 --- a/src/music_kraken/utils/config/logging.py +++ b/src/music_kraken/utils/config/logging.py @@ -1,7 +1,7 @@ import logging from typing import Callable -from .config import SingleAttribute, StringAttribute, Section, Description, EmptyLine +from .base_classes import SingleAttribute, StringAttribute, Section, Description, EmptyLine LOG_LEVELS = { "CRITICAL": 50, @@ -104,6 +104,7 @@ class LoggingSection(Section): Description("Logging settings for the actual logging:"), self.FORMAT, self.LOG_LEVEL, + EmptyLine(), Description("Just the names for different logger, for different parts of the programm:"), self.DOWNLOAD_LOGGER, self.TAGGING_LOGGER, diff --git a/src/music_kraken/utils/path_manager/locations.py b/src/music_kraken/utils/path_manager/locations.py index a53ef3e..54e982d 100644 --- a/src/music_kraken/utils/path_manager/locations.py +++ b/src/music_kraken/utils/path_manager/locations.py @@ -16,6 +16,7 @@ class Locations: self.CONFIG_DIRECTORY = get_config_directory(str(application_name)) self.CONFIG_DIRECTORY.mkdir(exist_ok=True) + self.CONFIG_FILE = Path(self.CONFIG_DIRECTORY, f"{application_name}.conf") def get_log_file(self, file_name: os.PathLike) -> Path: return Path(self.TEMP_DIRECTORY, file_name)