Fail to run on <2.0.0 configuration files

This commit is contained in:
Ritiek Malhotra
2020-05-17 03:37:47 +05:30
parent e0e7048ced
commit 23e18e1550
6 changed files with 72 additions and 41 deletions

View File

@@ -8,10 +8,11 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
## [2.0.0] - <add-date-here-when-ready-to-publish>
### Migrating from v1.2.6 to v2.0.0
It is highly recommended to remove your previous `config.yml` due to breaking changes
in v2.0.0 (marked as **[Breaking]** in the below sections), new options being added, and old
ones being removed. You may want to first backup your old configuration for reference.
You can then install spotdl v2.0.0 and remove your current configuration by running:
For v2.0.0 to work correctly, you need to remove your previous `config.yml` due to
breaking changes in v2.0.0 (marked as **[Breaking]** in the below sections), new options being
added, and old ones being removed. You may want to first backup your old configuration for
reference. You can then install spotdl v2.0.0 and remove your current configuration by
running:
```
$ spotdl --remove-config
```
@@ -42,6 +43,9 @@ All the below changes were made as a part of #690.
Such as `-o .mp3` is now written as `-o mp3`.
- **[Breaking]** Search format now uses hyphen for word break instead of underscore. Such as
`-sf "{artist} - {track_name}"` is now written as `-sf "{artist} - {track-name}"`.
- **[Breaking]** `--write-sucessful` and `--skip` is renamed to `--write-succesful-file` and
`--skip-file` respectively.
Such as `-o .mp3` is now written as `-o mp3`.
- Partial re-write and internal API refactor.
- Enhance debug log output readability.
- Internally adapt to latest changes made in Spotipy library.
@@ -51,6 +55,8 @@ All the below changes were made as a part of #690.
for the already downloaded track to determine whether to overwrite the already downloaded
track, which caused unexpected behvaiours at times.
- Codebase is now more modular making it easier to use spotdl in python scripts.
- `config.yml` now uses underscores for separating between argument words instead of
hyphens for better compatibility with `argparse`.
### Optimized
- Track download and encoding now happen parallely instead of sequentially making spotdl

View File

@@ -31,10 +31,16 @@ def set_logger(level):
def main():
argument_handler = get_arguments()
logging_level = argument_handler.get_logging_level()
logger = set_logger(logging_level)
try:
argument_handler = get_arguments()
except ArgumentError as e:
logger = set_logger(logging.INFO)
logger.info(e.args[0])
sys.exit(5)
logging_level = argument_handler.get_logging_level()
print(logging_level)
logger = set_logger(logging_level)
try:
spotdl = Spotdl(argument_handler)
except ArgumentError as e:

View File

