diff --git a/server/file_association.py b/server/file_association.py index b1a9471..0acca4c 100644 --- a/server/file_association.py +++ b/server/file_association.py @@ -14,6 +14,8 @@ from typing import Optional, List, Dict, Tuple, Union from datetime import datetime import time import re +import shutil +import shutil def extract_all_zips( @@ -238,6 +240,42 @@ def get_files_with_times(folder: Path) -> List[Tuple[Path, datetime]]: return files +def extract_zip_recursive(zip_path: Path, extract_dir: Path) -> List[Path]: + """递归解压 zip 文件,如果解压后的文件还有 zip,继续解压""" + # 先清空 extract_dir 中的内容 + for item in extract_dir.iterdir(): + if item.is_file(): + item.unlink() + elif item.is_dir(): + shutil.rmtree(item) + + # 解压当前层 + with zipfile.ZipFile(zip_path, 'r') as zip_ref: + zip_ref.extractall(extract_dir) + + # 查找解压后的所有 zip 文件,递归解压 + new_zips = list(extract_dir.glob("*.zip")) + while new_zips: + for z in new_zips: + with zipfile.ZipFile(z, 'r') as zip_ref: + zip_ref.extractall(extract_dir) + z.unlink() # 删除已解压的 zip 文件 + new_zips = list(extract_dir.glob("*.zip")) + + # 递归收集所有解压后的文件(包括子目录) + def collect_all_files(dir_path: Path) -> List[Path]: + files = [] + for item in dir_path.iterdir(): + if item.is_file(): + files.append(item) + elif item.is_dir(): + files.extend(collect_all_files(item)) + return files + + extracted_files = collect_all_files(extract_dir) + return extracted_files + + def build_file_associations( word_content: List[str], twole_folder: Path, @@ -245,7 +283,7 @@ def build_file_associations( ) -> Dict: """构建文件关联关系""" result = [] - + twole_files = get_files_with_times(twole_folder) zxxk_files = get_files_with_times(zxxk_folder) @@ -254,16 +292,49 @@ def build_file_associations( parts = content.split('\t') if len(parts) < 6: continue - + # 提取两组数据:标题、网址、时间 title1, url1, time1 = parts[0].strip(), parts[1].strip(), parts[2].strip() title2, url2, time2 = parts[3].strip(), parts[4].strip(), parts[5].strip() - + + # 辅助函数:处理文件路径,如果是 zip 则递归解压 + def process_file(file_path: Path) -> List[str]: + filenames = [file_path.name] + # 检查是否是压缩文件 + if file_path.suffix.lower() in ('.zip', '.rar', '.7z'): + tmp_dir = Path(__file__).parent / "tmp" + tmp_dir.mkdir(exist_ok=True) + extract_target = tmp_dir / file_path.stem + # 清空 extract_target 目录 + if extract_target.exists(): + for item in extract_target.iterdir(): + if item.is_file(): + item.unlink() + elif item.is_dir(): + shutil.rmtree(item) + else: + extract_target.mkdir(parents=True, exist_ok=True) + + # 根据压缩格式选择解压方式 + if file_path.suffix.lower() == '.zip': + extracted = extract_zip_recursive(file_path, extract_target) + else: + # 其他压缩格式使用 subprocess + import subprocess + subprocess.run(['unzip', '-o', str(file_path), '-d', str(extract_target)], + capture_output=True) + extracted = list(extract_target.iterdir()) + + # 将解压后的文件名添加到列表 + filenames.extend([f.name for f in extracted]) + return filenames + return filenames + # 第一组:根据网址匹配文件 if 'www.21cnjy.com' in url1 and twole_files: file_path, ctime = twole_files.pop(0) result.append({ - "filename": [file_path.name], + "filename": process_file(file_path), "title": title1, "url": url1, "time": time1 @@ -271,17 +342,17 @@ def build_file_associations( elif 'www.zxxk.com' in url1 and zxxk_files: file_path, ctime = zxxk_files.pop(0) result.append({ - "filename": [file_path.name], + "filename": process_file(file_path), "title": title1, "url": url1, "time": time1 }) - + # 第二组:根据网址匹配文件 if 'www.21cnjy.com' in url2 and twole_files: file_path, ctime = twole_files.pop(0) result.append({ - "filename": [file_path.name], + "filename": process_file(file_path), "title": title2, "url": url2, "time": time2 @@ -289,12 +360,12 @@ def build_file_associations( elif 'www.zxxk.com' in url2 and zxxk_files: file_path, ctime = zxxk_files.pop(0) result.append({ - "filename": [file_path.name], + "filename": process_file(file_path), "title": title2, "url": url2, "time": time2 }) - + return {"items": result}