2 Commits

Author SHA1 Message Date
Alex Shnitman
3bf7fb51f4 fix filepath regression 2026-02-14 08:58:01 +02:00
Alex Shnitman
8ae06c65d0 Refactor download status handling to ensure correct file path processing and task synchronization (closes #872) 2026-02-13 16:29:57 +02:00

View File

@@ -144,10 +144,21 @@ class Download:
def put_status_postprocessor(d): def put_status_postprocessor(d):
if d['postprocessor'] == 'MoveFiles' and d['status'] == 'finished': if d['postprocessor'] == 'MoveFiles' and d['status'] == 'finished':
filepath = d['info_dict']['filepath']
if '__finaldir' in d['info_dict']: if '__finaldir' in d['info_dict']:
filename = os.path.join(d['info_dict']['__finaldir'], os.path.basename(d['info_dict']['filepath'])) finaldir = d['info_dict']['__finaldir']
# Compute relative path from temp dir to preserve
# subdirectory structure from the output template.
try:
rel_path = os.path.relpath(filepath, self.temp_dir)
except ValueError:
rel_path = os.path.basename(filepath)
if rel_path.startswith('..'):
# filepath is not under temp_dir, fall back to basename
rel_path = os.path.basename(filepath)
filename = os.path.join(finaldir, rel_path)
else: else:
filename = d['info_dict']['filepath'] filename = filepath
self.status_queue.put({'status': 'finished', 'filename': filename}) self.status_queue.put({'status': 'finished', 'filename': filename})
# Capture all chapter files when SplitChapters finishes # Capture all chapter files when SplitChapters finishes
@@ -203,8 +214,14 @@ class Download:
self.notifier = notifier self.notifier = notifier
self.info.status = 'preparing' self.info.status = 'preparing'
await self.notifier.updated(self.info) await self.notifier.updated(self.info)
asyncio.create_task(self.update_status()) self.status_task = asyncio.create_task(self.update_status())
return await self.loop.run_in_executor(None, self.proc.join) await self.loop.run_in_executor(None, self.proc.join)
# Signal update_status to stop and wait for it to finish
# so that all status updates (including MoveFiles with correct
# file size) are processed before _post_download_cleanup runs.
if self.status_queue is not None:
self.status_queue.put(None)
await self.status_task
def cancel(self): def cancel(self):
log.info(f"Cancelling download: {self.info.title}") log.info(f"Cancelling download: {self.info.title}")
@@ -221,8 +238,6 @@ class Download:
log.info(f"Closing download process for: {self.info.title}") log.info(f"Closing download process for: {self.info.title}")
if self.started(): if self.started():
self.proc.close() self.proc.close()
if self.status_queue is not None:
self.status_queue.put(None)
def running(self): def running(self):
try: try: