mirror of
https://github.com/Wojtek242/qobuz-dl.git
synced 2024-11-22 02:55:25 +01:00
clean format function improved, config updates
This commit is contained in:
parent
0d02292823
commit
3affd97916
@ -101,8 +101,20 @@ def main():
|
|||||||
no_cover = config.getboolean("DEFAULT", "no_cover")
|
no_cover = config.getboolean("DEFAULT", "no_cover")
|
||||||
no_database = config.getboolean("DEFAULT", "no_database")
|
no_database = config.getboolean("DEFAULT", "no_database")
|
||||||
app_id = config["DEFAULT"]["app_id"]
|
app_id = config["DEFAULT"]["app_id"]
|
||||||
|
|
||||||
|
if ("folder_format" not in config["DEFAULT"]
|
||||||
|
or "track_format" not in config["DEFAULT"]):
|
||||||
|
logging.info(f'{YELLOW}Config file does not include format string,'
|
||||||
|
' updating...')
|
||||||
|
config["DEFAULT"]["folder_format"] = "{artist} - {album} ({year}) "
|
||||||
|
"[{bit_depth}B-{sampling_rate}kHz]"
|
||||||
|
config["DEFAULT"]["track_format"] = "{tracknumber}. {tracktitle}"
|
||||||
|
with open(CONFIG_FILE, 'w') as cf:
|
||||||
|
config.write(cf)
|
||||||
|
|
||||||
folder_format = config["DEFAULT"]["folder_format"]
|
folder_format = config["DEFAULT"]["folder_format"]
|
||||||
track_format = config["DEFAULT"]["track_format"]
|
track_format = config["DEFAULT"]["track_format"]
|
||||||
|
|
||||||
secrets = [
|
secrets = [
|
||||||
secret for secret in config["DEFAULT"]["secrets"].split(",") if secret
|
secret for secret in config["DEFAULT"]["secrets"].split(",") if secret
|
||||||
]
|
]
|
||||||
@ -137,9 +149,9 @@ def main():
|
|||||||
no_cover=arguments.no_cover or no_cover,
|
no_cover=arguments.no_cover or no_cover,
|
||||||
downloads_db=None if no_database or arguments.no_db else QOBUZ_DB,
|
downloads_db=None if no_database or arguments.no_db else QOBUZ_DB,
|
||||||
folder_format=arguments.folder_format
|
folder_format=arguments.folder_format
|
||||||
if hasattr(arguments, "folder_format") else folder_format,
|
if arguments.folder_format is not None else folder_format,
|
||||||
track_format=arguments.track_format
|
track_format=arguments.track_format
|
||||||
if hasattr(arguments, "track_format") else track_format,
|
if arguments.track_format is not None else track_format,
|
||||||
)
|
)
|
||||||
qobuz.initialize_client(email, password, app_id, secrets)
|
qobuz.initialize_client(email, password, app_id, secrets)
|
||||||
|
|
||||||
|
@ -108,7 +108,7 @@ def add_common_arg(custom_parser, default_folder, default_quality):
|
|||||||
metavar='PATTERN',
|
metavar='PATTERN',
|
||||||
help='pattern for formatting folder names, e.g '
|
help='pattern for formatting folder names, e.g '
|
||||||
'"{artist} - {album} ({year})". available keys: artist, '
|
'"{artist} - {album} ({year})". available keys: artist, '
|
||||||
'album, year, sampling_rate, bit_rate, tracktitle. '
|
'albumartist, album, year, sampling_rate, bit_rate, tracktitle. '
|
||||||
'cannot contain characters used by the system, which includes /:<>',
|
'cannot contain characters used by the system, which includes /:<>',
|
||||||
)
|
)
|
||||||
custom_parser.add_argument(
|
custom_parser.add_argument(
|
||||||
|
@ -11,10 +11,17 @@ from qobuz_dl.color import OFF, GREEN, RED, YELLOW, CYAN
|
|||||||
from qobuz_dl.exceptions import NonStreamable
|
from qobuz_dl.exceptions import NonStreamable
|
||||||
|
|
||||||
QL_DOWNGRADE = "FormatRestrictedByFormatAvailability"
|
QL_DOWNGRADE = "FormatRestrictedByFormatAvailability"
|
||||||
DEFAULT_MP3_FOLDER_FORMAT = '{artist} - {album} [MP3]'
|
# used in case of error
|
||||||
DEFAULT_MP3_TRACK_FORMAT = '{tracknumber}. {tracktitle}'
|
DEFAULT_FORMATS = {
|
||||||
DEFAULT_UNKNOWN_FOLDER_FORMAT = '{artist} - {album}'
|
'MP3': [
|
||||||
DEFAULT_UNKNOWN_TRACK_FORMAT = '{tracknumber}. {tracktitle}'
|
'{artist} - {album} ({year}) [MP3]',
|
||||||
|
'{tracknumber}. {tracktitle}',
|
||||||
|
],
|
||||||
|
'Unknown': [
|
||||||
|
'{artist} - {album}',
|
||||||
|
'{tracknumber}. {tracktitle}',
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -145,15 +152,16 @@ def download_and_tag(
|
|||||||
filename = os.path.join(root_dir, f".{tmp_count:02}.tmp")
|
filename = os.path.join(root_dir, f".{tmp_count:02}.tmp")
|
||||||
|
|
||||||
# Determine the filename
|
# Determine the filename
|
||||||
track_title = track_metadata["title"]
|
track_title = track_metadata.get("title")
|
||||||
print(track_metadata)
|
artist = _safe_get(track_metadata, "performer", "name")
|
||||||
filename_attr = {
|
filename_attr = {
|
||||||
'artist': track_metadata["performer"]["name"],
|
'artist': artist,
|
||||||
'albumartist': track_metadata["album"]["artist"]["name"],
|
'albumartist': _safe_get(track_metadata, "album", "artist", "name",
|
||||||
|
default=artist),
|
||||||
'bit_depth': track_metadata['maximum_bit_depth'],
|
'bit_depth': track_metadata['maximum_bit_depth'],
|
||||||
'sampling_rate': track_metadata['maximum_sampling_rate'],
|
'sampling_rate': track_metadata['maximum_sampling_rate'],
|
||||||
'tracktitle': track_title,
|
'tracktitle': track_title,
|
||||||
'version': track_metadata["version"],
|
'version': track_metadata.get("version"),
|
||||||
'tracknumber': f"{track_metadata['track_number']:02}"
|
'tracknumber': f"{track_metadata['track_number']:02}"
|
||||||
}
|
}
|
||||||
# track_format is a format string
|
# track_format is a format string
|
||||||
@ -250,9 +258,9 @@ def download_id_by_type(
|
|||||||
'bit_depth': bit_depth,
|
'bit_depth': bit_depth,
|
||||||
'sampling_rate': sampling_rate
|
'sampling_rate': sampling_rate
|
||||||
}
|
}
|
||||||
folder_format, track_format = clean_format_str(folder_format,
|
folder_format, track_format = _clean_format_str(folder_format,
|
||||||
track_format,
|
track_format,
|
||||||
file_format)
|
file_format)
|
||||||
sanitized_title = sanitize_filename(
|
sanitized_title = sanitize_filename(
|
||||||
folder_format.format(**album_attr)
|
folder_format.format(**album_attr)
|
||||||
)
|
)
|
||||||
@ -303,9 +311,9 @@ def download_id_by_type(
|
|||||||
is_track_id=True, track_url_dict=parse)
|
is_track_id=True, track_url_dict=parse)
|
||||||
file_format, quality_met, bit_depth, sampling_rate = format_info
|
file_format, quality_met, bit_depth, sampling_rate = format_info
|
||||||
|
|
||||||
folder_format, track_format = clean_format_str(folder_format,
|
folder_format, track_format = _clean_format_str(folder_format,
|
||||||
track_format,
|
track_format,
|
||||||
bit_depth)
|
bit_depth)
|
||||||
|
|
||||||
if not downgrade_quality and not quality_met:
|
if not downgrade_quality and not quality_met:
|
||||||
logger.info(
|
logger.info(
|
||||||
@ -342,45 +350,46 @@ def download_id_by_type(
|
|||||||
|
|
||||||
|
|
||||||
# ----------- Utilities -----------
|
# ----------- Utilities -----------
|
||||||
def _clean_format_gen(s: str) -> str:
|
|
||||||
'''General clean for format strings. Avoids user errors.
|
|
||||||
'''
|
|
||||||
if s.endswith('.mp3'):
|
|
||||||
s = s[:-4]
|
|
||||||
elif s.endswith('.flac'):
|
|
||||||
s = s[:-5]
|
|
||||||
s = s.strip()
|
|
||||||
return s
|
|
||||||
|
|
||||||
|
def _clean_format_str(folder: str, track: str,
|
||||||
def _not_mp3_valid(s: str) -> bool:
|
file_format: str) -> Tuple[str, str]:
|
||||||
return 'bit_depth' in s or 'sample_rate' in s
|
'''Cleans up the format strings, avoids errors
|
||||||
|
|
||||||
|
|
||||||
def clean_format_str(folder: str, track: str,
|
|
||||||
file_format: str) -> Tuple[str, str]:
|
|
||||||
'''Cleans up the format strings to avoid errors
|
|
||||||
with MP3 files.
|
with MP3 files.
|
||||||
'''
|
'''
|
||||||
folder = _clean_format_gen(folder)
|
final = []
|
||||||
track = _clean_format_gen(track)
|
for i, fs in enumerate((folder, track)):
|
||||||
if file_format == 'MP3':
|
if fs.endswith('.mp3'):
|
||||||
if _not_mp3_valid(folder):
|
fs = fs[:-4]
|
||||||
logger.error(f'{RED}invalid format string for MP3: "{folder}"'
|
elif fs.endswith('.flac'):
|
||||||
f'\ndefaulting to "{DEFAULT_MP3_FOLDER_FORMAT}"')
|
fs = fs[:-5]
|
||||||
folder = DEFAULT_MP3_FOLDER_FORMAT
|
fs = fs.strip()
|
||||||
if _not_mp3_valid(track):
|
|
||||||
logger.error(f'{RED}invalid format string for MP3: "{track}"'
|
|
||||||
f'\ndefaulting to "{DEFAULT_MP3_TRACK_FORMAT}"')
|
|
||||||
track = DEFAULT_MP3_TRACK_FORMAT
|
|
||||||
elif file_format == 'Unknown':
|
|
||||||
if _not_mp3_valid(folder):
|
|
||||||
logger.error(f'{RED}Error getting format. Defaulting format '
|
|
||||||
f'string to "{DEFAULT_UNKNOWN_FOLDER_FORMAT}"')
|
|
||||||
folder = DEFAULT_UNKNOWN_FOLDER_FORMAT
|
|
||||||
if _not_mp3_valid(track):
|
|
||||||
logger.error(f'{RED}Error getting format. Defaulting format '
|
|
||||||
f'string to "{DEFAULT_UNKNOWN_TRACK_FORMAT}"')
|
|
||||||
track = DEFAULT_UNKNOWN_TRACK_FORMAT
|
|
||||||
|
|
||||||
return (folder, track)
|
# default to pre-chosen string if format is invalid
|
||||||
|
if (file_format in ('MP3', 'Unknown') and
|
||||||
|
'bit_depth' in file_format or 'sampling_rate' in file_format):
|
||||||
|
default = DEFAULT_FORMATS[file_format][i]
|
||||||
|
logger.error(f'{RED}invalid format string for format {file_format}'
|
||||||
|
f'. defaulting to {default}')
|
||||||
|
fs = default
|
||||||
|
final.append(fs)
|
||||||
|
|
||||||
|
return tuple(final)
|
||||||
|
|
||||||
|
|
||||||
|
def _safe_get(d: dict, *keys, default=None):
|
||||||
|
'''A replacement for chained `get()` statements on dicts:
|
||||||
|
>>> d = {'foo': {'bar': 'baz'}}
|
||||||
|
>>> _safe_get(d, 'baz')
|
||||||
|
None
|
||||||
|
>>> _safe_get(d, 'foo', 'bar')
|
||||||
|
'baz'
|
||||||
|
'''
|
||||||
|
curr = d
|
||||||
|
res = default
|
||||||
|
for key in keys:
|
||||||
|
res = curr.get(key, default)
|
||||||
|
if res == default or not hasattr(res, '__getitem__'):
|
||||||
|
return res
|
||||||
|
else:
|
||||||
|
curr = res
|
||||||
|
return res
|
||||||
|
Loading…
Reference in New Issue
Block a user