嗯,真心觉得程序员挺不容易的。
程序介绍:
本程序是一个多功能的压缩文件处理工具,支持解压、转换和合并文件。主要功能包括:
使用说明1. 启动程序
运行程序后,首先会提示用户是否启用日志记录:
请选择是否启用日志记录:1. 启用日志记录2. 禁用日志记录请输入数字选择:
接下来,程序会提示用户选择是否删除以下文件:
是否删除原始压缩包?(y/n): 是否删除解压缩后的 PDG 文件?(y/n): 是否删除转换后的 PDF 文件?(y/n): 是否删除解压后的文件夹?(y/n):
最后,用户需要输入压缩文件的路径:请输入压缩文件路径:
屏幕截图 2025-01-28 174224.png (48.28 KB, 下载次数: 0)
下载附件
如图展示
2025-1-28 17:42 上传
4. 程序运行
[color=]程序将按照以下步骤运行:
程序会在每个关键步骤输出简明的提示信息,例如:
[color=]程序有点大,启动可能花一点点时间,还请耐心等待。
[color=]如果有问题,还请发送日志内容,最好附带截图和文字描述!
[color=]如果有更好建议,希望大家提出来!
[color=]感谢!
下载:
主链:https://www.123865.com/s/nij4jv-2Iwmh? 提取码:52pj备链:https://www.123684.com/s/nij4jv-2Iwmh? 提取码:52pj
源代码:
import os
import zipfile
import rarfile
import py7zr
import logging
from PIL import Image
from PyPDF2 import PdfMerger, PdfReader
from concurrent.futures import ThreadPoolExecutor
from tqdm import tqdm# 配置日志
def configure_logging(enable_logging, log_level=logging.INFO):
"""配置日志记录"""
if enable_logging:
logging.basicConfig(
filename='error.log',
level=log_level,
format='%(asctime)s %(levelname)s:%(message)s'
)
logging.info("日志记录已启用.")
else:
logging.disable(logging.CRITICAL)
print("日志记录已禁用.")
def get_user_log_level():
"""从用户输入中获取日志级别"""
print("请选择是否启用日志记录:")
print("1. 启用日志记录")
print("2. 禁用日志记录")
choice = input("请输入数字选择: ").strip()
if choice == "1":
return True
elif choice == "2":
return False
else:
print("无效选择,将禁用日志记录.")
return False
class CompressionHandler:
"""处理压缩文件的解压、加密检测和解密"""
def __init__(self, file_path):
self.file_path = file_path
self.file_type = os.path.splitext(file_path)[1].lower().lstrip('.')
self.unzip_path = os.path.splitext(file_path)[0]
def _extract_zip(self, password=None):
"""提取 ZIP 文件"""
with zipfile.ZipFile(self.file_path, 'r') as zip_file:
zip_file.extractall(path=self.unzip_path, pwd=password.encode('utf-8') if password else None)
def _extract_rar(self, password=None):
"""提取 RAR 文件"""
with rarfile.RarFile(self.file_path, 'r') as rar_file:
rar_file.extractall(path=self.unzip_path, pwd=password.encode('utf-8') if password else None)
def _extract_7z(self, password=None):
"""提取 7z 文件"""
with py7zr.SevenZipFile(self.file_path, 'r', password=password) as archive:
archive.extractall(path=self.unzip_path)
def extract_file(self, password=None):
"""解压文件"""
try:
logging.info(f"开始解压缩文件: {self.file_path}")
print(f"正在解压缩文件: {self.file_path}")
if self.file_type == "zip":
self._extract_zip(password)
elif self.file_type == "rar":
self._extract_rar(password)
elif self.file_type == "7z":
try:
self._extract_7z(password)
except py7zr.exceptions.PasswordError:
logging.error("解压缩文件时发生错误: 密码错误")
print("错误: 解压缩文件时发生错误,原因:密码错误.")
return False
else:
logging.error(f"不支持的文件类型: {self.file_type}")
print(f"错误: 不支持的文件类型: {self.file_type}")
return False
logging.info(f"文件解压缩完成: {self.file_path}")
print("文件解压缩完成.")
return True
except Exception as e:
logging.error(f"解压缩 {self.file_path} 时发生错误: {e}")
print("错误: 解压缩文件时发生错误.")
return False
def check_encryption(self):
"""检查文件是否加密"""
try:
if self.file_type == "zip":
with zipfile.ZipFile(self.file_path) as zip_file:
return any(info.flag_bits & 0x1 for info in zip_file.infolist())
elif self.file_type == "rar":
with rarfile.RarFile(self.file_path) as rar_file:
return rar_file.needs_password()
elif self.file_type == "7z":
try:
with py7zr.SevenZipFile(self.file_path, 'r') as archive:
return archive.needs_password
except Exception:
return True
else:
logging.warning(f"不支持的文件类型: {self.file_type}")
print(f"警告: 不支持的文件类型: {self.file_type}")
return False
except Exception as e:
logging.error(f"检查加密时发生错误: {e}")
print(f"错误: 检查加密时发生错误.")
return False
def decrypt_and_extract(self, password_file="passwords.txt"):
"""尝试解密加密文件"""
try:
print("正在尝试解密文件...")
with open(password_file, encoding='utf-8') as f:
passwords = list(map(str.strip, f))
except FileNotFoundError:
logging.error(f"密码文件未找到: {password_file}")
print(f"错误: 密码文件未找到.")
return False
for password in passwords:
if self.extract_file(password):
logging.info(f"成功解密 {self.file_path},密码为: {password}")
print("文件解密完成.")
return True
logging.info("密码册中未找到正确密码")
print("解密失败,密码册中未找到正确密码.")
return False
def walk_os_file(path):
"""遍历文件目录下的所有文件"""
return [
os.path.join(root, file).replace("\\", "/")
for root, _, files in os.walk(path)
for file in files
]
def pdg2pdf(pdg_path, output_dir):
"""将 PDG 文件转换为 PDF"""
output_path = os.path.join(output_dir, os.path.basename(pdg_path).replace(".pdg", ".pdf"))
try:
logging.info(f"开始转换文件: {pdg_path}")
print(f"正在转换文件: {pdg_path}")
with Image.open(pdg_path) as img:
img = img.convert('RGB')
img.save(output_path, "PDF", quality=50, resolution=100.0)
logging.info(f"文件转换完成: {pdg_path} -> {output_path}")
print("文件转换完成.")
except Exception as e:
logging.error(f"转换 {pdg_path} 时发生错误: {e}")
print("错误: 转换文件时发生错误.")
def merge_pdf(extracted_path, output_dir, output_name='PDF(合并).pdf'):
"""合并同一目录下的 PDF 文件"""
pdf_files = [os.path.join(extracted_path, f) for f in os.listdir(extracted_path) if f.endswith('.pdf')]
pdf_files.sort()
merger = PdfMerger()
try:
logging.info("开始合并 PDF 文件")
print("正在合并 PDF 文件...")
with tqdm(pdf_files, desc="合并 PDF", unit="文件") as progress:
for pdf in progress:
with open(pdf, 'rb') as f:
reader = PdfReader(f)
if reader.is_encrypted:
logging.warning(f"跳过加密文件: {pdf}")
print(f"跳过加密文件: {pdf}")
continue
merger.append(reader)
output_path = os.path.join(output_dir, output_name)
with open(output_path, 'wb') as merged_pdf:
merger.write(merged_pdf)
logging.info(f"文件合并完成: {merged_pdf.name}")
print("文件合并完成.")
except Exception as e:
logging.error(f"合并 PDF 文件时发生错误: {e}")
print("错误: 合并 PDF 文件时发生错误.")
def delete_intermediate_files(target_dir, delete_pdg=False, delete_pdfs=True, delete_folder=False):
"""删除中间文件和目标文件夹"""
try:
logging.info("开始删除中间文件和目标文件夹...")
print("正在删除中间文件和目标文件夹...")
# 删除 PDG 和 PDF 文件
for root, _, files in os.walk(target_dir):
for file in files:
file_path = os.path.join(root, file)
if delete_pdg and file.endswith('.pdg'):
os.remove(file_path)
logging.info(f"已删除 PDG 文件: {file_path}")
print("删除 PDG 文件完成.")
if delete_pdfs and file.endswith('.pdf'):
os.remove(file_path)
logging.info(f"已删除 PDF 文件: {file_path}")
print("删除 PDF 文件完成.")
# 删除目标文件夹
if delete_folder and os.path.exists(target_dir):
os.rmdir(target_dir)
logging.info(f"已删除目标文件夹: {target_dir}")
print("删除目标文件夹完成.")
logging.info("中间文件和目标文件夹删除完成.")
print("删除中间文件和目标文件夹完成.")
except Exception as e:
logging.error(f"删除中间文件和目标文件夹时发生错误: {e}")
print("错误: 删除中间文件和目标文件夹时发生错误.")
def convert(compressed_file_path, delete_original=False, delete_pdg=False, delete_pdfs=False, delete_folder=False):
"""处理压缩文件,解压并转换为 PDF"""
compressed_file_path = os.path.join(os.getcwd(), compressed_file_path.strip('"'))
compressed_file_path = os.path.normpath(compressed_file_path)
if not os.path.exists(compressed_file_path):
logging.error(f"压缩文件不存在: {compressed_file_path}")
print("错误: 压缩文件不存在.")
return
try:
logging.info(f"开始处理文件: {compressed_file_path}")
print("开始处理文件...")
handler = CompressionHandler(compressed_file_path)
if handler.check_encryption():
if not handler.decrypt_and_extract():
logging.error("解密失败,程序终止")
print("解密失败,程序终止.")
return
else:
if not handler.extract_file():
logging.error("解压失败,程序终止")
print("解压失败,程序终止.")
return
if not os.path.exists(handler.unzip_path):
logging.error(f"解压后的目录不存在: {handler.unzip_path}")
print("错误: 解压后的目录不存在.")
return
# 获取原始文件所在目录
original_dir = os.path.dirname(compressed_file_path)
pdg_files = walk_os_file(handler.unzip_path)
if not pdg_files:
logging.error("未找到 PDG 文件进行转换")
print("错误: 未找到 PDG 文件进行转换.")
return
# 并行转换 PDG 文件
with ThreadPoolExecutor() as executor:
list(tqdm(
executor.map(lambda pdg: pdg2pdf(pdg, handler.unzip_path), pdg_files),
total=len(pdg_files),
desc="转换 PDG 到 PDF"
))
# 合并 PDF 文件到原始文件所在目录
merge_pdf(handler.unzip_path, output_dir=original_dir)
# 删除中间文件和目标文件夹
if delete_pdg or delete_pdfs or delete_folder:
delete_intermediate_files(handler.unzip_path, delete_pdg, delete_pdfs, delete_folder)
if delete_original:
os.remove(compressed_file_path)
logging.info(f"原始压缩包已删除: {compressed_file_path}")
print("原始压缩包已删除.")
logging.info("处理完成.")
print("处理完成.")
except Exception as e:
logging.error(f"处理文件时发生错误: {e}")
print("错误: 处理文件时发生错误.")
def get_user_choices():
"""获取用户的所有选择"""
delete_original = input("是否删除原始压缩包?(y/n): ").strip().lower() == 'y'
delete_pdg = input("是否删除解压缩后的 PDG 文件?(y/n): ").strip().lower() == 'y'
delete_pdfs = input("是否删除转换后的 PDF 文件?(y/n): ").strip().lower() == 'y'
delete_folder = input("是否删除解压后的文件夹?(y/n): ").strip().lower() == 'y'
compressed_file_path = input(r"请输入压缩文件路径: ").strip('"')
return compressed_file_path, delete_original, delete_pdg, delete_pdfs, delete_folder
if __name__ == '__main__':
try:
# 获取用户选择是否启用日志记录
enable_logging = get_user_log_level()
configure_logging(enable_logging)
# 获取用户的所有选择
compressed_file_path, delete_original, delete_pdg, delete_pdfs, delete_folder = get_user_choices()
convert(compressed_file_path, delete_original, delete_pdg, delete_pdfs, delete_folder)
except Exception as e:
logging.error(f"运行程序时发生错误: {e}")
print("错误: 运行程序时发生错误.")