@@ -25,7 +25,7 @@ _LOG_LEVELS = {
if os.path.isfile(spotdl.config.DEFAULT_CONFIG_FILE):
saved_config = spotdl.config.read_config(spotdl.config.DEFAULT_CONFIG_FILE)
else:
saved_config = {}
saved_config = {"spotify-downloader": {}}
_CONFIG_BASE = spotdl.util.merge(
spotdl.config.DEFAULT_CONFIGURATION,
@@ -34,15 +34,33 @@ _CONFIG_BASE = spotdl.util.merge(
def get_arguments(config_base=_CONFIG_BASE):
defaults = config_base["spotify-downloader"]
parser = argparse.ArgumentParser(
description="Download and convert tracks from Spotify, Youtube etc.",
description="Download and convert tracks from Spotify, Youtube, etc.",
formatter_class=argparse.ArgumentDefaultsHelpFormatter,
)
defaults = config_base["spotify-downloader"]
to_remove_config = "--remove-config" in sys.argv[1:]
if not to_remove_config and "download-only-metadata" in defaults:
raise ArgumentError(
"The default configuration file currently set is not suitable for spotdl>=2.0.0.\n"
"You need to remove your previous `config.yml` due to breaking changes\n"
"introduced in v2.0.0, new options being added, and old ones being removed\n"
"You may want to first backup your old configuration for reference. You can\n"
"then remove your current configuration by running:\n"
"```\n"
"$ spotdl --remove-config\n"
"```\n"
"spotdl will automatically generate a new configuration file on the next run.\n"
"You can then replace the appropriate fields in the newly generated\n"
"configuration file by referring to your old configuration file.\n\n"
"For the list of OTHER BREAKING CHANGES and release notes check out:\n"
"https://github.com/ritiek/spotify-downloader/releases/tag/v2.0.0"
)
# `--remove-config` does not require the any of the group arguments to be passed.
require_group_args = not "--remove-config" in sys.argv[1:]
group = parser.add_mutually_exclusive_group(required=require_group_args)
group = parser.add_mutually_exclusive_group(required=not to_remove_config)
group.add_argument(
"-s",
@@ -188,24 +206,16 @@ def get_arguments(config_base=_CONFIG_BASE):
"generating filenames",
action="store_true",
)
parser.add_argument(
"-ll",
"--log-level",
default=defaults["log_level"],
choices=_LOG_LEVELS.keys(),
type=str.upper,
help="set log verbosity",
)
parser.add_argument(
"-sk",
"--skip",
default=defaults["skip"],
"--skip-file",
default=defaults["skip_file"],
help="path to file containing tracks to skip",
)
parser.add_argument(
"-w",
"--write-successful",
default=defaults["write_successful"],
"--write-successful-file",
default=defaults["write_successful_file"],
help="path to file to write successful tracks to",
)
parser.add_argument(
@@ -218,6 +228,14 @@ def get_arguments(config_base=_CONFIG_BASE):
default=defaults["spotify_client_secret"],
help=argparse.SUPPRESS,
)
parser.add_argument(
"-ll",
"--log-level",
default=defaults["log_level"],
choices=_LOG_LEVELS.keys(),
type=str.upper,
help="set log verbosity",
)
parser.add_argument(
"-c",
"--config",
@@ -268,7 +286,7 @@ class ArgumentHandler:
return self.configured_args
def get_logging_level(self):
return _LOG_LEVELS[self.args["log_level"]]
return _LOG_LEVELS[self.configured_args["log_level"]]
def run_errands(self):
args = self.get_configured_args()

View File

@@ -326,8 +326,8 @@ class Spotdl:
except (NoYouTubeVideoFoundError, NoYouTubeVideoMatchError) as e:
logger.error("{err}".format(err=e.args[0]))
else:
if self.arguments["write_successful"]:
with open(self.arguments["write_successful"], "a") as fout:
if self.arguments["write_sucessful_file"]:
with open(self.arguments["write_sucessful_file"], "a") as fout:
fout.write(track)
finally:
spotdl.util.writelines_to_nonbinary_file(path, tracks[position:])
@@ -397,8 +397,8 @@ class Spotdl:
tracks.append(current_track)
else:
tracks_count -= 1
if self.arguments["write_successful"]:
with open(self.arguments["write_successful"], "a") as fout:
if self.arguments["write_sucessful_file"]:
with open(self.arguments["write_sucessful_file"], "a") as fout:
fout.write(current_track)
finally:
current_iteration += 1

View File

@@ -10,7 +10,6 @@ DEFAULT_CONFIGURATION = {
"spotify-downloader": {
"manual": False,
"no_metadata": False,
"no_fallback_metadata": False,
"no_encode": False,
"overwrite": "prompt",
"quality": "best",
@@ -18,19 +17,16 @@ DEFAULT_CONFIGURATION = {
"output_ext": "mp3",
"write_to": None,
"trim_silence": False,
"download_only_metadata": False,
"search_format": "{artist} - {track-name} lyrics",
"dry_run": False,
"music_videos_only": False,
"no_spaces": False,
# "processor": "synchronous",
"output_file": "{artist} - {track-name}.{output-ext}",
"search_format": "{artist} - {track-name} lyrics",
"youtube_api_key": None,
"skip": None,
"write_successful": None,
"log_level": "INFO",
"skip_file": None,
"write_successful_file": None,
"spotify_client_id": "4fe3fecfe5334023a1472516cc99d805",
"spotify_client_secret": "0f02b7c483c04257984695007a4a8d5c",
"log_level": "INFO",
}
}

View File

@@ -44,10 +44,15 @@ class ThreadWithReturnValue(threading.Thread):
def merge(base, overrider):
""" Override default dict with config dict. """
merger = base.copy()
merger.update(overrider)
return merger
""" Override base dict with an overrider dict, recursively. """
for key, value in base.items():
if isinstance(value, dict):
subitem = overrider.setdefault(key, {})
merge(value, subitem)
else:
overrider[key] = value
return overrider
def prompt_user_for_selection(items):