Merge pull request #183 from gp-slick-coder/master

Misc fixes
This commit is contained in:
Vitiko 2022-12-13 21:39:05 -04:00 committed by GitHub
commit be37d82e70
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 49 additions and 160 deletions

150
.gitignore vendored
View File

@ -1,150 +1,2 @@
Qobuz Downloads Qobuz Downloads
*__pycache* __pycache__
.env
__pycache__/
*.py[cod]
*$py.class
.bumpversion.cfg
/*.py
!/setup.py
# C extensions
*.so
*.json
*.txt
*.db
*.sh
*.txt
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py,cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# PEP 582; used by e.g. github.com/David-OConnor/pyflow
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/

27
.vscode/launch.json vendored Normal file
View File

@ -0,0 +1,27 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Python: Module",
"type": "python",
"request": "launch",
"module": "qobuz_dl.cli",
"justMyCode": true,
"args": [
"dl",
"dl.txt",
"--embed-art",
"-q",
"27",
"--no-db",
"--og-cover"
],
"env": {
"PYTHONDONTWRITEBYTECODE": "1"
}
}
]
}

1
dl.txt Normal file
View File

@ -0,0 +1 @@
https://open.qobuz.com/track/652159

View File

@ -138,7 +138,8 @@ class Download:
if "sample" not in parse and parse["sampling_rate"]: if "sample" not in parse and parse["sampling_rate"]:
meta = self.client.get_track_meta(self.item_id) meta = self.client.get_track_meta(self.item_id)
track_title = _get_title(meta) track_title = _get_title(meta)
logger.info(f"\n{YELLOW}Downloading: {track_title}") artist = _safe_get(meta, "performer", "name")
logger.info(f"\n{YELLOW}Downloading: {artist} - {track_title}")
format_info = self._get_format(meta, is_track_id=True, track_url_dict=parse) format_info = self._get_format(meta, 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
@ -176,7 +177,7 @@ class Download:
meta, meta,
True, True,
is_mp3, is_mp3,
self.embed_art, False,
) )
else: else:
logger.info(f"{OFF}Demo. Skipping") logger.info(f"{OFF}Demo. Skipping")
@ -221,8 +222,7 @@ class Download:
logger.info(f"{OFF}{track_title} was already downloaded") logger.info(f"{OFF}{track_title} was already downloaded")
return return
desc = _get_description(track_url_dict, track_title, multiple) tqdm_download(url, filename, filename)
tqdm_download(url, filename, desc)
tag_function = metadata.tag_mp3 if is_mp3 else metadata.tag_flac tag_function = metadata.tag_mp3 if is_mp3 else metadata.tag_flac
try: try:
tag_function( tag_function(
@ -305,20 +305,26 @@ class Download:
return ("Unknown", quality_met, None, None) return ("Unknown", quality_met, None, None)
def tqdm_download(url, fname, track_name): def tqdm_download(url, fname, desc):
r = requests.get(url, allow_redirects=True, stream=True) r = requests.get(url, allow_redirects=True, stream=True)
total = int(r.headers.get("content-length", 0)) total = int(r.headers.get("content-length", 0))
download_size = 0
with open(fname, "wb") as file, tqdm( with open(fname, "wb") as file, tqdm(
total=total, total=total,
unit="iB", unit="iB",
unit_scale=True, unit_scale=True,
unit_divisor=1024, unit_divisor=1024,
desc=track_name, desc=desc,
bar_format=CYAN + "{n_fmt}/{total_fmt} /// {desc}", bar_format=CYAN + "{n_fmt}/{total_fmt} /// {desc}",
) as bar: ) as bar:
for data in r.iter_content(chunk_size=1024): for data in r.iter_content(chunk_size=1024):
size = file.write(data) size = file.write(data)
bar.update(size) bar.update(size)
download_size += size
if total != download_size:
# https://stackoverflow.com/questions/69919912/requests-iter-content-thinks-file-is-complete-but-its-not
raise ConnectionError("File download was interrupted for " + fname)
def _get_description(item: dict, track_title, multiple=None): def _get_description(item: dict, track_title, multiple=None):

View File

@ -45,8 +45,9 @@ def _get_title(track_dict):
def _format_copyright(s: str) -> str: def _format_copyright(s: str) -> str:
s = s.replace("(P)", PHON_COPYRIGHT) if s:
s = s.replace("(C)", COPYRIGHT) s = s.replace("(P)", PHON_COPYRIGHT)
s = s.replace("(C)", COPYRIGHT)
return s return s
@ -107,7 +108,9 @@ def _embed_id3_img(root_dir, audio: id3.ID3):
# Use KeyError catching instead of dict.get to avoid empty tags # Use KeyError catching instead of dict.get to avoid empty tags
def tag_flac(filename, root_dir, final_name, d, album, istrack=True, em_image=False): def tag_flac(
filename, root_dir, final_name, d: dict, album, istrack=True, em_image=False
):
""" """
Tag a FLAC file Tag a FLAC file
@ -147,14 +150,14 @@ def tag_flac(filename, root_dir, final_name, d, album, istrack=True, em_image=Fa
audio["TRACKTOTAL"] = str(d["album"]["tracks_count"]) audio["TRACKTOTAL"] = str(d["album"]["tracks_count"])
audio["ALBUM"] = d["album"]["title"] audio["ALBUM"] = d["album"]["title"]
audio["DATE"] = d["album"]["release_date_original"] audio["DATE"] = d["album"]["release_date_original"]
audio["COPYRIGHT"] = _format_copyright(d.get("copyright", "n/a")) audio["COPYRIGHT"] = _format_copyright(d.get("copyright") or "n/a")
else: else:
audio["GENRE"] = _format_genres(album["genres_list"]) audio["GENRE"] = _format_genres(album["genres_list"])
audio["ALBUMARTIST"] = album["artist"]["name"] audio["ALBUMARTIST"] = album["artist"]["name"]
audio["TRACKTOTAL"] = str(album["tracks_count"]) audio["TRACKTOTAL"] = str(album["tracks_count"])
audio["ALBUM"] = album["title"] audio["ALBUM"] = album["title"]
audio["DATE"] = album["release_date_original"] audio["DATE"] = album["release_date_original"]
audio["COPYRIGHT"] = _format_copyright(album.get("copyright", "n/a")) audio["COPYRIGHT"] = _format_copyright(album.get("copyright") or "n/a")
if em_image: if em_image:
_embed_flac_img(root_dir, audio) _embed_flac_img(root_dir, audio)