Merge pull request #157 from nathom/better_config_update

Keep more of the config when updating
This commit is contained in:
Nathan Thomas 2021-08-17 10:04:41 -07:00 committed by GitHub
commit c9dfc61d9f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -5,7 +5,7 @@ import logging
import os import os
import shutil import shutil
from pprint import pformat from pprint import pformat
from typing import Any, Dict from typing import Any, Dict, List, Union
import tomlkit import tomlkit
from click import secho from click import secho
@ -31,7 +31,9 @@ class Config:
values. values.
""" """
default_config_path = os.path.join(os.path.dirname(__file__), "config.toml") default_config_path = os.path.join(
os.path.dirname(__file__), "config.toml"
)
with open(default_config_path) as cfg: with open(default_config_path) as cfg:
defaults: Dict[str, Any] = tomlkit.parse(cfg.read().strip()) defaults: Dict[str, Any] = tomlkit.parse(cfg.read().strip())
@ -55,7 +57,10 @@ class Config:
if os.path.isfile(self._path): if os.path.isfile(self._path):
self.load() self.load()
if self.file["misc"]["version"] != self.defaults["misc"]["version"]: if (
self.file["misc"]["version"]
!= self.defaults["misc"]["version"]
):
secho( secho(
"Updating config file to new version. Some settings may be lost.", "Updating config file to new version. Some settings may be lost.",
fg="yellow", fg="yellow",
@ -71,21 +76,51 @@ class Config:
def update(self): def update(self):
"""Reset the config file except for credentials.""" """Reset the config file except for credentials."""
self.reset()
# Save original credentials # Save original credentials
qobuz_creds = self.file["qobuz"] cached_info = self._cache_info(
tidal_creds = self.file["tidal"] [
"qobuz",
"tidal",
"deezer",
"downloads.folder",
"filepaths.folder_format",
"filepaths.track_format",
]
)
# Reset and load config file # Reset and load config file
shutil.copy(self.default_config_path, self._path) shutil.copy(self.default_config_path, self._path)
self.load() self.load()
# Set credentials and download directory, then save self._dump_cached(cached_info)
self.file["qobuz"].update(qobuz_creds)
self.file["tidal"].update(tidal_creds)
self.file["downloads"]["folder"] = DOWNLOADS_DIR
self.save() self.save()
def _dot_get(self, dot_key: str) -> Union[dict, str]:
"""Get a key from a toml file using section.key format."""
item = self.file
for key in dot_key.split("."):
item = item[key]
return item
def _dot_set(self, dot_key, val):
"""Set a key in the toml file using the section.key format."""
keys = dot_key.split(".")
item = self.file
for key in keys[:-1]: # stop at the last one in case it's an immutable
item = item[key]
item[keys[-1]] = val
def _cache_info(self, keys: List[str]):
"""Return a deepcopy of the values from the config to be saved."""
return {key: copy.deepcopy(self._dot_get(key)) for key in keys}
def _dump_cached(self, cached_values):
"""Set cached values into the current config file."""
for k, v in cached_values.items():
self._dot_set(k, v)
def save(self): def save(self):
"""Save the config state to file.""" """Save the config state to file."""
self.dump(self.file) self.dump(self.file)
@ -111,7 +146,6 @@ class Config:
self.session[k] = v self.session[k] = v
logger.debug("Config loaded") logger.debug("Config loaded")
self.__loaded = True
def dump(self, info): def dump(self, info):
"""Given a state of the config, save it to the file. """Given a state of the config, save it to the file.
@ -158,6 +192,6 @@ class Config:
raise InvalidSourceError(source) raise InvalidSourceError(source)
def __repr__(self): def __repr__(self) -> str:
"""Return a string representation of the config.""" """Return a string representation of the config."""
return f"Config({pformat(self.session)})" return f"Config({pformat(self.session)})"