mirror of
https://github.com/KevinMidboe/spotify-downloader.git
synced 2026-02-12 12:29:24 +00:00
Implement --write-successful-file and --skip-file
This commit is contained in:
@@ -39,7 +39,6 @@ def main():
|
|||||||
sys.exit(5)
|
sys.exit(5)
|
||||||
|
|
||||||
logging_level = argument_handler.get_logging_level()
|
logging_level = argument_handler.get_logging_level()
|
||||||
print(logging_level)
|
|
||||||
logger = set_logger(logging_level)
|
logger = set_logger(logging_level)
|
||||||
try:
|
try:
|
||||||
spotdl = Spotdl(argument_handler)
|
spotdl = Spotdl(argument_handler)
|
||||||
|
|||||||
@@ -189,15 +189,17 @@ def get_arguments(config_base=_CONFIG_BASE):
|
|||||||
"to the next track (if any)",
|
"to the next track (if any)",
|
||||||
action="store_true",
|
action="store_true",
|
||||||
)
|
)
|
||||||
# parser.add_argument(
|
parser.add_argument(
|
||||||
# "--processor",
|
"--processor",
|
||||||
# default=defaults["processor"],
|
default="synchronous",
|
||||||
# choices={"synchronous", "threaded"},
|
choices={"synchronous", "threaded"},
|
||||||
# help='list downloading strategy: - "synchronous" downloads '
|
# help='list downloading strategy: - "synchronous" downloads '
|
||||||
# 'tracks one-by-one. - "threaded" (highly experimental at the '
|
# 'tracks one-by-one. - "threaded" (highly experimental at the '
|
||||||
# 'moment! expect it to slash & burn) pre-fetches the next '
|
# 'moment! expect it to slash & burn) pre-fetches the next '
|
||||||
# 'track\'s metadata for more efficient downloading'
|
# 'track\'s metadata for more efficient downloading'
|
||||||
# )
|
# XXX: Still very experimental to be exposed
|
||||||
|
help=argparse.SUPPRESS,
|
||||||
|
)
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
"-ns",
|
"-ns",
|
||||||
"--no-spaces",
|
"--no-spaces",
|
||||||
|
|||||||
@@ -208,6 +208,17 @@ class Spotdl:
|
|||||||
|
|
||||||
return to_overwrite
|
return to_overwrite
|
||||||
|
|
||||||
|
def generate_temp_filename(self, filename, for_stdout=False):
|
||||||
|
if for_stdout:
|
||||||
|
return filename
|
||||||
|
return "{filename}.temp".format(filename=filename)
|
||||||
|
|
||||||
|
def output_filename_filter(self, allow_spaces):
|
||||||
|
replace_spaces_with_underscores = not allow_spaces
|
||||||
|
if replace_spaces_with_underscores:
|
||||||
|
return lambda s: s.replace(" ", "_")
|
||||||
|
return lambda s: s
|
||||||
|
|
||||||
def download_track_from_metadata(self, metadata):
|
def download_track_from_metadata(self, metadata):
|
||||||
track = Track(metadata, cache_albumart=(not self.arguments["no_metadata"]))
|
track = Track(metadata, cache_albumart=(not self.arguments["no_metadata"]))
|
||||||
stream = metadata["streams"].get(
|
stream = metadata["streams"].get(
|
||||||
@@ -229,10 +240,7 @@ class Spotdl:
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
download_to_stdout = filename == "-"
|
download_to_stdout = filename == "-"
|
||||||
if download_to_stdout:
|
temp_filename = self.generate_temp_filename(filename, for_stdout=download_to_stdout)
|
||||||
temp_filename = filename
|
|
||||||
else:
|
|
||||||
temp_filename = "{filename}.temp".format(filename=filename)
|
|
||||||
|
|
||||||
to_skip_download = self.arguments["dry_run"]
|
to_skip_download = self.arguments["dry_run"]
|
||||||
if os.path.isfile(filename):
|
if os.path.isfile(filename):
|
||||||
@@ -249,6 +257,17 @@ class Spotdl:
|
|||||||
if not self.arguments["no_metadata"]:
|
if not self.arguments["no_metadata"]:
|
||||||
metadata["lyrics"].start()
|
metadata["lyrics"].start()
|
||||||
|
|
||||||
|
filter_space_chars = self.output_filename_filter(not self.arguments["no_spaces"])
|
||||||
|
directory = os.path.dirname(
|
||||||
|
spotdl.metadata.format_string(
|
||||||
|
self.arguments["output_file"],
|
||||||
|
metadata,
|
||||||
|
output_extension=output_extension,
|
||||||
|
sanitizer=filter_space_chars
|
||||||
|
)
|
||||||
|
)
|
||||||
|
os.makedirs(directory or ".", exist_ok=True)
|
||||||
|
|
||||||
logger.info('Downloading to "{filename}"'.format(filename=filename))
|
logger.info('Downloading to "{filename}"'.format(filename=filename))
|
||||||
if self.arguments["no_encode"]:
|
if self.arguments["no_encode"]:
|
||||||
track.download(stream, temp_filename)
|
track.download(stream, temp_filename)
|
||||||
@@ -282,18 +301,33 @@ class Spotdl:
|
|||||||
except TypeError:
|
except TypeError:
|
||||||
logger.warning("Cannot apply metadata on provided output format.")
|
logger.warning("Cannot apply metadata on provided output format.")
|
||||||
|
|
||||||
|
def strip_and_filter_duplicates(self, tracks):
|
||||||
|
filtered_tracks = spotdl.util.remove_duplicates(
|
||||||
|
tracks,
|
||||||
|
condition=lambda x: x,
|
||||||
|
operation=str.strip
|
||||||
|
)
|
||||||
|
return filtered_tracks
|
||||||
|
|
||||||
|
def filter_against_skip_file(self, items, skip_file):
|
||||||
|
skip_items = spotdl.util.readlines_from_nonbinary_file(skip_file)
|
||||||
|
filtered_skip_items = self.strip_and_filter_duplicates(skip_items)
|
||||||
|
filtered_items = [item for item in items if not item in filtered_skip_items]
|
||||||
|
return filtered_items
|
||||||
|
|
||||||
def download_tracks_from_file(self, path):
|
def download_tracks_from_file(self, path):
|
||||||
logger.info(
|
logger.info(
|
||||||
"Checking and removing any duplicate tracks in {}.".format(path)
|
"Checking and removing any duplicate tracks in {}.".format(path)
|
||||||
)
|
)
|
||||||
tracks = spotdl.util.readlines_from_nonbinary_file(path)
|
tracks = spotdl.util.readlines_from_nonbinary_file(path)
|
||||||
# Remove duplicates and empty elements
|
tracks = self.strip_and_filter_duplicates(tracks)
|
||||||
# Also strip whitespaces from elements (if any)
|
|
||||||
tracks = spotdl.util.remove_duplicates(
|
if self.arguments["skip_file"]:
|
||||||
tracks,
|
len_tracks_before = len(tracks)
|
||||||
condition=lambda x: x,
|
tracks = self.filter_against_skip_file(tracks, self.arguments["skip_file"])
|
||||||
operation=str.strip
|
logger.info("Skipping {} tracks due to matches in skip file.".format(
|
||||||
)
|
len_tracks_before - len(tracks))
|
||||||
|
)
|
||||||
# Overwrite file
|
# Overwrite file
|
||||||
spotdl.util.writelines_to_nonbinary_file(path, tracks)
|
spotdl.util.writelines_to_nonbinary_file(path, tracks)
|
||||||
|
|
||||||
@@ -326,9 +360,9 @@ class Spotdl:
|
|||||||
except (NoYouTubeVideoFoundError, NoYouTubeVideoMatchError) as e:
|
except (NoYouTubeVideoFoundError, NoYouTubeVideoMatchError) as e:
|
||||||
logger.error("{err}".format(err=e.args[0]))
|
logger.error("{err}".format(err=e.args[0]))
|
||||||
else:
|
else:
|
||||||
if self.arguments["write_sucessful_file"]:
|
if self.arguments["write_successful_file"]:
|
||||||
with open(self.arguments["write_sucessful_file"], "a") as fout:
|
with open(self.arguments["write_successful_file"], "a") as fout:
|
||||||
fout.write(track)
|
fout.write("{}\n".format(track))
|
||||||
finally:
|
finally:
|
||||||
spotdl.util.writelines_to_nonbinary_file(path, tracks[position:])
|
spotdl.util.writelines_to_nonbinary_file(path, tracks[position:])
|
||||||
print("", file=sys.stderr)
|
print("", file=sys.stderr)
|
||||||
|
|||||||
@@ -45,14 +45,14 @@ class ThreadWithReturnValue(threading.Thread):
|
|||||||
|
|
||||||
def merge(base, overrider):
|
def merge(base, overrider):
|
||||||
""" Override base dict with an overrider dict, recursively. """
|
""" Override base dict with an overrider dict, recursively. """
|
||||||
for key, value in base.items():
|
for key, value in overrider.items():
|
||||||
if isinstance(value, dict):
|
if isinstance(value, dict):
|
||||||
subitem = overrider.setdefault(key, {})
|
subitem = base.setdefault(key, {})
|
||||||
merge(value, subitem)
|
merge(subitem, value)
|
||||||
else:
|
else:
|
||||||
overrider[key] = value
|
base[key] = value
|
||||||
|
|
||||||
return overrider
|
return base
|
||||||
|
|
||||||
|
|
||||||
def prompt_user_for_selection(items):
|
def prompt_user_for_selection(items):
|
||||||
|
|||||||
Reference in New Issue
Block a user