first commit

This commit is contained in:
Hong_SZ
2025-10-03 17:36:19 +08:00
commit ae703e80fa
4 changed files with 421 additions and 0 deletions

232
process_archives.py Normal file
View File

@@ -0,0 +1,232 @@
import os
import zipfile
import shutil
import tempfile
import glob
import subprocess
from pathlib import Path
import threading
from concurrent.futures import ThreadPoolExecutor, as_completed
import time
# 导入可能需要安装的库
import tqdm
import patoolib
# 全局锁用于线程安全的输出和文件操作
print_lock = threading.Lock()
file_operation_lock = threading.Lock()
def safe_print(*args, **kwargs):
"""线程安全的打印函数"""
with print_lock:
print(*args, **kwargs)
def safe_file_operation(operation, *args, **kwargs):
"""线程安全的文件操作函数"""
with file_operation_lock:
return operation(*args, **kwargs)
def extract_archive(archive_path, extract_dir):
"""解压缩文件到指定目录"""
safe_print("正在解压文件...")
if archive_path.lower().endswith('.zip'):
# 使用zipfile处理zip文件可以显示进度条
with zipfile.ZipFile(archive_path, 'r') as zip_ref:
total = len(zip_ref.namelist())
for file in tqdm.tqdm(zip_ref.namelist(), total=total, desc="解压进度"):
zip_ref.extract(file, extract_dir)
else:
# 使用patoolib处理其他类型的压缩文件包括RAR
patoolib.extract_archive(archive_path, outdir=extract_dir)
safe_print("解压完成")
# 如果解压后只有一个文件夹将其内容移到extract_dir
items = os.listdir(extract_dir)
if len(items) == 1 and os.path.isdir(os.path.join(extract_dir, items[0])):
subfolder = os.path.join(extract_dir, items[0])
# 将子文件夹中的所有内容移到extract_dir
for item in os.listdir(subfolder):
shutil.move(os.path.join(subfolder, item), extract_dir)
# 删除空文件夹
os.rmdir(subfolder)
def process_files(directory):
"""处理目录中的文件:删除.bat文件重命名.jar文件"""
safe_print("正在处理文件...")
# 查找所有.bat文件并删除
bat_files = []
for root, _, files in os.walk(directory):
for file in files:
if file.lower().endswith('.bat'):
bat_path = os.path.join(root, file)
bat_files.append(bat_path)
# 使用线程池并行删除.bat文件
if bat_files:
def safe_remove_file(file_path):
"""安全删除文件"""
try:
safe_file_operation(os.remove, file_path)
return True
except Exception as e:
safe_print(f"删除文件 {file_path} 时出错: {e}")
return False
with ThreadPoolExecutor(max_workers=4) as executor:
futures = [executor.submit(safe_remove_file, bat_file) for bat_file in bat_files]
successful_deletions = 0
for future in tqdm.tqdm(as_completed(futures), total=len(futures), desc="删除.bat文件"):
if future.result():
successful_deletions += 1
safe_print(f"成功删除 {successful_deletions}/{len(bat_files)} 个.bat文件")
else:
safe_print("未找到需要删除的.bat文件")
# 查找所有.jar文件
jar_files = []
for root, _, files in os.walk(directory):
for file in files:
if file.lower().endswith('.jar'):
jar_path = os.path.join(root, file)
jar_files.append(jar_path)
# 处理.jar文件
if jar_files:
for jar_file in tqdm.tqdm(jar_files, desc="处理.jar文件"):
dir_path = os.path.dirname(jar_file)
# 检查是否存在fabric-server-launch.jar和server.jar
if os.path.basename(jar_file).lower() == 'fabric-server-launch.jar':
server_jar = os.path.join(dir_path, 'server.jar')
if os.path.exists(server_jar):
# 将server.jar重命名为ser.jar
ser_jar = os.path.join(dir_path, 'ser.jar')
safe_file_operation(shutil.move, server_jar, ser_jar)
# 将fabric-server-launch.jar重命名为server.jar
safe_file_operation(shutil.move, jar_file, os.path.join(dir_path, 'server.jar'))
# 如果是普通的jar文件且不是server.jar或ser.jar则重命名为server.jar
elif os.path.basename(jar_file).lower() != 'server.jar' and os.path.basename(jar_file).lower() != 'ser.jar':
# 检查目录中是否已存在server.jar
server_jar = os.path.join(dir_path, 'server.jar')
if not os.path.exists(server_jar):
safe_file_operation(shutil.move, jar_file, server_jar)
else:
safe_print("未找到需要处理的.jar文件")
def compress_directory(source_dir, output_path):
"""将目录压缩为zip文件确保解压后直接是文件而不是文件夹"""
safe_print("正在压缩文件...")
with zipfile.ZipFile(output_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
# 获取要压缩的文件列表
file_paths = []
for root, dirs, files in os.walk(source_dir):
for file in files:
file_path = os.path.join(root, file)
file_paths.append(file_path)
# 显示压缩进度
for file in tqdm.tqdm(file_paths, desc="压缩进度"):
# 计算相对路径,确保解压后不会有额外的目录层级
# 获取文件相对于source_dir的路径
rel_path = os.path.relpath(file, source_dir)
# 如果文件在子文件夹中,我们需要保留子文件夹结构,但去掉最外层文件夹
# 例如,如果文件在 temp_dir/folder1/file.txt我们希望在zip中存储为 folder1/file.txt
# 如果文件在 temp_dir/file.txt我们希望在zip中存储为 file.txt
zipf.write(file, rel_path)
def process_single_archive(archive_path, current_dir, index, total):
"""处理单个压缩文件的函数"""
safe_print(f"\n[线程 {threading.current_thread().name}] 处理第 {index+1}/{total} 个压缩文件: {os.path.basename(archive_path)}")
try:
# 创建临时目录用于解压
with tempfile.TemporaryDirectory() as temp_dir:
# 解压文件
try:
extract_archive(archive_path, temp_dir)
except Exception as e:
safe_print(f"解压失败: {e}")
return False
# 处理文件
process_files(temp_dir)
# 确保successzip目录存在
success_dir = os.path.join(current_dir, 'successzip')
if not os.path.exists(success_dir):
safe_file_operation(os.makedirs, success_dir, exist_ok=True)
# 创建新的压缩文件名,使用"cjsyun-"前缀保存到successzip文件夹
processed_archive = os.path.join(success_dir, f"cjsyun-{os.path.basename(archive_path)}")
if processed_archive.lower().endswith('.rar'):
processed_archive = processed_archive[:-4] + '.zip' # 将RAR转换为ZIP
# 压缩处理后的文件
compress_directory(temp_dir, processed_archive)
safe_print(f"[线程 {threading.current_thread().name}] 处理完成: {os.path.basename(processed_archive)}")
return True
except Exception as e:
safe_print(f"处理文件时出错: {e}")
return False
def main():
# 获取当前目录下的所有压缩文件
current_dir = os.path.dirname(os.path.abspath(__file__))
archives = []
for ext in ['*.zip', '*.rar']:
archives.extend(glob.glob(os.path.join(current_dir, ext)))
if not archives:
safe_print("当前目录下没有找到压缩文件")
return
safe_print(f"找到 {len(archives)} 个压缩文件")
# 确定线程数量最多使用4个线程但不超过文件数量
max_workers = min(4, len(archives))
safe_print(f"使用 {max_workers} 个线程并行处理")
start_time = time.time()
# 使用线程池并行处理压缩文件
with ThreadPoolExecutor(max_workers=max_workers, thread_name_prefix="Archive") as executor:
# 提交所有任务
futures = []
for i, archive_path in enumerate(archives):
future = executor.submit(process_single_archive, archive_path, current_dir, i, len(archives))
futures.append(future)
# 等待所有任务完成并收集结果
successful = 0
failed = 0
for future in as_completed(futures):
try:
result = future.result()
if result:
successful += 1
else:
failed += 1
except Exception as e:
safe_print(f"任务执行出错: {e}")
failed += 1
end_time = time.time()
total_time = end_time - start_time
safe_print(f"\n处理完成!")
safe_print(f"成功处理: {successful} 个文件")
safe_print(f"处理失败: {failed} 个文件")
safe_print(f"总耗时: {total_time:.2f}")
safe_print(f"平均每个文件: {total_time/len(archives):.2f}")
if __name__ == "__main__":
main()