From d9340bf17a828b335b6a77b6be0b555c32628196 Mon Sep 17 00:00:00 2001 From: alper-han <89567766+alper-han@users.noreply.github.com> Date: Sun, 6 Jul 2025 04:03:59 +0300 Subject: [PATCH] Fix Linux path issues for cross-platform support --- backend/config.py | 15 +++++- backend/main.py | 29 +++++++++-- backend/subfinder/linux/VideoSubFinderCli.run | 1 - backend/tools/process_manager.py | 21 ++++++-- backend/tools/reformat.py | 47 +++++++++++++++--- design/vse.png | Bin 0 -> 30230 bytes gui.py | 6 ++- ui/icon/my_fluent_icon.py | 3 +- 8 files changed, 100 insertions(+), 22 deletions(-) create mode 100644 design/vse.png diff --git a/backend/config.py b/backend/config.py index 904d6ba8..fd289e7d 100644 --- a/backend/config.py +++ b/backend/config.py @@ -1,5 +1,6 @@ import os +import platform from pathlib import Path from qfluentwidgets import (qconfig, ConfigItem, QConfig, OptionsValidator, BoolValidator, OptionsConfigItem, EnumSerializer, RangeValidator, RangeConfigItem, ConfigValidator) @@ -97,7 +98,19 @@ class Config(QConfig): # VideoSubFinder 视频解码组件 videoSubFinderDecoder = OptionsConfigItem("Main", "VideoSubFinderDecoder", VideoSubFinderDecoder.OPENCV, OptionsValidator(VideoSubFinderDecoder), EnumSerializer(VideoSubFinderDecoder)) -CONFIG_FILE = 'config/config.json' +def get_config_file(): + system = platform.system() + + if system == 'Windows': + return os.path.join('config', 'config.json') + + else: + config_dir = Path.home() / '.config' / 'video-subtitle-extractor' + + config_dir.mkdir(parents=True, exist_ok=True) + return str(config_dir / 'config.json') + +CONFIG_FILE = get_config_file() config = Config() qconfig.load(CONFIG_FILE, config) diff --git a/backend/main.py b/backend/main.py index db9989fc..bdd2fb43 100644 --- a/backend/main.py +++ b/backend/main.py @@ -61,7 +61,10 @@ def __init__(self, vd_path): # 通过视频路径获取视频名称 self.vd_name = Path(self.video_path).stem # 临时存储文件夹 - self.temp_output_dir = os.path.join(os.path.dirname(BASE_DIR), 'output', str(self.vd_name)) + if platform.system() == 'Windows': + self.temp_output_dir = os.path.join(os.path.dirname(BASE_DIR), 'output', str(self.vd_name)) + else: + self.temp_output_dir = os.path.join(os.path.expanduser('~'), '.cache', 'video-subtitle-extractor', str(self.vd_name)) # 视频帧总数 self.frame_count = self.video_cap.get(cv2.CAP_PROP_FRAME_COUNT) # 视频帧率 @@ -452,8 +455,26 @@ def vsf_output(out, ): if platform.system() == 'Windows': path_vsf = os.path.join(BASE_DIR, 'subfinder', 'windows', 'VideoSubFinderWXW.exe') else: - path_vsf = os.path.join(BASE_DIR, 'subfinder', 'linux', 'VideoSubFinderCli.run') - os.chmod(path_vsf, 0o775) + # Create a writable copy of subfinder in cache directory + import shutil + cache_subfinder_dir = os.path.join(os.path.expanduser('~'), '.cache', 'video-subtitle-extractor', 'subfinder', 'linux') + original_subfinder_dir = os.path.join(BASE_DIR, 'subfinder', 'linux') + + # To ensure it's a clean copy with correct permissions, remove old one. + if os.path.exists(cache_subfinder_dir): + shutil.rmtree(cache_subfinder_dir) + + shutil.copytree(original_subfinder_dir, cache_subfinder_dir) + + # Make copied directory and all its contents writable by user + os.chmod(cache_subfinder_dir, 0o775) + for root, dirs, files in os.walk(cache_subfinder_dir): + for name in dirs: + os.chmod(os.path.join(root, name), 0o775) + for name in files: + os.chmod(os.path.join(root, name), 0o775) + + path_vsf = os.path.join(cache_subfinder_dir, 'VideoSubFinderCli.run') # :图像上半部分所占百分比,取值【0-1】 top_end = 1 - self.sub_area.ymin / self.frame_height # bottom_end:图像下半部分所占百分比,取值【0-1】 @@ -496,7 +517,7 @@ def vsf_output(out, ): self.vsf_running = True try: p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=1, - close_fds='posix' in sys.builtin_module_names, shell=True, creationflags=subprocess.CREATE_NEW_PROCESS_GROUP) + close_fds='posix' in sys.builtin_module_names, shell=True) Thread(target=vsf_output, daemon=True, args=(p.stderr,)).start() ProcessManager.instance().add_process(p) self.manage_process(p.pid) diff --git a/backend/subfinder/linux/VideoSubFinderCli.run b/backend/subfinder/linux/VideoSubFinderCli.run index 9f2ad6a5..f52ad90e 100755 --- a/backend/subfinder/linux/VideoSubFinderCli.run +++ b/backend/subfinder/linux/VideoSubFinderCli.run @@ -1,5 +1,4 @@ #!/bin/sh cd ${0%/*} export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PWD:/lib64 -chmod +x ./VideoSubFinderCli ./VideoSubFinderCli "$@" diff --git a/backend/tools/process_manager.py b/backend/tools/process_manager.py index 7d4642ce..26624c06 100644 --- a/backend/tools/process_manager.py +++ b/backend/tools/process_manager.py @@ -120,9 +120,20 @@ def terminate_by_pid(self, pid): subprocess.run(['taskkill', '/F', '/T', '/PID', str(pid)], stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=3) else: - subprocess.run(['pkill', '-9', '-P', str(pid)], - stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=2) - subprocess.run(['kill', '-9', str(pid)], - stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=3) + # NixOS requires absolute paths for commands in subprocess + pkill_path = '/run/current-system/sw/bin/pkill' + kill_path = '/run/current-system/sw/bin/kill' + if os.path.exists(pkill_path): + subprocess.run([pkill_path, '-9', '-P', str(pid)], + stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=2) + if os.path.exists(kill_path): + subprocess.run([kill_path, '-9', str(pid)], + stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=3) + else: + # Fallback for linux + subprocess.run(['pkill', '-9', '-P', str(pid)], + stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=2) + subprocess.run(['kill', '-9', str(pid)], + stdout=subprocess.PIPE, stderr=subprocess.PIPE, timeout=3) except Exception as e: - print(f"Error forcibly terminating process with PID {pid}: {str(e)}") \ No newline at end of file + print(f"Error forcibly terminating process with PID {pid}: {str(e)}") diff --git a/backend/tools/reformat.py b/backend/tools/reformat.py index b4fb89d0..0c4dca4e 100644 --- a/backend/tools/reformat.py +++ b/backend/tools/reformat.py @@ -12,6 +12,8 @@ import pysrt import wordsegment as ws import re +import shutil +import platform def execute(path, lang='en'): try: @@ -43,14 +45,43 @@ def execute(path, lang='en'): "needn't", "oughtn't", "shan't", "shouldn't", "usedn't", "won't", "wouldn't", "that's", "what's", "it'll"] verb_form_map = {} - typo_map_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'configs', 'typoMap.json') - try: - with open(typo_map_path, 'r', encoding='utf-8') as load_f: - typo_map = json.load(load_f) - except Exception as e: - print(f"Error: Failed to load typoMap.json: {str(e)}") - print(traceback.format_exc()) - typo_map = {} + if platform.system() == 'Windows': + typo_map_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'configs', 'typoMap.json') + try: + with open(typo_map_path, 'r', encoding='utf-8') as load_f: + typo_map = json.load(load_f) + except Exception as e: + print(f"Error: Failed to load typoMap.json: {str(e)}") + print(traceback.format_exc()) + typo_map = {} + else: + config_dir = os.path.join(os.path.expanduser('~'), '.config', 'video-subtitle-extractor') + user_typo_map_path = os.path.join(config_dir, 'typoMap.json') + default_typo_map_path = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'configs', 'typoMap.json') + + if os.path.exists(user_typo_map_path): + typo_map_path = user_typo_map_path + elif os.path.exists(default_typo_map_path): + os.makedirs(config_dir, exist_ok=True) + import shutil + shutil.copy2(default_typo_map_path, user_typo_map_path) + os.chmod(user_typo_map_path, 0o664) # Make the file writable for the user + typo_map_path = user_typo_map_path + print(f"Created user typoMap.json at: {user_typo_map_path}") + else: + typo_map_path = None + + if typo_map_path: + try: + with open(typo_map_path, 'r', encoding='utf-8') as load_f: + typo_map = json.load(load_f) + print(f"Loaded typoMap.json from: {typo_map_path}") + except Exception as e: + print(f"Error: Failed to load typoMap.json: {str(e)}") + print(traceback.format_exc()) + typo_map = {} + else: + print("No typoMap.json found, using empty typo corrections") for verb in verb_forms: verb_form_map[verb.replace("'", "").lower()] = verb diff --git a/design/vse.png b/design/vse.png new file mode 100644 index 0000000000000000000000000000000000000000..a28d81b41e70fd3ae3d04892164712638fbb96ce GIT binary patch literal 30230 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