Files
automation_tool_for_work-wb/integrated_tool_test.py
T
2026-02-06 17:27:28 +08:00

433 lines
16 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import os
import shutil
import sys
import pathlib
import subprocess
from io import BytesIO
current_mode = None
def force_close_handles(folder_path):
try:
import psutil
closed_count = 0
for proc in psutil.process_iter(['pid', 'name']):
try:
for item in proc.open_files():
if folder_path.lower() in item.path.lower():
proc.kill()
closed_count += 1
print(f"[系统] 已关闭占用进程: {proc.info['name']} (PID: {proc.info['pid']})")
break
except (psutil.NoSuchProcess, psutil.AccessDenied):
pass
if closed_count > 0:
import time
time.sleep(0.5)
return closed_count > 0
except ImportError:
return False
def delete_system_files(folder_path):
system_files = ['thumbs.db', 'desktop.ini', '.ds_store', 'thumbs.db:encryptable']
deleted_count = 0
try:
for root, dirs, files in os.walk(folder_path):
for filename in files:
if filename.lower() in system_files or filename.startswith('._'):
file_path = os.path.join(root, filename)
try:
os.chmod(file_path, 0o777)
os.remove(file_path)
deleted_count += 1
except:
pass
if deleted_count > 0:
print(f"[系统] 已清理 {deleted_count} 个系统隐藏文件")
except:
pass
def get_next_log_index():
index = 1
while pathlib.Path(f"path_list_{index}.log").exists():
index += 1
return index
def open_folder(path: pathlib.Path):
if sys.platform.startswith("win"):
os.startfile(path)
elif sys.platform.startswith("darwin"):
subprocess.run(["open", path])
else:
subprocess.run(["xdg-open", path])
def mode_wb():
print("\n" + "="*60)
print("已进入 WB 模式 - 文件夹批处理工具")
print("功能:复制文件夹 -> 重命名文件夹和内部文件 -> 标记原文件夹")
print("="*60)
while True:
print("\n================== 新的工作任务 ==================")
work_dir = input("请输入主文件夹路径 (工作路径, 输入 :back 返回): ").strip()
if work_dir == ":back":
return
if not os.path.exists(work_dir):
print(f"[错误] 工作路径 '{work_dir}' 不存在,请先创建或检查路径。")
continue
print(f"[系统] 已锁定工作路径: {work_dir}")
process_wb_folder(work_dir)
print("\n------------------------------------------------------")
while True:
choice = input("任务结束。输入 :back 返回主菜单,或输入 :y 开启下一个工作路径: ").strip().lower()
if choice == ":back":
return
elif choice == ":y":
break
else:
print("输入无效,请输入 :back 或 :y")
def process_wb_folder(work_dir):
while True:
print("\n------------------------------------------------------")
src_path_input = input("请输入待复制的文件夹路径 (输入 :end 结束当前阶段): ").strip()
if src_path_input == ":end":
return
if not os.path.exists(src_path_input):
print(f"[错误] 路径 '{src_path_input}' 不存在,请重新输入。")
continue
target_name = input("请输入想要重命名的名称: ").strip()
if not target_name:
print("[错误] 名称不能为空。")
continue
dest_path = os.path.join(work_dir, target_name)
try:
if os.path.exists(dest_path):
print(f"[错误] 目标文件夹 '{dest_path}' 已经在工作路径下存在,跳过此任务。")
continue
shutil.copytree(src_path_input, dest_path)
print(f"[成功] 文件夹已复制并重命名为: {target_name}")
all_items = os.listdir(dest_path)
files = []
for f in all_items:
full_path = os.path.join(dest_path, f)
if os.path.isfile(full_path) and not f.startswith('.') and f.lower() not in ['thumbs.db', 'desktop.ini']:
files.append(f)
files.sort()
count = 1
for filename in files:
file_ext = os.path.splitext(filename)[1]
new_filename = f"{target_name} {count}{file_ext}"
old_file_path = os.path.join(dest_path, filename)
new_file_path = os.path.join(dest_path, new_filename)
os.rename(old_file_path, new_file_path)
count += 1
print(f"[成功] 已重命名文件夹内的 {count-1} 个文件 (从 1 开始)。")
clean_src_path = os.path.normpath(src_path_input)
parent_dir = os.path.dirname(clean_src_path)
original_folder_name = os.path.basename(clean_src_path)
new_src_folder_name = "used_" + original_folder_name
used_src_path = os.path.join(parent_dir, new_src_folder_name)
try:
delete_system_files(clean_src_path)
os.rename(clean_src_path, used_src_path)
print(f"[成功] 原文件夹已重命名为: {new_src_folder_name}")
except PermissionError:
print(f"[警告] 文件夹被占用,尝试强制解锁...")
if force_close_handles(clean_src_path):
try:
os.rename(clean_src_path, used_src_path)
print(f"[成功] 原文件夹已重命名为: {new_src_folder_name}")
except Exception as e:
print(f"[警告] 解锁后仍无法重命名: {e}")
print(f" 原文件夹路径: {clean_src_path}")
else:
print(f"[警告] 无法重命名原文件夹为 used_ 开头(需要安装psutil库)")
print(f" 安装命令: python.exe -m pip install psutil --break-system-packages")
print(f" 原文件夹路径: {clean_src_path}")
except FileExistsError:
print(f"[警告] 目标名称 '{new_src_folder_name}' 已存在,跳过重命名")
except Exception as e:
print(f"[警告] 重命名原文件夹时出错: {e}")
except PermissionError:
print(f"[错误] 权限不足,无法访问或复制文件夹")
except Exception as e:
print(f"[异常] 发生未知错误: {e}")
def mode_path():
print("\n" + "="*60)
print("已进入 PATH 模式 - 文件夹批量创建工具")
print("操作指南:")
print("1. 输入路径后按回车 -> 加入待创建队列")
print("2. 输入 ':y' 并回车 -> 立即批量创建队列中所有文件夹")
print("3. 输入 ':open x' -> 打开 path_list_x.log 中的所有文件夹")
print("4. 输入 ':back' -> 返回主菜单")
print("="*60 + "\n")
path_queue = []
while True:
queue_count = len(path_queue)
prompt = f"[{queue_count} 个待创建] >>> 请输入路径: "
raw_path = input(prompt).strip()
if raw_path.lower().startswith(":open"):
parts = raw_path.split()
if len(parts) != 2 or not parts[1].isdigit():
print("用法错误,应为 :open x")
continue
log_index = parts[1]
log_file = pathlib.Path(f"path_list_{log_index}.log")
if not log_file.exists():
print(f"日志文件不存在: {log_file}")
continue
print(f"正在打开 {log_file} 中的文件夹...")
with log_file.open("r", encoding="utf-8") as f:
for line in f:
folder = pathlib.Path(line.strip())
if folder.exists():
open_folder(folder)
else:
print(f"路径不存在,已跳过: {folder}")
continue
if raw_path.lower() == ':y':
if not path_queue:
print("警告:队列为空,没有什么可创建的。")
print("-" * 30)
continue
print(f"\n开始执行批量创建,共 {len(path_queue)} 个任务...")
success_count = 0
created_paths = []
for p_str in path_queue:
target_path = pathlib.Path(p_str)
try:
target_path.mkdir(parents=True, exist_ok=True)
print(f" [OK] Created: {target_path}")
success_count += 1
created_paths.append(str(target_path))
except Exception as e:
print(f" [ERR] Failed: {target_path} | 原因: {e}")
print(f"\n执行完毕。成功: {success_count} / 总计: {len(path_queue)}")
log_index = get_next_log_index()
log_file = pathlib.Path(f"path_list_{log_index}.log")
with log_file.open("w", encoding="utf-8") as f:
for p in created_paths:
f.write(p + "\n")
print(f"已生成日志文件: {log_file}")
print("-" * 30)
path_queue.clear()
continue
if raw_path.lower() == ':back':
if path_queue:
confirm = input(f"队列中还有 {len(path_queue)} 个路径未创建,确定要返回吗?(y/n): ")
if confirm.lower() != 'y':
continue
return
if not raw_path:
continue
path_queue.append(raw_path)
print(f"已加入队列: '{raw_path}'")
print("-" * 20)
def mode_photo():
print("\n" + "="*60)
print("已进入 PHOTO 模式 - 图片左右镜像工具")
print("功能:批量将文件夹中的所有图片进行左右镜像翻转")
print("支持格式:.jpg, .jpeg, .png, .bmp, .gif, .webp, .tif, .tiff")
print("操作指南:")
print("1. 输入文件夹路径后按回车 -> 加入待处理队列")
print("2. 输入 ':y' 并回车 -> 批量处理队列中所有文件夹的图片")
print("3. 输入 ':back' -> 返回主菜单")
print("="*60 + "\n")
try:
from PIL import Image
except ImportError:
print("[错误] 未检测到 Pillow 库!")
print("请先安装 Pillow")
print(" python.exe -m pip install pillow")
print("或者手动下载 pillow 的 .whl 文件后安装")
input("\n按回车返回主菜单...")
return
folder_queue = []
supported_extensions = {'.jpg', '.jpeg', '.png', '.bmp', '.gif', '.webp', '.tif', '.tiff'}
while True:
queue_count = len(folder_queue)
prompt = f"[{queue_count} 个文件夹待处理] >>> 请输入文件夹路径: "
folder_path = input(prompt).strip()
if folder_path.lower() == ':y':
if not folder_queue:
print("警告:队列为空,没有什么可处理的。")
print("-" * 30)
continue
print(f"\n开始执行图片镜像处理,共 {len(folder_queue)} 个文件夹...")
for folder in folder_queue:
print(f"\n处理文件夹: {folder}")
if not os.path.exists(folder):
print(f" [警告] 文件夹不存在,跳过")
continue
if not os.path.isdir(folder):
print(f" [警告] 路径不是文件夹,跳过")
continue
image_count = 0
error_count = 0
for filename in os.listdir(folder):
file_path = os.path.join(folder, filename)
if not os.path.isfile(file_path):
continue
_, ext = os.path.splitext(filename)
if ext.lower() not in supported_extensions:
continue
try:
if ext.lower() in ['.tif', '.tiff']:
with open(file_path, 'rb') as f:
img_data = f.read()
img = Image.open(BytesIO(img_data))
flipped_img = img.transpose(Image.FLIP_LEFT_RIGHT)
output = BytesIO()
flipped_img.save(output, format='TIFF')
with open(file_path, 'wb') as f:
f.write(output.getvalue())
else:
img = Image.open(file_path)
flipped_img = img.transpose(Image.FLIP_LEFT_RIGHT)
flipped_img.save(file_path)
print(f" [OK] {filename}")
image_count += 1
except Exception as e:
print(f" [ERR] {filename} | 原因: {e}")
error_count += 1
print(f" 文件夹处理完毕。成功: {image_count}, 失败: {error_count}")
print(f"\n全部执行完毕!共处理 {len(folder_queue)} 个文件夹。")
print("-" * 30)
folder_queue.clear()
continue
if folder_path.lower() == ':back':
if folder_queue:
confirm = input(f"队列中还有 {len(folder_queue)} 个文件夹未处理,确定要返回吗?(y/n): ")
if confirm.lower() != 'y':
continue
return
if not folder_path:
continue
folder_queue.append(folder_path)
print(f"已加入队列: '{folder_path}'")
print("-" * 20)
def print_main_menu():
print("\n" + "="*60)
print(" 集成工具箱 by FlandreScarle7")
print("="*60)
print("可用模式:")
print(" :mode wb - 文件夹批处理工具 (复制、重命名、标记)")
print(" :mode path - 文件夹批量创建工具")
print(" :mode photo - 图片左右镜像工具")
print(" :exit - 退出程序")
print("="*60)
def main():
print_main_menu()
while True:
command = input("\n>>> 请输入命令: ").strip().lower()
if command == ":exit":
print("[系统] 程序已退出。")
sys.exit(0)
elif command == ":mode wb":
mode_wb()
print_main_menu()
elif command == ":mode path":
mode_path()
print_main_menu()
elif command == ":mode photo":
mode_photo()
print_main_menu()
elif command == ":help":
print_main_menu()
else:
print("[错误] 未知命令。请输入 :mode wb / :mode path / :mode photo / :exit")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\n\n[系统] 程序被强制中断。")
sys.exit(0)