mirror of
https://github.com/leiyuwei/RemovePwd.git
synced 2026-09-03 06:35:02 +08:00
Add files via upload
This commit is contained in:
15
src/docx.py
Normal file
15
src/docx.py
Normal file
@@ -0,0 +1,15 @@
|
||||
|
||||
def a():
|
||||
try:
|
||||
m
|
||||
except Exception as e:
|
||||
raise Exception("拷贝 pptx 文件错误") from e
|
||||
|
||||
|
||||
def b():
|
||||
try:
|
||||
a()
|
||||
except Exception as e:
|
||||
print('捕获到异常:{}'.format(e))
|
||||
|
||||
b()
|
||||
91
src/excel.py
Normal file
91
src/excel.py
Normal file
@@ -0,0 +1,91 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@文件 :excel.py
|
||||
@时间 :2023/07/20 14:02:21
|
||||
@作者 :aliha
|
||||
@版本 :1.0
|
||||
@依赖 :无
|
||||
@说明 :移除限制xlsx的限制密码
|
||||
'''
|
||||
|
||||
|
||||
from lxml import etree
|
||||
import shutil
|
||||
import os
|
||||
from util import delDirs, filterFiles, unZip, zipDir, mkdir
|
||||
|
||||
keyNode = ['sheetProtection', 'workbookProtection']
|
||||
|
||||
def unlockFile(fpath:str):
|
||||
fname = os.path.basename(fpath)
|
||||
fnamef, ftype = fname.rsplit(".",1)
|
||||
|
||||
parent_path = os.path.dirname(fpath)
|
||||
|
||||
tmpdir_path = os.path.join(parent_path, 'tmp')
|
||||
copyed_tar_fpath = os.path.join(tmpdir_path, fname)
|
||||
old_zip_fpath = tmpdir_path + '\\' + fnamef + '.zip'
|
||||
extractalldir_path = os.path.join(tmpdir_path, fnamef)
|
||||
new_zip_path = os.path.join(tmpdir_path, fnamef + '_removedPwd.zip')
|
||||
new_zip_fnamef = os.path.basename(new_zip_path)
|
||||
removedPwd_fpath = os.path.join(tmpdir_path, new_zip_fnamef + ftype)
|
||||
new_fpath = os.path.join(parent_path, fnamef + '_removedPwd.' + ftype)
|
||||
|
||||
try:
|
||||
if os.path.exists(tmpdir_path):
|
||||
os.remove(tmpdir_path)
|
||||
|
||||
mkdir(tmpdir_path)
|
||||
shutil.copyfile(fpath, copyed_tar_fpath)
|
||||
os.rename(copyed_tar_fpath, old_zip_fpath)
|
||||
|
||||
except FileExistsError as e:
|
||||
raise Exception("文件已存在,无法创建") from e
|
||||
except Exception as e:
|
||||
raise Exception("拷贝 pptx 文件错误") from e
|
||||
|
||||
# 解压文件
|
||||
unZip(old_zip_fpath, extractalldir_path)
|
||||
|
||||
xmls = filterFiles(extractalldir_path, 'xml')
|
||||
|
||||
for xml in xmls:
|
||||
if('styles' not in xml and 'app' not in xml and 'core' not in xml and 'custom' not in xml):
|
||||
for kwd in keyNode:
|
||||
removeNode(xml, xml, kwd)
|
||||
|
||||
zipDir(extractalldir_path, new_zip_path) # 重新压缩
|
||||
|
||||
try: # 重命名为 pptx,拷贝到原目录
|
||||
os.rename(new_zip_path, removedPwd_fpath)
|
||||
shutil.copyfile(removedPwd_fpath, new_fpath)
|
||||
except Exception as e:
|
||||
raise Exception("拷贝文件错误") from e
|
||||
|
||||
# 删除tmp下所有文件
|
||||
delDirs(tmpdir_path,root=True)
|
||||
|
||||
|
||||
def removeNode(fpath:str, sfPath, keyNode:str):
|
||||
"""移除xml节点,并且存储
|
||||
|
||||
Args:
|
||||
fpath (str): 源xml路径
|
||||
sfpath (str): 移除节点后的xml路径
|
||||
keyNode (str): 要移除节点
|
||||
"""
|
||||
try:
|
||||
tree = etree.parse(fpath)
|
||||
|
||||
for child in tree.iter():
|
||||
if(keyNode in child.tag):
|
||||
child.getparent().remove(child)
|
||||
tree.write(sfPath)
|
||||
break
|
||||
except Exception as e:
|
||||
raise Exception("移除节点失败") from e
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
src/icon.ico
Normal file
BIN
src/icon.ico
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 448 KiB |
37
src/pdf.py
Normal file
37
src/pdf.py
Normal file
@@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@文件 :pdf.py
|
||||
@时间 :2023/07/20 14:01:58
|
||||
@作者 :aliha
|
||||
@版本 :1.0
|
||||
@依赖 :无
|
||||
@说明 :移除PDF限制密码
|
||||
'''
|
||||
|
||||
|
||||
import pikepdf
|
||||
|
||||
|
||||
def unlockFile(fpath:str):
|
||||
"""移除pdf限制编辑,并且存储
|
||||
|
||||
Args:
|
||||
fpath (str): 带限制的pdf路径
|
||||
sfpath (str): 移除限制的pdf路径
|
||||
|
||||
Returns:
|
||||
str: 移除成功的提示话语
|
||||
"""
|
||||
try:
|
||||
pdf = pikepdf.open(fpath, allow_overwriting_input=True)
|
||||
except Exception as e:
|
||||
print('打开pdf出错')
|
||||
|
||||
try:
|
||||
sfpath = fpath.rsplit('.',1)[0] +"_removepwd."+ fpath.rsplit('.',1)[1]
|
||||
pdf.save(sfpath)
|
||||
except Exception as e:
|
||||
print('写入pdf失败')
|
||||
|
||||
return 'ヾ(≧▽≦*)o 恭喜你,移除成功'
|
||||
16
src/pic.py
Normal file
16
src/pic.py
Normal file
File diff suppressed because one or more lines are too long
95
src/pptx.py
Normal file
95
src/pptx.py
Normal file
@@ -0,0 +1,95 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@文件 :pptx.py
|
||||
@时间 :2023/07/20 14:00:53
|
||||
@作者 :aliha
|
||||
@版本 :1.0
|
||||
@依赖 :util.py
|
||||
@说明 :移除PPTX限制密码
|
||||
'''
|
||||
|
||||
|
||||
from lxml import etree
|
||||
import shutil
|
||||
import os
|
||||
from util import delDirs, filterFiles, unZip, zipDir, mkdir
|
||||
|
||||
keyNode = ['modifyVerifier']
|
||||
|
||||
def unlockFile(fpath:str):
|
||||
fname = os.path.basename(fpath)
|
||||
fnamef, ftype = fname.rsplit(".",1)
|
||||
|
||||
parent_path = os.path.dirname(fpath)
|
||||
|
||||
tmpdir_path = os.path.join(parent_path, 'tmp')
|
||||
copyed_tar_fpath = os.path.join(tmpdir_path, fname)
|
||||
old_zip_fpath = tmpdir_path + '\\' + fnamef + '.zip'
|
||||
extractalldir_path = os.path.join(tmpdir_path, fnamef)
|
||||
new_zip_path = os.path.join(tmpdir_path, fnamef + '_removedPwd.zip')
|
||||
new_zip_fnamef = os.path.basename(new_zip_path)
|
||||
removedPwd_fpath = os.path.join(tmpdir_path, new_zip_fnamef + ftype)
|
||||
new_fpath = os.path.join(parent_path, fnamef + '_removedPwd.' + ftype)
|
||||
|
||||
|
||||
try:
|
||||
if os.path.exists(tmpdir_path):
|
||||
os.remove(tmpdir_path)
|
||||
|
||||
mkdir(tmpdir_path)
|
||||
shutil.copyfile(fpath, copyed_tar_fpath)
|
||||
os.rename(copyed_tar_fpath, old_zip_fpath)
|
||||
|
||||
except FileExistsError as e:
|
||||
raise Exception("文件已存在,无法创建") from e
|
||||
except Exception as e:
|
||||
raise Exception("拷贝 pptx 文件错误") from e
|
||||
|
||||
|
||||
# 解压文件
|
||||
unZip(old_zip_fpath, extractalldir_path)
|
||||
|
||||
xmls = filterFiles(extractalldir_path, 'xml')
|
||||
|
||||
for xml in xmls:
|
||||
if('Styles' not in xml and 'Props' not in xml and 'theme' not in xml and 'tag' not in xml and 'slide' not in xml):
|
||||
for kwd in keyNode:
|
||||
removeNode(xml, xml, kwd)
|
||||
|
||||
zipDir(extractalldir_path, new_zip_path) # 重新压缩
|
||||
|
||||
try: # 重命名为 pptx,拷贝到原目录
|
||||
os.rename(new_zip_path, removedPwd_fpath)
|
||||
shutil.copyfile(removedPwd_fpath, new_fpath)
|
||||
except Exception as e:
|
||||
raise Exception("拷贝文件错误") from e
|
||||
|
||||
|
||||
# 删除tmp下所有文件
|
||||
delDirs(tmpdir_path,root=True)
|
||||
|
||||
|
||||
def removeNode(fpath:str, sfPath, keyNode:str):
|
||||
"""移除xml节点,并且存储
|
||||
|
||||
Args:
|
||||
fpath (str): 源xml路径
|
||||
sfpath (str): 移除节点后的xml路径
|
||||
keyNode (str): 要移除节点
|
||||
"""
|
||||
try:
|
||||
tree = etree.parse(fpath)
|
||||
|
||||
for child in tree.iter():
|
||||
if(keyNode in child.tag):
|
||||
child.getparent().remove(child)
|
||||
tree.write(sfPath)
|
||||
break
|
||||
except Exception as e:
|
||||
raise Exception("移除节点失败") from e
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
62
src/readme.py
Normal file
62
src/readme.py
Normal file
@@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@文件 :readme.py
|
||||
@时间 :2023/07/20 14:00:28
|
||||
@作者 :aliha
|
||||
@版本 :1.0
|
||||
@依赖 :无
|
||||
@说明 :软件的介绍说明
|
||||
'''
|
||||
|
||||
|
||||
__updateLog = '''
|
||||
|
||||
<h4><span style="color:red">V 0.3.1 </span></h4>
|
||||
<p>更新日期:2023-7-21</p>
|
||||
<p>修复:错误路径导致程序卡死</p>
|
||||
<hr />
|
||||
|
||||
<h4><span style="color:red">V 0.3.0 </span></h4>
|
||||
<p>更新日期:2023-7-20</p>
|
||||
<p>新增:拖拽文件或者文件夹打开的功能</p>
|
||||
<p>新增:批量移除限制密码的功能</p>
|
||||
<p>变更:更改 GUI 框架为 Pyside6 ,更漂亮的 UI</p>
|
||||
<p>修复:无法重复点击【开始处理】按钮,需要重新打开的 BUG</p>
|
||||
<hr />
|
||||
|
||||
<h4><span style="color:red">V 0.2.1 </span></h4>
|
||||
<p>更新日期:2023-7-17</p>
|
||||
<p>1. 增加移除限制 pptx 文档编辑的密码</p>
|
||||
<p>2. 修复 bug :启动软件直接点击【开始】按钮会退出软件</p>
|
||||
<hr />
|
||||
|
||||
<h4><span style="color:red">V 0.2.0 </span></h4>
|
||||
<p>更新日期:2023-7-13</p>
|
||||
<p>1. 增加移除限制 xlsx 文档编辑的密码,包括工作簿和工作表保护密码</p>
|
||||
<hr />
|
||||
|
||||
<h4><span style="color:red">V 0.1.0 </span></h4>
|
||||
<p>更新日期:2022-10-24</p>
|
||||
<p>1. 移除限制pdf文档编辑的密码</p>
|
||||
<hr />
|
||||
|
||||
'''
|
||||
|
||||
__info = """
|
||||
<p>批量移除限制编辑密码</p>
|
||||
<p>移除PDF、xlsx、pptx限制密码输出文件在源路径,结果名称带_removepwd</p>
|
||||
<p>只能移除文档限制编辑的密码解密不了加密文件</p>
|
||||
"""
|
||||
|
||||
info = {
|
||||
'author': 'aliha',
|
||||
'version': '0.3.1',
|
||||
'updateDate': '2023-07-21',
|
||||
'userWeb': 'https://www.52pojie.cn/home.php?mod=space&uid=1873109',
|
||||
'info': __info,
|
||||
'updateLog': __updateLog
|
||||
}
|
||||
|
||||
# <p style="font-size:30px;color:orange">p标签设置字体颜色</p>
|
||||
# nuitka --enable-plugin=pyside6 --standalone --onefile --remove-output --windows-disable-console --windows-icon-from-ico=icon.ico RemovePwd.py
|
||||
239
src/removePwd.py
Normal file
239
src/removePwd.py
Normal file
@@ -0,0 +1,239 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@文件 :removePwd.py
|
||||
@时间 :2023/07/20 10:42:17
|
||||
@作者 :aliha
|
||||
@版本 :1.0
|
||||
@依赖 :thread.py, styleSheet.py, readme.py, pic.py
|
||||
@说明 :文档密码移除工具主界面
|
||||
'''
|
||||
|
||||
|
||||
from PySide6.QtWidgets import QApplication, QLabel, QVBoxLayout, QWidget, QTabWidget, QPushButton, QHBoxLayout, QTextEdit, QTextBrowser, QSizePolicy, QSpacerItem
|
||||
from PySide6.QtGui import QDragEnterEvent, QDropEvent, QDragMoveEvent, QPixmap, QPainter, QCursor, QCloseEvent, QFont
|
||||
from PySide6.QtCore import Qt, QByteArray, QThread, Signal
|
||||
import sys
|
||||
import base64
|
||||
import os
|
||||
from styleSheet import styleSheet
|
||||
from readme import info
|
||||
from pic import imgstr
|
||||
from thread import WorkThread
|
||||
|
||||
class FileDropLabel(QLabel):
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent)
|
||||
self.setObjectName("label") # 添加该行
|
||||
self.setAcceptDrops(True)
|
||||
self.setAlignment(Qt.AlignCenter)
|
||||
self.setText("拖拽文件或文件夹到这里")
|
||||
self.setStyleSheet("QLabel { border: 2px dashed #aaa; padding: 5px; color: #555; }")
|
||||
|
||||
def dragEnterEvent(self, event: QDragEnterEvent):
|
||||
if event.mimeData().hasUrls():
|
||||
event.acceptProposedAction()
|
||||
|
||||
def dragMoveEvent(self, event: QDragMoveEvent):
|
||||
if event.mimeData().hasUrls():
|
||||
event.acceptProposedAction()
|
||||
event.setDropAction(Qt.CopyAction)
|
||||
pixmap = QPixmap(100, 100)
|
||||
pixmap.fill(Qt.transparent)
|
||||
painter = QPainter(pixmap)
|
||||
painter.setOpacity(0.7)
|
||||
painter.drawPixmap(0, 0, self.grab())
|
||||
painter.end()
|
||||
cursor = QCursor(pixmap)
|
||||
event.accept()
|
||||
self.setCursor(cursor)
|
||||
else:
|
||||
event.ignore()
|
||||
|
||||
def dropEvent(self, event: QDropEvent):
|
||||
if event.mimeData().hasUrls():
|
||||
urls = event.mimeData().urls()
|
||||
file_path = urls[0].toLocalFile()
|
||||
self.setText("已选择: " + file_path)
|
||||
self.setCursor(Qt.CursorShape.ArrowCursor)
|
||||
# 调用MainWindow的方法,将选定的文件路径传递过去
|
||||
main_window = self.window() # 使用 window() 方法获取父级窗口(MainWindow)
|
||||
if isinstance(main_window, MainWindow):
|
||||
main_window.setSelectedFilePath(file_path)
|
||||
else:
|
||||
event.ignore()
|
||||
|
||||
class ClickableLabel(QLabel):
|
||||
def __init__(self, text, url=None):
|
||||
super().__init__()
|
||||
self.url = url
|
||||
self.text = text
|
||||
|
||||
if self.url is not None:
|
||||
self.setText(f'<a href="{url}">{text}</a>')
|
||||
self.setOpenExternalLinks(True) # 打开链接时在外部浏览器中打开
|
||||
self.setStyleSheet("color: blue; text-decoration: underline;") # 设置颜色和下划线效果
|
||||
else:
|
||||
self.setText(f'<p >{text}</>')
|
||||
|
||||
font = QFont("Arial", 12, QFont.Bold)
|
||||
self.setFont(font)
|
||||
|
||||
|
||||
|
||||
class AboutUsTab(QWidget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
|
||||
layout = QHBoxLayout(self)
|
||||
left_layout = QVBoxLayout()
|
||||
|
||||
# Create labels for displaying software information
|
||||
author_label = ClickableLabel("作者信息:\t{}".format(info['author']),info['userWeb'])
|
||||
version_label = ClickableLabel("软件版本信息:\t{}".format(info['version']))
|
||||
update_label = ClickableLabel("更新日期:\t{}".format(info['updateDate']))
|
||||
|
||||
# Create a layout for the QR code
|
||||
qr_code_layout = QHBoxLayout()
|
||||
qr_code_label = QLabel(self)
|
||||
png = self.base64ToByte()
|
||||
qr_code_image = QPixmap()
|
||||
qr_code_image.loadFromData(png)
|
||||
# qr_code_image = QPixmap("QR.png")
|
||||
qr_code_image = qr_code_image.scaled(250, 250, Qt.KeepAspectRatio)
|
||||
qr_code_label.setPixmap(qr_code_image)
|
||||
qr_code_layout.addWidget(qr_code_label)
|
||||
|
||||
left_layout.addWidget(author_label)
|
||||
left_layout.addWidget(version_label)
|
||||
left_layout.addWidget(update_label)
|
||||
left_layout.addLayout(qr_code_layout)
|
||||
left_layout.addStretch()
|
||||
|
||||
funcInfo_label = QTextBrowser(self)
|
||||
funcInfo_label.setOpenExternalLinks(True)
|
||||
funcInfo_label.setLineWrapMode(QTextBrowser.WidgetWidth)
|
||||
|
||||
func_info_html = """
|
||||
<h3>功能简介:</h3>
|
||||
{}
|
||||
<h3>更新日志</h3>
|
||||
{}
|
||||
""".format(info['info'],info['updateLog'])
|
||||
|
||||
funcInfo_label.setHtml(func_info_html)
|
||||
|
||||
layout.addLayout(left_layout)
|
||||
layout.addWidget(funcInfo_label)
|
||||
|
||||
self.setLayout(layout)
|
||||
|
||||
def base64ToByte(self):
|
||||
# Step 1: Decode the base64 data to obtain the raw image data
|
||||
decoded_data = base64.b64decode(imgstr)
|
||||
|
||||
# Step 2: Create a QByteArray from the decoded image data
|
||||
byte_array = QByteArray(decoded_data)
|
||||
|
||||
# Step 3: Load the image data into a QPixmap
|
||||
# pixmap = QPixmap()
|
||||
# pixmap.loadFromData(byte_array)
|
||||
return byte_array
|
||||
|
||||
class MainWindow(QWidget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setWindowTitle("文档密码移除工具")
|
||||
self.resize(600, 280)
|
||||
self.thread = None
|
||||
self.selected_file_path = None
|
||||
|
||||
# def rendererWindow(self):
|
||||
layout = QVBoxLayout(self)
|
||||
|
||||
tab_widget = QTabWidget(self)
|
||||
|
||||
# Tab 1: Password Removal
|
||||
tab1 = QWidget(self)
|
||||
tab1_layout = QVBoxLayout(tab1)
|
||||
label = FileDropLabel(tab1)
|
||||
tab1_layout.addWidget(label)
|
||||
|
||||
self.progress_output = QTextEdit(tab1)
|
||||
self.progress_output.setReadOnly(True)
|
||||
tab1_layout.addWidget(self.progress_output)
|
||||
|
||||
self.button = QPushButton("开始处理", tab1)
|
||||
self.button.clicked.connect(self.startWorkerThread)
|
||||
tab1_layout.addWidget(self.button)
|
||||
|
||||
tab1.setLayout(tab1_layout)
|
||||
tab_widget.addTab(tab1, "限制密码移除")
|
||||
|
||||
# Tab 2: Software Settings
|
||||
tab2 = QWidget(self)
|
||||
tab_widget.addTab(tab2, "批量加密解密")
|
||||
|
||||
tab2_layout = QVBoxLayout(tab2)
|
||||
development_label = QLabel("正在开发中,请耐心等待", tab2)
|
||||
development_label.setAlignment(Qt.AlignCenter)
|
||||
tab2_layout.addWidget(development_label)
|
||||
|
||||
tab2.setLayout(tab2_layout)
|
||||
|
||||
# Create the third tab (About Us)
|
||||
tab3 = AboutUsTab()
|
||||
tab_widget.addTab(tab3, "关于我们")
|
||||
|
||||
layout.addWidget(tab_widget)
|
||||
|
||||
self.setStyleSheet(styleSheet)
|
||||
layout.setContentsMargins(0, 1, 0, 0)
|
||||
self.setLayout(layout)
|
||||
|
||||
def closeEvent(self, event: QCloseEvent) -> None:
|
||||
return super().closeEvent(event)
|
||||
|
||||
def startWorkerThread(self):
|
||||
if self.selected_file_path is not None:
|
||||
if os.path.isdir(self.selected_file_path) or os.path.isfile(self.selected_file_path):
|
||||
self.worker = WorkThread()
|
||||
self.thread = QThread()
|
||||
self.worker.moveToThread(self.thread)
|
||||
self.worker.setFilePath(self.selected_file_path)
|
||||
self.worker.progressSignal.connect(self.updateProgressBar)
|
||||
self.thread.started.connect(self.progress_output.clear)
|
||||
self.thread.started.connect(self.worker.work)
|
||||
self.thread.finished.connect(self.thread.quit)
|
||||
self.thread.finished.connect(self.unlockStartButtom)
|
||||
self.thread.finished.connect(self.thread.deleteLater)
|
||||
self.thread.start()
|
||||
self.button.setEnabled(False)
|
||||
self.button.setStyleSheet('background-color: #e0e0e0;')
|
||||
label = self.findChild(FileDropLabel, "label")
|
||||
if label:
|
||||
label.setEnabled(False)
|
||||
else:
|
||||
self.progress_output.clear()
|
||||
self.progress_output.append('请输入正确的路径')
|
||||
|
||||
def unlockStartButtom(self):
|
||||
self.button.setEnabled(True)
|
||||
self.button.setStyleSheet('background-color: #4caf50;')
|
||||
label = self.findChild(FileDropLabel, "label")
|
||||
if label:
|
||||
label.setEnabled(True)
|
||||
|
||||
def setSelectedFilePath(self, file_path):
|
||||
self.selected_file_path = file_path
|
||||
|
||||
def updateProgressBar(self, value):
|
||||
self.progress_output.append(value)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
app = QApplication(sys.argv)
|
||||
window = MainWindow()
|
||||
# window.rendererWindow()
|
||||
window.show()
|
||||
sys.exit(app.exec())
|
||||
BIN
src/requirements.txt
Normal file
BIN
src/requirements.txt
Normal file
Binary file not shown.
56
src/styleSheet.py
Normal file
56
src/styleSheet.py
Normal file
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@文件 :styleSheet.py
|
||||
@时间 :2023/07/20 14:00:10
|
||||
@作者 :aliha
|
||||
@版本 :1.0
|
||||
@依赖 :无
|
||||
@说明 :窗口的样式文件
|
||||
'''
|
||||
|
||||
|
||||
styleSheet = """
|
||||
QPushButton {
|
||||
background-color: #4caf50;
|
||||
color: white;
|
||||
padding: 10px;
|
||||
border: none;
|
||||
border-radius: 5px;
|
||||
}
|
||||
QPushButton:hover {
|
||||
background-color: #45a049;
|
||||
}
|
||||
QPushButton:pressed {
|
||||
background-color: #2980b9;
|
||||
}
|
||||
QTextEdit {
|
||||
background-color: #fff;
|
||||
border: 2px solid #aaa;
|
||||
padding: 5px;
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
color: #333;
|
||||
}
|
||||
QTabWidget::pane {
|
||||
border: 1px solid #aaa;
|
||||
background-color: #f0f0f0;
|
||||
padding: 0px;
|
||||
}
|
||||
QTabBar::tab {
|
||||
background-color: #4caf50;
|
||||
color: white;
|
||||
padding: 8px;
|
||||
border: none;
|
||||
font-family: Arial, sans-serif;
|
||||
font-size: 14px;
|
||||
font-weight: bold;
|
||||
}
|
||||
QTabBar::tab:hover {
|
||||
background-color: #45a049;
|
||||
}
|
||||
QTabBar::tab:selected {
|
||||
background-color: #fff;
|
||||
color: #4caf50;
|
||||
}
|
||||
"""
|
||||
97
src/thread.py
Normal file
97
src/thread.py
Normal file
@@ -0,0 +1,97 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@文件 :thread.py
|
||||
@时间 :2023/07/20 10:41:04
|
||||
@作者 :aliha
|
||||
@版本 :1.0
|
||||
@依赖 :excel.py, pdf.py, pptx.py
|
||||
@说明 :移除密码的多线程处理
|
||||
'''
|
||||
|
||||
from PySide6.QtCore import QObject, QThread, Signal
|
||||
from pdf import unlockFile as pdfUnlock
|
||||
from excel import unlockFile as xlsxUnlock
|
||||
from pptx import unlockFile as pptxUnlock
|
||||
import time
|
||||
import os
|
||||
|
||||
class WorkThread(QObject):
|
||||
count = (0)
|
||||
# countSignal = Signal(int)
|
||||
progressSignal = Signal(str)
|
||||
tipsSignal = Signal(str)
|
||||
|
||||
def __init__(self):
|
||||
super(WorkThread, self).__init__()
|
||||
self.file_path = None
|
||||
|
||||
def setFilePath(self, file_path):
|
||||
self.file_path = file_path
|
||||
|
||||
# def work(self):
|
||||
# self.flag = True
|
||||
# while self.flag:
|
||||
# self.count += 1
|
||||
# self.progressSignal.emit(self.count)
|
||||
# time.sleep(0.1)
|
||||
# if(self.count == 100):
|
||||
# QThread.currentThread().quit()
|
||||
# break
|
||||
|
||||
def work(self):
|
||||
if os.path.isfile(self.file_path ):
|
||||
self.progressSignal.emit('#=>[1/1]: {}'.format(self.file_path))
|
||||
self.unlockFile(self.file_path)
|
||||
|
||||
if os.path.isdir(self.file_path ):
|
||||
file_lists = os.listdir(self.file_path)
|
||||
|
||||
for file in file_lists:
|
||||
self.count += 1
|
||||
child_path = os.path.join(self.file_path, file)
|
||||
|
||||
try:
|
||||
self.unlockFile(child_path)
|
||||
except Exception as e:
|
||||
self.progressSignal.emit('捕获到异常信息: {}'.format(e))
|
||||
|
||||
self.progressSignal.emit('#=>[{}/{}]: {}'.format(self.count, len(file_lists), file))
|
||||
|
||||
self.progressSignal.emit('ヾ(≧▽≦*)o 恭喜你,移除成功 \r\n 解密的文件保存在原目录下哦,名称带“removedPwd')
|
||||
QThread.currentThread().quit()
|
||||
|
||||
|
||||
|
||||
def unlockFile(self, file):
|
||||
try:
|
||||
if('xlsx' in os.path.basename(file)):
|
||||
xlsxUnlock(file)
|
||||
if('pdf' in os.path.basename(file)):
|
||||
pdfUnlock(file)
|
||||
if('pptx' in os.path.basename(file)):
|
||||
pptxUnlock(file)
|
||||
|
||||
except Exception as e:
|
||||
raise Exception("程序错误,请联系作者") from e
|
||||
|
||||
|
||||
# 上述代码的启动方式如下:
|
||||
|
||||
# class main():
|
||||
|
||||
# def runIt(self):
|
||||
# self.worker = WorkThread()
|
||||
# self.thread = QThread()
|
||||
# self.worker.moveToThread(self.thread)
|
||||
# self.worker.countSignal.connect(self.flush)
|
||||
# self.thread.started.connect(self.worker.work)
|
||||
# self.finished.connect(self.worker.quit)
|
||||
# self.finished.connect(self.worker.deleteLater)
|
||||
# self.thread.start()
|
||||
|
||||
# def flush(self):
|
||||
# print('flush ing')
|
||||
|
||||
|
||||
|
||||
113
src/util.py
Normal file
113
src/util.py
Normal file
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/env python
|
||||
# -*- encoding: utf-8 -*-
|
||||
'''
|
||||
@文件 :util.py
|
||||
@时间 :2023/07/20 13:59:26
|
||||
@作者 :aliha
|
||||
@版本 :1.0
|
||||
@依赖 :无
|
||||
@说明 :常用的文件处理的工具函数抽取到了这里
|
||||
'''
|
||||
|
||||
|
||||
import shutil
|
||||
import os
|
||||
import zipfile
|
||||
|
||||
|
||||
def delDirs(dirpath:str, root=False):
|
||||
"""删除路径文件下所有的文件,root=true 时包括根文件夹
|
||||
|
||||
Args:
|
||||
dirpath (str): 文件夹路径
|
||||
root (boolean): 是否删除根目录
|
||||
"""
|
||||
try:
|
||||
filelists = os.listdir(dirpath) # 获取目录下所有文件列表
|
||||
for mydir in filelists: # 遍历文件列表
|
||||
filepath = os.path.join(dirpath, mydir) # 将文件名进行拼接
|
||||
if os.path.isfile(filepath): # 判断该文件是否为文件
|
||||
os.remove(filepath) # 若为文件,则直接删除
|
||||
elif os.path.isdir(filepath): # 判断该文件是否为文件夹
|
||||
shutil.rmtree(filepath, True) # 若为文件夹,则删除该文件夹及文件夹内所有文件
|
||||
if(root):
|
||||
shutil.rmtree(dirpath, True) # 最后删除根文件夹
|
||||
except Exception as e:
|
||||
print('删除缓存文件失败')
|
||||
|
||||
|
||||
def filterFiles(folder_path:str, file_extension:str):
|
||||
"""获取指定路径下,符合扩展名条件的文件路径
|
||||
|
||||
Args:
|
||||
folder_path (str): 根目录
|
||||
file_extension (str): 扩展名
|
||||
|
||||
Returns:
|
||||
_type_: 查找结果组成的数组
|
||||
"""
|
||||
|
||||
files = []
|
||||
|
||||
def filter(folder:str, extension:str):
|
||||
|
||||
try:
|
||||
file_lists = os.listdir(folder)
|
||||
for child in file_lists:
|
||||
child_path = os.path.join(folder, child)
|
||||
|
||||
if(os.path.isfile(child_path)):
|
||||
frname, ftype = os.path.basename(child_path).rsplit('.',1)
|
||||
if(extension in ftype):
|
||||
files.append(child_path)
|
||||
continue
|
||||
elif(os.path.isdir(child_path)):
|
||||
filter(child_path, extension)
|
||||
except Exception as e:
|
||||
print('遍历文件错误')
|
||||
raise e
|
||||
|
||||
filter(folder_path, file_extension)
|
||||
|
||||
return files
|
||||
|
||||
|
||||
def unZip(zip_file:str, extractall_path:str):
|
||||
"""解压缩zip文件
|
||||
|
||||
Args:
|
||||
zip_file (str): zip文件路径
|
||||
extractall_path (str): 解压路径
|
||||
"""
|
||||
try:
|
||||
if(zipfile.is_zipfile(zip_file)):
|
||||
zin = zipfile.ZipFile(zip_file, 'r') # 以只读方式打开压缩包
|
||||
zin.extractall(path=extractall_path)
|
||||
zin.close()
|
||||
except Exception as e:
|
||||
print('解压失败')
|
||||
raise e
|
||||
|
||||
|
||||
def zipDir(dirpath:str, outFullName:str):
|
||||
"""
|
||||
压缩指定文件夹
|
||||
:param dirpath: 目标文件夹路径
|
||||
:param outFullName: 压缩文件保存路径+xxxx.zip
|
||||
:return: 无
|
||||
"""
|
||||
zip = zipfile.ZipFile(outFullName, "w", zipfile.ZIP_DEFLATED)
|
||||
for path, dirnames, filenames in os.walk(dirpath):
|
||||
# 去掉目标跟路径,只对目标文件夹下边的文件及文件夹进行压缩
|
||||
fpath = path.replace(dirpath, '')
|
||||
|
||||
for filename in filenames:
|
||||
zip.write(os.path.join(path, filename), os.path.join(fpath, filename))
|
||||
zip.close()
|
||||
|
||||
def mkdir(dirpath:str):
|
||||
try:
|
||||
if( not os.path.exists(dirpath)):
|
||||
os.makedirs(dirpath)
|
||||
except Exception as e:
|
||||
print('创建缓存文件错误')
|
||||
Reference in New Issue
Block a user