From 2a2e5edfdd8977be1e7078eaa0e2f5020845bad8 Mon Sep 17 00:00:00 2001 From: Menghuan1918 Date: Sun, 22 Dec 2024 14:35:57 +0800 Subject: [PATCH] Many changes --- .github/workflows/python.app.yml | 0 Main.py | 28 ++++++++++++++++ README.md | 10 +++++- app.py | 55 ++++++++++++++++++++++++++++++- file_tool.py | 48 +++++++++++++++++++++++++++ icon.png | Bin 0 -> 17381 bytes requirements.txt | 5 +-- 7 files changed, 142 insertions(+), 4 deletions(-) create mode 100644 .github/workflows/python.app.yml create mode 100644 file_tool.py create mode 100644 icon.png diff --git a/.github/workflows/python.app.yml b/.github/workflows/python.app.yml new file mode 100644 index 0000000..e69de29 diff --git a/Main.py b/Main.py index bf23bb6..73a432f 100644 --- a/Main.py +++ b/Main.py @@ -80,6 +80,34 @@ def get_translator(choice=None): def create_translator(name): """Create translator instance based on name""" + # Get translator-specific settings from environment variables + openai_apikey = os.getenv("openai_apikey") + openai_baseurl = os.getenv("openai_baseurl", "https://api.openai.com/v1") + openai_model = os.getenv("openai_model", "gpt-4o-mini") + + ollama_baseurl = os.getenv("ollama_baseurl", "http://localhost:11434/v1") + ollama_model = os.getenv("ollama_model", "qwen2.5") + + deepseek_api = os.getenv("deepseek_api") + + deeplx_url = os.getenv("deeplx_url", "http://127.0.0.1:1188/translate") + deeplx_src = os.getenv("deeplx_src", "EN") + deeplx_dest = os.getenv("deeplx_dest", "ZH") + + deepl_apikey = os.getenv("deepl_apikey") + deepl_dest = os.getenv("deepl_dest", "ZH") + + # LLM common settings + temperature = float(os.getenv("temperature", 0.8)) + system_prompt = os.getenv("system_prompt", "") + input_prompt = os.getenv("input", "") + extra_type = os.getenv("extra_type", "markdown") + llm_src = os.getenv("llm_src", "English") + llm_dest = os.getenv("llm_dest", "中文") + + system_prompt = None if system_prompt == "" else system_prompt + input_prompt = None if input_prompt == "" else input_prompt + if name == "openai": if not openai_apikey or openai_apikey == "sk-1234567": print("Error: OpenAI API key not set") diff --git a/README.md b/README.md index 3ec8c4e..8430330 100644 --- a/README.md +++ b/README.md @@ -49,6 +49,14 @@ cp example.env .env 使用pyinstaller进行打包。使用`pip install pyinstaller`进行安装。 +### Linux/MacOS + +```bash +pyinstaller --onefile --add-data "reference.docx:." -i icon.png app.py +``` + +### Windows + ```bash -pyinstaller --onefile --add-data "reference.docx:." --collect-all pypandoc_binary app.py +pyinstaller --onefile --add-data "reference.docx;." -i icon.png app.py ``` \ No newline at end of file diff --git a/app.py b/app.py index f0dda33..1609f7c 100644 --- a/app.py +++ b/app.py @@ -31,12 +31,57 @@ from pdfdeal.Doc2X.ConvertV2 import upload_pdf, uid_status from PySide6.QtWidgets import QMessageBox from pdfdeal.file_tools import md_replace_imgs +from file_tool import fix_image_size # 常量 CONFIG_DIR = os.path.expanduser("~/.config/Doc2X") CONFIG_FILE = os.path.join(CONFIG_DIR, ".env") +# 设置环境变量 +def set_translator_env(translator_type, config): + if translator_type == "deepl": + os.environ["deepl_apikey"] = config.get("deepl_apikey", "") + os.environ["deepl_dest"] = config.get("deepl_dest", "") + elif translator_type == "google": + os.environ["google_src"] = config.get("google_src", "") + os.environ["google_dest"] = config.get("google_dest", "") + elif translator_type == "deeplx": + os.environ["deeplx_url"] = config.get("deeplx_url", "") + os.environ["deeplx_src"] = config.get("deeplx_src", "") + os.environ["deeplx_dest"] = config.get("deeplx_dest", "") + elif translator_type == "deepseek": + os.environ["deepseek_api"] = config.get("deepseek_api", "") + # LLM专属设置 + os.environ["temperature"] = config.get("temperature", "0.8") + os.environ["system_prompt"] = config.get("system_prompt", "") + os.environ["input"] = config.get("input", "") + os.environ["extra_type"] = config.get("extra_type", "markdown") + os.environ["llm_src"] = config.get("llm_src", "English") + os.environ["llm_dest"] = config.get("llm_dest", "中文") + elif translator_type == "openai": + os.environ["openai_apikey"] = config.get("openai_apikey", "") + os.environ["openai_baseurl"] = config.get("openai_baseurl", "") + os.environ["openai_model"] = config.get("openai_model", "") + # LLM专属设置 + os.environ["temperature"] = config.get("temperature", "0.8") + os.environ["system_prompt"] = config.get("system_prompt", "") + os.environ["input"] = config.get("input", "") + os.environ["extra_type"] = config.get("extra_type", "markdown") + os.environ["llm_src"] = config.get("llm_src", "English") + os.environ["llm_dest"] = config.get("llm_dest", "中文") + elif translator_type == "ollama": + os.environ["ollama_baseurl"] = config.get("ollama_baseurl", "") + os.environ["ollama_model"] = config.get("ollama_model", "") + # LLM专属设置 + os.environ["temperature"] = config.get("temperature", "0.8") + os.environ["system_prompt"] = config.get("system_prompt", "") + os.environ["input"] = config.get("input", "") + os.environ["extra_type"] = config.get("extra_type", "markdown") + os.environ["llm_src"] = config.get("llm_src", "English") + os.environ["llm_dest"] = config.get("llm_dest", "中文") + + class LLMSettingsDialog(QDialog): def __init__(self, config, parent=None): super().__init__(parent) @@ -156,6 +201,9 @@ def __init__(self, file_path, config, translator_type): def run(self): try: + # 设置环境变量 + set_translator_env(self.translator_type, self.config) + # 创建自定义打印函数以发出输出 def custom_print(text): self.output.emit(str(text)) @@ -215,6 +263,10 @@ async def process_pdf(file_path, apikey): self.file_path = output_md_path print("开始下载图片(如果有)...") md_replace_imgs(mdfile=self.file_path, replace="local", threads=10) + print("开始修复图片大小以解决 pandoc 中图片尺寸问题:") + img_dir = os.path.dirname(self.file_path) + img_folder = os.path.basename(self.file_path).split(".")[0] + "_img" + fix_image_size(os.path.join(img_dir, img_folder)) print("翻译中...") self.progress.emit(0, 100) Process_MD( @@ -327,7 +379,7 @@ def __init__(self): layout.addLayout(thread_layout) # 测试按钮 - self.test_btn = QPushButton("保存并测试") + self.test_btn = QPushButton("测试翻译器") self.test_btn.clicked.connect(self.test_translator) layout.addWidget(self.test_btn) @@ -470,6 +522,7 @@ def run(self): self.failure.emit(str(e)) translator_type = self.translator_combo.currentText() + set_translator_env(translator_type, self.config) self.output_text.append("提示: 正在测试翻译器,这可能需要一些时间..") self.output_text.show() diff --git a/file_tool.py b/file_tool.py new file mode 100644 index 0000000..13f2e89 --- /dev/null +++ b/file_tool.py @@ -0,0 +1,48 @@ +from PIL import Image +import os +import concurrent.futures + + +def process_image(file_path: str) -> None: + """Process a single image file by resaving it. + + Args: + file_path (str): Path to the image file + """ + try: + # Open and resave image + with Image.open(file_path) as img: + img.save(file_path, quality=95, optimize=True) + print(f"{os.path.basename(file_path)} ", end="") + except Exception as e: + print(f"Error processing {os.path.basename(file_path)}: {str(e)}") + + +def fix_image_size(folder_path: str, max_workers: int = 10) -> None: + """Fix image size issue for pandoc by resaving images in the folder using multiple threads. + + Args: + folder_path (str): Path to the folder containing images + max_workers (int, optional): Maximum number of worker threads. Defaults to 4. + """ + # Check if folder exists + if not os.path.exists(folder_path): + print(f"Error: Folder {folder_path} does not exist") + return + + # Get all files in folder + files = os.listdir(folder_path) + + # Common image extensions + img_extensions = [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp"] + + # Get list of image files to process + image_files = [ + os.path.join(folder_path, file) + for file in files + if any(file.lower().endswith(ext) for ext in img_extensions) + ] + + # Process images in parallel using ThreadPoolExecutor + with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor: + executor.map(process_image, image_files) diff --git a/icon.png b/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..165826e171b90dbb4057afa545a84479063fb974 GIT binary patch literal 17381 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 literal 0 HcmV?d00001 diff --git a/requirements.txt b/requirements.txt index 45b7b8b..80240d8 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,7 +1,8 @@ openai PySide6 -# "pdfdeal[rag]">=1.0.2 +pdfdeal[rag]>=1.0.2 git+https://github.com/ssut/py-googletrans.git httpx==0.27.2 pypandoc_binary -python-dotenv \ No newline at end of file +python-dotenv +pillow \ No newline at end of file