[dl:ytdl] improve error detection
- intercept ytdl logging messages and signal error when it emits an error message - remove "ERROR:" etc from ytdl logging messages
This commit is contained in:
@@ -42,6 +42,7 @@ class YoutubeDLDownloader(DownloaderBase):
|
|||||||
|
|
||||||
if ytdl_instance := kwdict.pop("_ytdl_instance", None):
|
if ytdl_instance := kwdict.pop("_ytdl_instance", None):
|
||||||
# 'ytdl' extractor
|
# 'ytdl' extractor
|
||||||
|
self._prepare(ytdl_instance)
|
||||||
info_dict = kwdict.pop("_ytdl_info_dict")
|
info_dict = kwdict.pop("_ytdl_info_dict")
|
||||||
else:
|
else:
|
||||||
# other extractors
|
# other extractors
|
||||||
@@ -69,6 +70,7 @@ class YoutubeDLDownloader(DownloaderBase):
|
|||||||
module, self, self.ytdl_opts)
|
module, self, self.ytdl_opts)
|
||||||
if self.outtmpl == "default":
|
if self.outtmpl == "default":
|
||||||
self.outtmpl = module.DEFAULT_OUTTMPL
|
self.outtmpl = module.DEFAULT_OUTTMPL
|
||||||
|
self._prepare(ytdl_instance)
|
||||||
|
|
||||||
if self.forward_cookies:
|
if self.forward_cookies:
|
||||||
self.log.debug("Forwarding cookies to %s",
|
self.log.debug("Forwarding cookies to %s",
|
||||||
@@ -80,8 +82,10 @@ class YoutubeDLDownloader(DownloaderBase):
|
|||||||
tries = 0
|
tries = 0
|
||||||
url = url[5:]
|
url = url[5:]
|
||||||
manifest = kwdict.get("_ytdl_manifest")
|
manifest = kwdict.get("_ytdl_manifest")
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
tries += 1
|
tries += 1
|
||||||
|
self.error = None
|
||||||
try:
|
try:
|
||||||
if manifest is None:
|
if manifest is None:
|
||||||
info_dict = self._extract_url(
|
info_dict = self._extract_url(
|
||||||
@@ -89,45 +93,63 @@ class YoutubeDLDownloader(DownloaderBase):
|
|||||||
else:
|
else:
|
||||||
info_dict = self._extract_manifest(
|
info_dict = self._extract_manifest(
|
||||||
ytdl_instance, url, kwdict)
|
ytdl_instance, url, kwdict)
|
||||||
if info_dict:
|
|
||||||
break
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
self.log.traceback(exc)
|
self.log.traceback(exc)
|
||||||
self.log.error("%s: %s (%s/%s)",
|
cls = exc.__class__
|
||||||
exc.__class__.__name__, exc,
|
if cls.__module__ == "builtins":
|
||||||
tries, self.retries+1)
|
tries = False
|
||||||
|
msg = f"{cls.__name__}: {exc}"
|
||||||
else:
|
else:
|
||||||
self.log.error("Empty 'info_dict' data (%s/%s)",
|
if self.error is not None:
|
||||||
tries, self.retries+1)
|
msg = self.error
|
||||||
|
elif not info_dict:
|
||||||
|
msg = "Empty 'info_dict' data"
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
if tries:
|
||||||
|
self.log.error("%s (%s/%s)", msg, tries, self.retries+1)
|
||||||
|
else:
|
||||||
|
self.log.error(msg)
|
||||||
|
return False
|
||||||
if tries > self.retries:
|
if tries > self.retries:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
if "__gdl_initialize" in ytdl_instance.params:
|
|
||||||
del ytdl_instance.params["__gdl_initialize"]
|
|
||||||
|
|
||||||
if self.progress is not None:
|
|
||||||
ytdl_instance.add_progress_hook(self._progress_hook)
|
|
||||||
if rlf := ytdl_instance.params.pop("__gdl_ratelimit_func", False):
|
|
||||||
self.rate_dyn = rlf
|
|
||||||
|
|
||||||
if extra := kwdict.get("_ytdl_extra"):
|
if extra := kwdict.get("_ytdl_extra"):
|
||||||
info_dict.update(extra)
|
info_dict.update(extra)
|
||||||
|
|
||||||
while True:
|
while True:
|
||||||
|
tries += 1
|
||||||
|
self.error = None
|
||||||
try:
|
try:
|
||||||
if "entries" in info_dict:
|
if "entries" in info_dict:
|
||||||
return self._download_playlist(
|
success = self._download_playlist(
|
||||||
|
ytdl_instance, pathfmt, info_dict)
|
||||||
|
else:
|
||||||
|
success = self._download_video(
|
||||||
ytdl_instance, pathfmt, info_dict)
|
ytdl_instance, pathfmt, info_dict)
|
||||||
return self._download_video(
|
|
||||||
ytdl_instance, pathfmt, info_dict)
|
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
tries += 1
|
|
||||||
self.log.traceback(exc)
|
self.log.traceback(exc)
|
||||||
self.log.error("%s: %s (%s/%s)",
|
cls = exc.__class__
|
||||||
exc.__class__.__name__, exc,
|
if cls.__module__ == "builtins":
|
||||||
tries, self.retries+1)
|
tries = False
|
||||||
if tries > self.retries:
|
msg = f"{cls.__name__}: {exc}"
|
||||||
return False
|
else:
|
||||||
|
if self.error is not None:
|
||||||
|
msg = self.error
|
||||||
|
elif not success:
|
||||||
|
msg = "Error"
|
||||||
|
else:
|
||||||
|
break
|
||||||
|
|
||||||
|
if tries:
|
||||||
|
self.log.error("%s (%s/%s)", msg, tries, self.retries+1)
|
||||||
|
else:
|
||||||
|
self.log.error(msg)
|
||||||
|
return False
|
||||||
|
if tries > self.retries:
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
def _extract_url(self, ytdl, url):
|
def _extract_url(self, ytdl, url):
|
||||||
return ytdl.extract_info(url, download=False)
|
return ytdl.extract_info(url, download=False)
|
||||||
@@ -281,6 +303,17 @@ class YoutubeDLDownloader(DownloaderBase):
|
|||||||
self.log.error("%s: %s", exc.__class__.__name__, exc)
|
self.log.error("%s: %s", exc.__class__.__name__, exc)
|
||||||
return status
|
return status
|
||||||
|
|
||||||
|
def _prepare(self, ytdl_instance):
|
||||||
|
if "__gdl_initialize" not in ytdl_instance.params:
|
||||||
|
return
|
||||||
|
|
||||||
|
del ytdl_instance.params["__gdl_initialize"]
|
||||||
|
if self.progress is not None:
|
||||||
|
ytdl_instance.add_progress_hook(self._progress_hook)
|
||||||
|
if rlf := ytdl_instance.params.pop("__gdl_ratelimit_func", False):
|
||||||
|
self.rate_dyn = rlf
|
||||||
|
ytdl_instance.params["logger"] = LoggerAdapter(self, ytdl_instance)
|
||||||
|
|
||||||
def _progress_hook(self, info):
|
def _progress_hook(self, info):
|
||||||
if info["status"] == "downloading" and \
|
if info["status"] == "downloading" and \
|
||||||
info["elapsed"] >= self.progress:
|
info["elapsed"] >= self.progress:
|
||||||
@@ -304,6 +337,31 @@ class YoutubeDLDownloader(DownloaderBase):
|
|||||||
ytdl_instance.params["outtmpl"] = {"default": outtmpl}
|
ytdl_instance.params["outtmpl"] = {"default": outtmpl}
|
||||||
|
|
||||||
|
|
||||||
|
class LoggerAdapter():
|
||||||
|
__slots__ = ("obj", "log")
|
||||||
|
|
||||||
|
def __init__(self, obj, ytdl_instance):
|
||||||
|
self.obj = obj
|
||||||
|
self.log = ytdl_instance.params.get("logger")
|
||||||
|
|
||||||
|
def debug(self, msg):
|
||||||
|
if self.log is not None:
|
||||||
|
if msg[0] == "[":
|
||||||
|
msg = msg[msg.find("]")+2:]
|
||||||
|
self.log.debug(msg)
|
||||||
|
|
||||||
|
def warning(self, msg):
|
||||||
|
if self.log is not None:
|
||||||
|
if "WARNING:" in msg:
|
||||||
|
msg = msg[msg.find(" ")+1:]
|
||||||
|
self.log.warning(msg)
|
||||||
|
|
||||||
|
def error(self, msg):
|
||||||
|
if "ERROR:" in msg:
|
||||||
|
msg = msg[msg.find(" ")+1:]
|
||||||
|
self.obj.error = msg
|
||||||
|
|
||||||
|
|
||||||
def compatible_formats(formats):
|
def compatible_formats(formats):
|
||||||
"""Returns True if 'formats' are compatible for merge"""
|
"""Returns True if 'formats' are compatible for merge"""
|
||||||
video_ext = formats[0].get("ext")
|
video_ext = formats[0].get("ext")
|
||||||
|
|||||||
Reference in New Issue
Block a user