From e2740782bba76ece493f32dab8fa854c3a75c29e Mon Sep 17 00:00:00 2001 From: kPherox Date: Fri, 21 Aug 2026 14:15:50 +0900 Subject: [PATCH] feat: support create symlink --- legendary/downloader/mp/manager.py | 4 ++++ legendary/downloader/mp/workers.py | 23 +++++++++++++++++++++++ legendary/models/downloading.py | 1 + 3 files changed, 28 insertions(+) diff --git a/legendary/downloader/mp/manager.py b/legendary/downloader/mp/manager.py index c44fb79..a2b5ec1 100644 --- a/legendary/downloader/mp/manager.py +++ b/legendary/downloader/mp/manager.py @@ -344,6 +344,10 @@ class DLManager(Process): # skip unchanged and empty files if current_file.filename in mc.unchanged: continue + elif current_file.symlink_target: + self.tasks.append(FileTask(current_file.filename, old_file=current_file.symlink_target, + flags=TaskFlags.CREATE_SYMLINK)) + continue elif not current_file.chunk_parts: self.tasks.append(FileTask(current_file.filename, flags=TaskFlags.CREATE_EMPTY_FILE)) continue diff --git a/legendary/downloader/mp/workers.py b/legendary/downloader/mp/workers.py index 1ffb7e4..849b737 100644 --- a/legendary/downloader/mp/workers.py +++ b/legendary/downloader/mp/workers.py @@ -205,6 +205,29 @@ class FileWorker(Process): if j.flags & TaskFlags.CREATE_EMPTY_FILE: # just create an empty file open(full_path, 'a').close() + self.o_q.put(WriterTaskResult(success=True, **j.__dict__)) + continue + if j.flags & TaskFlags.CREATE_SYMLINK: + if current_file: + logger.warning('Trying to create symlink without closing first!') + current_file.close() + current_file = None + + try: + os.symlink(j.old_file, full_path) + except FileExistsError: + try: + os.remove(full_path) + os.symlink(j.old_file, full_path) + except OSError as e: + logger.error(f'Creating symlink failed: {e!r}') + self.o_q.put(WriterTaskResult(success=False, **j.__dict__)) + continue + except OSError as e: + logger.error(f'Creating symlink failed: {e!r}') + self.o_q.put(WriterTaskResult(success=False, **j.__dict__)) + continue + self.o_q.put(WriterTaskResult(success=True, **j.__dict__)) continue elif j.flags & TaskFlags.OPEN_FILE: diff --git a/legendary/models/downloading.py b/legendary/models/downloading.py index 63ac27e..b1fa50c 100644 --- a/legendary/models/downloading.py +++ b/legendary/models/downloading.py @@ -59,6 +59,7 @@ class TaskFlags(Flag): CLOSE_FILE = auto() DELETE_FILE = auto() CREATE_EMPTY_FILE = auto() + CREATE_SYMLINK = auto() RENAME_FILE = auto() RELEASE_MEMORY = auto() MAKE_EXECUTABLE = auto()