Spaces:
Sleeping
Sleeping
| import os | |
| import shutil | |
| import yaml | |
| import logging | |
| import io | |
| import re | |
| from jmcomic import create_option | |
| from utils import BASE_DIR, PDF_FINAL_DIR, sanitize_filename, manual_merge_pdf | |
| # --- 日志捕获设置 (专用于 JMComic) --- | |
| log_capture_string = io.StringIO() | |
| ch = logging.StreamHandler(log_capture_string) | |
| ch.setLevel(logging.INFO) | |
| logger = logging.getLogger('jmcomic') | |
| logger.addHandler(ch) | |
| logger.setLevel(logging.INFO) | |
| TEMP_YML = "jm_option_temp.yml" | |
| # 🔴 改动1:新增 quality 参数 | |
| def run_jm_download(album_ids_str, auth_type, cookies_input, username_input, password_input, quality): | |
| # 1. 解析 ID 列表 | |
| id_list = [x.strip() for x in re.split(r'[\s,,\n]+', album_ids_str) if x.strip()] | |
| if not id_list: | |
| yield None, "❌ 错误: 请至少输入一个本子 ID", "未检测到 ID" | |
| return | |
| # 2. 初始化环境 | |
| log_capture_string.truncate(0) | |
| log_capture_string.seek(0) | |
| # 临时目录 | |
| raw_download_dir = os.path.join(BASE_DIR, "raw_jm") | |
| # 3. 生成基础配置 | |
| config = { | |
| 'client': {'impl': 'api', 'retry_times': 3}, | |
| 'download': { | |
| 'image': {'suffix': '.jpg', 'quality': 85}, # 这里的quality是下载时的jpg质量,和我们后期的压缩不同,保持默认即可 | |
| 'threading': {'batch_count': 5} | |
| }, | |
| 'dir_rule': {'base_dir': raw_download_dir}, | |
| } | |
| if auth_type == "使用账号密码 (推荐)": | |
| if not username_input or not password_input: | |
| yield None, "❌ 错误: 请填写账号和密码", "参数错误" | |
| return | |
| config['client']['username'] = username_input | |
| config['client']['password'] = password_input | |
| with open(TEMP_YML, 'w', encoding='utf-8') as f: | |
| yaml.dump(config, f) | |
| # 4. 创建 Option | |
| try: | |
| option = create_option(TEMP_YML) | |
| if auth_type == "使用 Cookies (手动)" and cookies_input: | |
| option.call_once() | |
| option.headers['cookie'] = cookies_input.strip() | |
| except Exception as e: | |
| yield None, f"❌ 配置初始化失败: {e}", "初始化错误" | |
| return | |
| # 5. 循环下载 | |
| success_files = [] | |
| total_count = len(id_list) | |
| for index, album_id in enumerate(id_list): | |
| current_num = index + 1 | |
| progress_str = f"({current_num}/{total_count})" | |
| # 清理旧图片 | |
| if os.path.exists(raw_download_dir): | |
| shutil.rmtree(raw_download_dir) | |
| os.makedirs(raw_download_dir, exist_ok=True) | |
| yield success_files, f"🔄 {progress_str} 正在处理 ID: {album_id} ...", f"处理中 {current_num}/{total_count}" | |
| real_title = f"Unknown_{album_id}" | |
| try: | |
| # A. 获取信息 | |
| client = option.build_jm_client() | |
| try: | |
| album_detail = client.get_album_detail(album_id) | |
| real_title = album_detail.title | |
| except Exception: | |
| pass | |
| # B. 下载 | |
| yield success_files, f"📥 {progress_str} 正在下载图片: {real_title}...", f"下载中 {current_num}/{total_count}" | |
| option.download_album(album_id) | |
| # C. 合并 | |
| yield success_files, f"🔨 {progress_str} 正在压缩并合并 PDF (画质:{quality})...", f"合并中 {current_num}/{total_count}" | |
| safe_title = sanitize_filename(real_title) | |
| # 🔴 改动2:文件名加上画质标记 | |
| quality_tag = "Original" if quality >= 100 else f"Q{quality}" | |
| final_pdf_name = f"[JM][{quality_tag}] {safe_title}.pdf" | |
| final_pdf_path = os.path.join(PDF_FINAL_DIR, final_pdf_name) | |
| try: | |
| # 🔴 改动3:传入 quality 参数 | |
| manual_merge_pdf(raw_download_dir, final_pdf_path, quality=quality) | |
| except Exception as e: | |
| logger.error(f"合并PDF失败: {e}") | |
| yield success_files, f"❌ {progress_str} 合并失败: {e}", "合并出错" | |
| continue | |
| success_files.append(final_pdf_path) | |
| yield success_files, f"✅ {progress_str} 完成: {real_title}", f"完成 {current_num}/{total_count}" | |
| except Exception as e: | |
| import traceback | |
| traceback.print_exc() | |
| continue | |
| full_log = log_capture_string.getvalue() | |
| if not success_files: | |
| yield None, f"❌ 任务结束,无成功文件。\n日志:\n{full_log[-1000:]}", "全部失败" | |
| else: | |
| yield success_files, f"🎉 全部处理完毕!成功: {len(success_files)}个", "全部完成" |