上传文件至 /

This commit is contained in:
2026-02-06 17:27:28 +08:00
parent 28987114bc
commit dbca17593b
+432
View File
@@ -0,0 +1,432 @@
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)