Merge pull request #220 from exislow/187-bug-audio-files-less-than-8-seconds-do-not-download

Fix: Short tracks won't cause an error on download. No infinity downl…
This commit is contained in:
exislow
2024-11-10 12:24:43 +01:00
committed by GitHub
+45 -35
View File
@@ -111,54 +111,64 @@ class Download:
# Send signal to GUI with media name # Send signal to GUI with media name
self.progress_gui.item_name.emit(media_name[:30]) self.progress_gui.item_name.emit(media_name[:30])
try: # Compute total iterations for progress
# Compute total iterations for progress urls_count: int = len(urls)
urls_count: int = len(urls)
if urls_count > 1: if urls_count > 1:
progress_total: int = urls_count progress_total: int = urls_count
block_size: int | None = None block_size: int | None = None
elif urls_count == 1: elif urls_count == 1:
# Compute progress iterations based on the file size. # Will be computed later.
r = requests.get(urls[0], stream=True, timeout=REQUESTS_TIMEOUT_SEC) progress_total: float = None
else:
raise ValueError
r.raise_for_status() # Create progress Task
p_task: TaskID = self.progress.add_task(
f"[blue]Item '{media_name[:30]}'",
total=progress_total,
visible=progress_stdout,
)
# Get file size and compute progress steps # Write content to file until progress is finished.
total_size_in_bytes: int = int(r.headers.get("content-length", 0)) while not self.progress.tasks[p_task].finished:
block_size: int | None = 1048576 with open(path_file, "wb") as f:
progress_total: float = total_size_in_bytes / block_size for url in urls:
else: try:
raise ValueError
# Create progress Task
p_task: TaskID = self.progress.add_task(
f"[blue]Item '{media_name[:30]}'",
total=progress_total,
visible=progress_stdout,
)
# Write content to file until progress is finished.
while not self.progress.tasks[p_task].finished:
with open(path_file, "wb") as f:
for url in urls:
# Create the request object with stream=True, so the content won't be loaded into memory at once. # Create the request object with stream=True, so the content won't be loaded into memory at once.
r = requests.get(url, stream=True, timeout=REQUESTS_TIMEOUT_SEC) r = requests.get(url, stream=True, timeout=REQUESTS_TIMEOUT_SEC)
r.raise_for_status() r.raise_for_status()
# Compute progress iterations based on the file size and update task details.
if not progress_total:
# Get file size and compute progress steps
total_size_in_bytes: int = int(r.headers.get("content-length", 0))
block_size: int | None = 1048576
progress_total: float = total_size_in_bytes / block_size
self.progress.update(p_task, total=progress_total)
# Write the content to disk. If `chunk_size` is set to `None` the whole file will be written at once. # Write the content to disk. If `chunk_size` is set to `None` the whole file will be written at once.
for data in r.iter_content(chunk_size=block_size): for data in r.iter_content(chunk_size=block_size):
f.write(data) f.write(data)
# Advance progress bar. # Advance progress bar.
self.progress.advance(p_task) self.progress.advance(p_task)
except HTTPError as e:
# To send the progress to the GUI, we need to emit the percentage. if url is urls[-1]:
if not progress_stdout: # It happens, if a track is very short (< 8 seconds or so), that the last URL in `urls` is
self.progress_gui.item.emit(self.progress.tasks[p_task].percentage) # invalid (HTTP Error 500) and not necessary. File won't be corrupt.
except HTTPError as e: # Thus, advance progress bar to avoid infinity loops.
# TODO: Handle Exception... self.progress.advance(p_task)
self.fn_logger.error(e) else:
# Finish downloading early and report error.
# TODO: The track should somehow be marked as corrupt.
self.progress.update(p_task, completed=progress_total)
self.fn_logger.error(e)
finally:
# To send the progress to the GUI, we need to emit the percentage.
if not progress_stdout:
self.progress_gui.item.emit(self.progress.tasks[p_task].percentage)
if isinstance(media, Track) and stream_manifest.is_encrypted: if isinstance(media, Track) and stream_manifest.is_encrypted:
key, nonce = decrypt_security_token(stream_manifest.encryption_key) key, nonce = decrypt_security_token(stream_manifest.encryption_key)