mirror of
https://github.com/wtc86939209/WeChatMsg110.git
synced 2026-05-19 19:00:39 +08:00
@@ -13,4 +13,5 @@ app/DataBase/Msg/*
|
||||
*.db
|
||||
*.pyc
|
||||
*.log
|
||||
*.spec
|
||||
test*
|
||||
Generated
+128
-95
@@ -4,15 +4,19 @@
|
||||
<option name="autoReloadType" value="SELECTIVE" />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="84e65474-7da9-466d-baf3-cc88dde3ffdd" name="变更" comment="更新wx选择的路径">
|
||||
<change afterPath="$PROJECT_DIR$/app/util/path.py" afterDir="false" />
|
||||
<list default="true" id="84e65474-7da9-466d-baf3-cc88dde3ffdd" name="变更" comment="优化启动过程">
|
||||
<change afterPath="$PROJECT_DIR$/requirements_decrypt.txt" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.gitignore" beforeDir="false" afterPath="$PROJECT_DIR$/.gitignore" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/DataBase/hard_link.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/DataBase/hard_link.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/components/bubble_message.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/components/bubble_message.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/ui_pc/Icon.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/Icon.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/ui_pc/chat/chat_info.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/chat/chat_info.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/config.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/config.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/decrypt/get_wx_info.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/decrypt/get_wx_info.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/log/logger.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/log/logger.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/ui_pc/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/__init__.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/ui_pc/mainview.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/mainview.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/util/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/util/__init__.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/ui_pc/tool/__init__.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/tool/__init__.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/ui_pc/tool/pc_decrypt/decryptUi.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/tool/pc_decrypt/decryptUi.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/app/ui_pc/tool/pc_decrypt/pc_decrypt.py" beforeDir="false" afterPath="$PROJECT_DIR$/app/ui_pc/tool/pc_decrypt/pc_decrypt.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/decrypt_window.py" beforeDir="false" afterPath="$PROJECT_DIR$/decrypt_window.py" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@@ -23,8 +27,9 @@
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="Freeze Requirements File" />
|
||||
<option value="HTML File" />
|
||||
<option value="Python Script" />
|
||||
<option value="HTML File" />
|
||||
<option value="Blank Requirements File" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
@@ -45,10 +50,23 @@
|
||||
</map>
|
||||
</branch-storage>
|
||||
</excluded-from-favorite>
|
||||
<favorite-branches>
|
||||
<branch-storage>
|
||||
<map>
|
||||
<entry type="LOCAL">
|
||||
<value>
|
||||
<list>
|
||||
<branch-info repo="$PROJECT_DIR$" source="dev_zsk" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
</map>
|
||||
</branch-storage>
|
||||
</favorite-branches>
|
||||
<option name="PUSH_AUTO_UPDATE" value="true" />
|
||||
<option name="RECENT_BRANCH_BY_REPOSITORY">
|
||||
<map>
|
||||
<entry key="$PROJECT_DIR$" value="dev_zsk" />
|
||||
<entry key="$PROJECT_DIR$" value="master" />
|
||||
</map>
|
||||
</option>
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
@@ -69,12 +87,12 @@
|
||||
<option name="branches">
|
||||
<list>
|
||||
<RecentBranch>
|
||||
<option name="branchName" value="master" />
|
||||
<option name="lastUsedInstant" value="1700478623" />
|
||||
<option name="branchName" value="dev_zsk" />
|
||||
<option name="lastUsedInstant" value="1700571991" />
|
||||
</RecentBranch>
|
||||
<RecentBranch>
|
||||
<option name="branchName" value="dev_zsk" />
|
||||
<option name="lastUsedInstant" value="1700046130" />
|
||||
<option name="branchName" value="master" />
|
||||
<option name="lastUsedInstant" value="1700478623" />
|
||||
</RecentBranch>
|
||||
</list>
|
||||
</option>
|
||||
@@ -88,7 +106,7 @@
|
||||
<component name="GithubPullRequestsUISettings">
|
||||
<option name="selectedUrlAndAccountId">
|
||||
<UrlAndAccount>
|
||||
<option name="accountId" value="17f6adba-af7f-4dcb-aeb1-4ed3d744f378" />
|
||||
<option name="accountId" value="44b9bc65-44ba-4722-bca5-f2a7cbe5ba1f" />
|
||||
<option name="url" value="https://github.com/LC044/WeChatMsg.git" />
|
||||
</UrlAndAccount>
|
||||
</option>
|
||||
@@ -111,7 +129,7 @@
|
||||
"RunOnceActivity.OpenProjectViewOnStart": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"last_opened_file_path": "D:/Program Files/Python310/Scripts/pyuic5.exe",
|
||||
"settings.editor.selected.configurable": "preferences.pluginManager"
|
||||
"settings.editor.selected.configurable": "preferences.externalTools"
|
||||
}
|
||||
}]]></component>
|
||||
<component name="RecentsManager">
|
||||
@@ -121,7 +139,7 @@
|
||||
<recent name="D:\Project\PythonProject\WeChatMsg\app\Ui" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunManager" selected="Python.main_pc">
|
||||
<component name="RunManager" selected="Python.decrypt_window">
|
||||
<configuration name="decrypt_window" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="WeChatMsg" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
@@ -143,27 +161,6 @@
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="hard_link" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="WeChatMsg" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/app/DataBase" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/app/DataBase/hard_link.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="main" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="WeChatMsg" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
@@ -179,7 +176,7 @@
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/main.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="true" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
@@ -200,7 +197,7 @@
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/main_pc.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="true" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
@@ -227,7 +224,7 @@
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="test" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<configuration name="test (1)" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="WeChatMsg" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
@@ -248,13 +245,34 @@
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="test" type="PythonConfigurationType" factoryName="Python" temporary="true" nameIsGenerated="true">
|
||||
<module name="WeChatMsg" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/app/components" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/app/components/test.py" />
|
||||
<option name="PARAMETERS" value="" />
|
||||
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||
<option name="EMULATE_TERMINAL" value="false" />
|
||||
<option name="MODULE_MODE" value="false" />
|
||||
<option name="REDIRECT_INPUT" value="false" />
|
||||
<option name="INPUT_FILE" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Python.main_pc" />
|
||||
<item itemvalue="Python.test" />
|
||||
<item itemvalue="Python.hard_link" />
|
||||
<item itemvalue="Python.decrypt_window" />
|
||||
<item itemvalue="Python.main" />
|
||||
<item itemvalue="Python.main_pc" />
|
||||
<item itemvalue="Python.test (1)" />
|
||||
<item itemvalue="Python.test" />
|
||||
</list>
|
||||
</recent_temporary>
|
||||
</component>
|
||||
@@ -270,48 +288,6 @@
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1672848140146</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00036" summary="重构一些class,删除一些不必要的文件">
|
||||
<created>1698765961025</created>
|
||||
<option name="number" value="00036" />
|
||||
<option name="presentableId" value="LOCAL-00036" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1698765961025</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00037" summary="用stackedWidget实现导航栏">
|
||||
<created>1698850498765</created>
|
||||
<option name="number" value="00037" />
|
||||
<option name="presentableId" value="LOCAL-00037" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1698850498765</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00038" summary="修复部分bug">
|
||||
<created>1698853140384</created>
|
||||
<option name="number" value="00038" />
|
||||
<option name="presentableId" value="LOCAL-00038" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1698853140384</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00039" summary="替换chat里的contact">
|
||||
<created>1698940208580</created>
|
||||
<option name="number" value="00039" />
|
||||
<option name="presentableId" value="LOCAL-00039" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1698940208580</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00040" summary="增加中文路径提示">
|
||||
<created>1699025065814</created>
|
||||
<option name="number" value="00040" />
|
||||
<option name="presentableId" value="LOCAL-00040" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1699025065814</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00041" summary="update readme">
|
||||
<created>1699026207401</created>
|
||||
<option name="number" value="00041" />
|
||||
<option name="presentableId" value="LOCAL-00041" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1699026207401</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00042" summary="用stackWidget重写contactUI">
|
||||
<created>1699104087256</created>
|
||||
<option name="number" value="00042" />
|
||||
@@ -613,7 +589,49 @@
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1700490633275</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="85" />
|
||||
<task id="LOCAL-00085" summary="显示聊天图片">
|
||||
<created>1700492891759</created>
|
||||
<option name="number" value="00085" />
|
||||
<option name="presentableId" value="LOCAL-00085" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1700492891759</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00086" summary="支持显示聊天图片">
|
||||
<created>1700574536723</created>
|
||||
<option name="number" value="00086" />
|
||||
<option name="presentableId" value="LOCAL-00086" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1700574536724</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00087" summary="支持导出HTML">
|
||||
<created>1700576604990</created>
|
||||
<option name="number" value="00087" />
|
||||
<option name="presentableId" value="LOCAL-00087" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1700576604990</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00088" summary="修复HTML卡顿的问题?">
|
||||
<created>1700583772986</created>
|
||||
<option name="number" value="00088" />
|
||||
<option name="presentableId" value="LOCAL-00088" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1700583772986</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00089" summary="update readme">
|
||||
<created>1700583952342</created>
|
||||
<option name="number" value="00089" />
|
||||
<option name="presentableId" value="LOCAL-00089" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1700583952342</updated>
|
||||
</task>
|
||||
<task id="LOCAL-00090" summary="优化启动过程">
|
||||
<created>1700658736626</created>
|
||||
<option name="number" value="00090" />
|
||||
<option name="presentableId" value="LOCAL-00090" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1700658736626</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="91" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="UnknownFeatures">
|
||||
@@ -636,7 +654,7 @@
|
||||
<entry key="branch">
|
||||
<value>
|
||||
<list>
|
||||
<option value="master" />
|
||||
<option value="dev_zsk" />
|
||||
</list>
|
||||
</value>
|
||||
</entry>
|
||||
@@ -649,11 +667,6 @@
|
||||
</option>
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<MESSAGE value="删除多余的Word文件" />
|
||||
<MESSAGE value="修复无法查找wxid的bug" />
|
||||
<MESSAGE value="修改UI" />
|
||||
<MESSAGE value="新增联系人头像组件" />
|
||||
<MESSAGE value="头像支持显示二进制" />
|
||||
<MESSAGE value="显示联系人信息" />
|
||||
<MESSAGE value="修复db文件空格路径的bug" />
|
||||
<MESSAGE value="修复情感分析数值显示过长的bug" />
|
||||
@@ -667,14 +680,19 @@
|
||||
<MESSAGE value="聊天记录从后往前显示" />
|
||||
<MESSAGE value="聊天消息自适应" />
|
||||
<MESSAGE value="新版本更新" />
|
||||
<MESSAGE value="update readme" />
|
||||
<MESSAGE value="修复时间插入位置" />
|
||||
<MESSAGE value="修复第一次启动的显示问题" />
|
||||
<MESSAGE value="支持查找功能" />
|
||||
<MESSAGE value="修复修改wixd的bug" />
|
||||
<MESSAGE value="文字消息设置圆角" />
|
||||
<MESSAGE value="更新wx选择的路径" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="更新wx选择的路径" />
|
||||
<MESSAGE value="显示聊天图片" />
|
||||
<MESSAGE value="支持显示聊天图片" />
|
||||
<MESSAGE value="支持导出HTML" />
|
||||
<MESSAGE value="修复HTML卡顿的问题" />
|
||||
<MESSAGE value="update readme" />
|
||||
<MESSAGE value="优化启动过程" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="优化启动过程" />
|
||||
<option name="OPTIMIZE_IMPORTS_BEFORE_PROJECT_COMMIT" value="true" />
|
||||
<option name="REFORMAT_BEFORE_PROJECT_COMMIT" value="true" />
|
||||
</component>
|
||||
@@ -693,9 +711,24 @@
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
|
||||
<url>file://$PROJECT_DIR$/app/decrypt/decrypt.py</url>
|
||||
<line>103</line>
|
||||
<line>107</line>
|
||||
<option name="timeStamp" value="9" />
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
|
||||
<url>file://$PROJECT_DIR$/app/person.py</url>
|
||||
<line>103</line>
|
||||
<option name="timeStamp" value="10" />
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
|
||||
<url>file://$PROJECT_DIR$/app/person.py</url>
|
||||
<line>101</line>
|
||||
<option name="timeStamp" value="11" />
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
|
||||
<url>file://$PROJECT_DIR$/app/person.py</url>
|
||||
<line>102</line>
|
||||
<option name="timeStamp" value="12" />
|
||||
</line-breakpoint>
|
||||
</breakpoints>
|
||||
<default-breakpoints>
|
||||
<breakpoint type="python-exception">
|
||||
|
||||
+9
-5
@@ -49,10 +49,14 @@ def get_messages(username_):
|
||||
'''
|
||||
result = []
|
||||
for cur in cursor:
|
||||
cur.execute(sql, [username_])
|
||||
result_ = cur.fetchall()
|
||||
# print(len(result))
|
||||
result += result_
|
||||
try:
|
||||
lock.acquire(True)
|
||||
cur.execute(sql, [username_])
|
||||
result_ = cur.fetchall()
|
||||
# print(len(result))
|
||||
result += result_
|
||||
finally:
|
||||
lock.release()
|
||||
result.sort(key=lambda x: x[5])
|
||||
return result
|
||||
|
||||
@@ -63,7 +67,7 @@ def get_message_by_num(username_, local_id):
|
||||
from MSG
|
||||
where StrTalker = ? and localId < ?
|
||||
order by CreateTime desc
|
||||
limit 30
|
||||
limit 10
|
||||
'''
|
||||
result = []
|
||||
try:
|
||||
|
||||
@@ -5,6 +5,7 @@ from PyQt5.QtCore import pyqtSignal, QThread
|
||||
|
||||
from . import msg
|
||||
from ..log import log
|
||||
from ..person import MePC
|
||||
|
||||
if not os.path.exists('./data/聊天记录'):
|
||||
os.mkdir('./data/聊天记录')
|
||||
@@ -24,6 +25,7 @@ class Output(QThread):
|
||||
|
||||
def __init__(self, contact, parent=None, type_=DOCX):
|
||||
super().__init__(parent)
|
||||
self.last_timestamp = 0
|
||||
self.sec = 2 # 默认1000秒
|
||||
self.contact = contact
|
||||
self.ta_username = contact.wxid
|
||||
@@ -51,9 +53,682 @@ class Output(QThread):
|
||||
df.to_csv(filename, encoding='utf-8')
|
||||
self.okSignal.emit('ok')
|
||||
|
||||
def to_html(self):
|
||||
|
||||
self.okSignal.emit('ok')
|
||||
|
||||
def is_5_min(self, timestamp):
|
||||
if abs(timestamp - self.last_timestamp) > 300:
|
||||
self.last_timestamp = timestamp
|
||||
|
||||
return True
|
||||
return False
|
||||
|
||||
def progress(self, value):
|
||||
self.progressSignal.emit(value)
|
||||
|
||||
def run(self):
|
||||
if self.output_type == self.DOCX:
|
||||
return
|
||||
elif self.output_type == self.CSV:
|
||||
# print("线程导出csv")
|
||||
self.to_csv(self.ta_username, "path")
|
||||
elif self.output_type == self.HTML:
|
||||
# self.to_html()
|
||||
self.Child0 = ChildThread(self.contact, type_=ChildThread.HTML)
|
||||
self.Child0.progressSignal.connect(self.progress)
|
||||
self.Child0.rangeSignal.connect(self.rangeSignal)
|
||||
self.Child0.okSignal.connect(self.okSignal)
|
||||
self.Child0.run()
|
||||
# self.okSignal.emit(1)
|
||||
|
||||
|
||||
class ChildThread(QThread):
|
||||
"""
|
||||
子线程,用于导出部分聊天记录
|
||||
"""
|
||||
progressSignal = pyqtSignal(int)
|
||||
rangeSignal = pyqtSignal(int)
|
||||
okSignal = pyqtSignal(int)
|
||||
i = 1
|
||||
CSV = 0
|
||||
DOCX = 1
|
||||
HTML = 2
|
||||
|
||||
def __init__(self, contact, parent=None, type_=DOCX):
|
||||
super().__init__(parent)
|
||||
self.contact = contact
|
||||
self.last_timestamp = 0
|
||||
self.sec = 2 # 默认1000秒
|
||||
self.msg_id = 0
|
||||
self.output_type = type_
|
||||
|
||||
def is_5_min(self, timestamp):
|
||||
if abs(timestamp - self.last_timestamp) > 300:
|
||||
self.last_timestamp = timestamp
|
||||
|
||||
return True
|
||||
return False
|
||||
|
||||
def text(self, doc, isSend, message, status):
|
||||
return
|
||||
|
||||
def image(self, doc, isSend, Type, content, imgPath):
|
||||
return
|
||||
|
||||
def emoji(self, doc, isSend, content, imgPath):
|
||||
return
|
||||
|
||||
def wx_file(self, doc, isSend, content, status):
|
||||
return
|
||||
|
||||
def retract_message(self, doc, isSend, content, status):
|
||||
return
|
||||
|
||||
def reply(self, doc, isSend, content, status):
|
||||
return
|
||||
|
||||
def pat_a_pat(self, doc, isSend, content, status):
|
||||
return
|
||||
|
||||
def video(self, doc, isSend, content, status, img_path):
|
||||
return
|
||||
|
||||
def to_html(self):
|
||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
||||
if not os.path.exists(origin_docx_path):
|
||||
os.mkdir(origin_docx_path)
|
||||
messages = msg.get_messages(self.contact.wxid)
|
||||
filename = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}/{self.contact.remark}.html"
|
||||
f = open(filename, 'w', encoding='utf-8')
|
||||
html_head = '''
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Title</title>
|
||||
<style>
|
||||
|
||||
*{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
body{
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.container{
|
||||
height: 760px;
|
||||
width: 900px;
|
||||
border-radius: 4px;
|
||||
border: 0.5px solid #e0e0e0;
|
||||
background-color: #f5f5f5;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.content{
|
||||
width: calc(100% - 40px);
|
||||
padding: 20px;
|
||||
overflow-y: scroll;
|
||||
flex: 1;
|
||||
}
|
||||
.content:hover::-webkit-scrollbar-thumb{
|
||||
background:rgba(0,0,0,0.1);
|
||||
}
|
||||
.bubble{
|
||||
max-width: 400px;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
color: #000;
|
||||
word-wrap:break-word;
|
||||
word-break:normal;
|
||||
}
|
||||
.item-left .bubble{
|
||||
margin-left: 15px;
|
||||
background-color: #fff;
|
||||
}
|
||||
.item-left .bubble:before{
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10px solid transparent;
|
||||
border-top: 10px solid transparent;
|
||||
border-right: 10px solid #fff;
|
||||
border-bottom: 10px solid transparent;
|
||||
left: -20px;
|
||||
}
|
||||
.item-right .bubble{
|
||||
margin-right: 15px;
|
||||
background-color: #9eea6a;
|
||||
}
|
||||
.item-right .bubble:before{
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10px solid #9eea6a;
|
||||
border-top: 10px solid transparent;
|
||||
border-right: 10px solid transparent;
|
||||
border-bottom: 10px solid transparent;
|
||||
right: -20px;
|
||||
}
|
||||
.item{
|
||||
margin-top: 15px;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
.item.item-right{
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.item.item-center{
|
||||
justify-content: center;
|
||||
}
|
||||
.item.item-center span{
|
||||
font-size: 12px;
|
||||
padding: 2px 4px;
|
||||
color: #fff;
|
||||
background-color: #dadada;
|
||||
border-radius: 3px;
|
||||
-moz-user-select:none; /*火狐*/
|
||||
-webkit-user-select:none; /*webkit浏览器*/
|
||||
-ms-user-select:none; /*IE10*/
|
||||
-khtml-user-select:none; /*早期浏览器*/
|
||||
user-select:none;
|
||||
}
|
||||
|
||||
.avatar img{
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.input-area{
|
||||
border-top:0.5px solid #e0e0e0;
|
||||
height: 150px;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
background-color: #fff;
|
||||
}
|
||||
textarea{
|
||||
flex: 1;
|
||||
padding: 5px;
|
||||
font-size: 14px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
outline:none;
|
||||
resize:none;
|
||||
}
|
||||
.button-area{
|
||||
display: flex;
|
||||
height: 40px;
|
||||
margin-right: 10px;
|
||||
line-height: 40px;
|
||||
padding: 5px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.button-area button{
|
||||
width: 80px;
|
||||
border: none;
|
||||
outline: none;
|
||||
border-radius: 4px;
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* 设置滚动条的样式 */
|
||||
::-webkit-scrollbar {
|
||||
width:10px;
|
||||
}
|
||||
/* 滚动槽 */
|
||||
::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow:inset006pxrgba(0,0,0,0.3);
|
||||
border-radius:8px;
|
||||
}
|
||||
/* 滚动条滑块 */
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius:10px;
|
||||
background:rgba(0,0,0,0);
|
||||
-webkit-box-shadow:inset006pxrgba(0,0,0,0.5);
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container" id="container" onscroll="handleScroll()">
|
||||
<div class="content">
|
||||
'''
|
||||
f.write(html_head)
|
||||
MePC().avatar.save(os.path.join(origin_docx_path, 'myhead.png'))
|
||||
self.contact.avatar.save(os.path.join(origin_docx_path, 'tahead.png'))
|
||||
self.rangeSignal.emit(len(messages))
|
||||
for index, message in enumerate(messages):
|
||||
type_ = message[2]
|
||||
str_content = message[7]
|
||||
str_time = message[8]
|
||||
# print(type_, type(type_))
|
||||
is_send = message[4]
|
||||
avatar = MePC().avatar_path if is_send else self.contact.avatar_path
|
||||
timestamp = message[5]
|
||||
self.progressSignal.emit(index)
|
||||
if type_ == 1:
|
||||
if self.is_5_min(timestamp):
|
||||
f.write(
|
||||
f'''
|
||||
<div class="item item-center"><span>{str_time}</span></div>
|
||||
'''
|
||||
)
|
||||
if is_send:
|
||||
f.write(
|
||||
f'''
|
||||
<div class="item item-right">
|
||||
<div class="bubble bubble-right">{str_content}</div>
|
||||
<div class="avatar">
|
||||
<img src="myhead.png" />
|
||||
</div>
|
||||
</div>
|
||||
'''
|
||||
)
|
||||
else:
|
||||
f.write(
|
||||
f'''
|
||||
<div class="item item-left">
|
||||
<div class="avatar">
|
||||
<img src="tahead.png" />
|
||||
</div>
|
||||
<div class="bubble bubble-left">{str_content}
|
||||
</div>
|
||||
</div>
|
||||
'''
|
||||
)
|
||||
html_end = '''
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
const container = document.getElementById('container');
|
||||
const content = document.getElementById('content');
|
||||
|
||||
const totalItems = 1000;
|
||||
const itemsPerPage = 20;
|
||||
const itemHeight = 50;
|
||||
|
||||
function updateContent() {
|
||||
const scrollTop = container.scrollTop;
|
||||
const startIndex = Math.floor(scrollTop / itemHeight);
|
||||
const endIndex = Math.min(startIndex + itemsPerPage, totalItems);
|
||||
|
||||
// Remove existing items
|
||||
content.innerHTML = '';
|
||||
|
||||
// Add new items
|
||||
for (let i = startIndex; i < endIndex; i++) {
|
||||
const item = document.createElement('div');
|
||||
item.className = 'item';
|
||||
item.textContent = `Item ${i}`;
|
||||
content.appendChild(item);
|
||||
}
|
||||
|
||||
// Update container height to show correct scrollbar
|
||||
container.style.height = totalItems * itemHeight + 'px';
|
||||
}
|
||||
|
||||
function handleScroll() {
|
||||
updateContent();
|
||||
}
|
||||
|
||||
// Initial content rendering
|
||||
updateContent();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
f.write(html_end)
|
||||
f.close()
|
||||
self.okSignal.emit(1)
|
||||
|
||||
def to_html_(self):
|
||||
origin_docx_path = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}"
|
||||
if not os.path.exists(origin_docx_path):
|
||||
os.mkdir(origin_docx_path)
|
||||
messages = msg.get_messages(self.contact.wxid)
|
||||
filename = f"{os.path.abspath('.')}/data/聊天记录/{self.contact.remark}/{self.contact.remark}.html"
|
||||
f = open(filename, 'w', encoding='utf-8')
|
||||
html_head = '''
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Chat Records</title>
|
||||
<style>
|
||||
|
||||
*{
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
}
|
||||
body{
|
||||
height: 100vh;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.container{
|
||||
height: 760px;
|
||||
width: 900px;
|
||||
border-radius: 4px;
|
||||
border: 0.5px solid #e0e0e0;
|
||||
background-color: #f5f5f5;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
overflow: hidden;
|
||||
}
|
||||
.content{
|
||||
width: calc(100% - 40px);
|
||||
padding: 20px;
|
||||
overflow-y: scroll;
|
||||
flex: 1;
|
||||
}
|
||||
.content:hover::-webkit-scrollbar-thumb{
|
||||
background:rgba(0,0,0,0.1);
|
||||
}
|
||||
.bubble{
|
||||
max-width: 400px;
|
||||
padding: 10px;
|
||||
border-radius: 5px;
|
||||
position: relative;
|
||||
color: #000;
|
||||
word-wrap:break-word;
|
||||
word-break:normal;
|
||||
}
|
||||
.item-left .bubble{
|
||||
margin-left: 15px;
|
||||
background-color: #fff;
|
||||
}
|
||||
.item-left .bubble:before{
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10px solid transparent;
|
||||
border-top: 10px solid transparent;
|
||||
border-right: 10px solid #fff;
|
||||
border-bottom: 10px solid transparent;
|
||||
left: -20px;
|
||||
}
|
||||
.item-right .bubble{
|
||||
margin-right: 15px;
|
||||
background-color: #9eea6a;
|
||||
}
|
||||
.item-right .bubble:before{
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-left: 10px solid #9eea6a;
|
||||
border-top: 10px solid transparent;
|
||||
border-right: 10px solid transparent;
|
||||
border-bottom: 10px solid transparent;
|
||||
right: -20px;
|
||||
}
|
||||
.item{
|
||||
margin-top: 15px;
|
||||
display: flex;
|
||||
width: 100%;
|
||||
}
|
||||
.item.item-right{
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.item.item-center{
|
||||
justify-content: center;
|
||||
}
|
||||
.item.item-center span{
|
||||
font-size: 12px;
|
||||
padding: 2px 4px;
|
||||
color: #fff;
|
||||
background-color: #dadada;
|
||||
border-radius: 3px;
|
||||
-moz-user-select:none; /*火狐*/
|
||||
-webkit-user-select:none; /*webkit浏览器*/
|
||||
-ms-user-select:none; /*IE10*/
|
||||
-khtml-user-select:none; /*早期浏览器*/
|
||||
user-select:none;
|
||||
}
|
||||
|
||||
.avatar img{
|
||||
width: 42px;
|
||||
height: 42px;
|
||||
border-radius: 50%;
|
||||
}
|
||||
.input-area{
|
||||
border-top:0.5px solid #e0e0e0;
|
||||
height: 150px;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
background-color: #fff;
|
||||
}
|
||||
textarea{
|
||||
flex: 1;
|
||||
padding: 5px;
|
||||
font-size: 14px;
|
||||
border: none;
|
||||
cursor: pointer;
|
||||
overflow-y: auto;
|
||||
overflow-x: hidden;
|
||||
outline:none;
|
||||
resize:none;
|
||||
}
|
||||
.button-area{
|
||||
display: flex;
|
||||
height: 40px;
|
||||
margin-right: 10px;
|
||||
line-height: 40px;
|
||||
padding: 5px;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.button-area button{
|
||||
width: 80px;
|
||||
border: none;
|
||||
outline: none;
|
||||
border-radius: 4px;
|
||||
float: right;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* 设置滚动条的样式 */
|
||||
::-webkit-scrollbar {
|
||||
width:10px;
|
||||
}
|
||||
/* 滚动槽 */
|
||||
::-webkit-scrollbar-track {
|
||||
-webkit-box-shadow:inset006pxrgba(0,0,0,0.3);
|
||||
border-radius:8px;
|
||||
}
|
||||
/* 滚动条滑块 */
|
||||
::-webkit-scrollbar-thumb {
|
||||
border-radius:10px;
|
||||
background:rgba(0,0,0,0);
|
||||
-webkit-box-shadow:inset006pxrgba(0,0,0,0.5);
|
||||
}
|
||||
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="content" id="chat-container">
|
||||
<div class="item item-center"><span>昨天 12:35</span></div>
|
||||
<div class="item item-center"><span>你已添加了凡繁烦,现在可以开始聊天了。</span></div>
|
||||
<div class="item item-left">
|
||||
<div class="avatar">
|
||||
<img src="https://dss1.bdstatic.com/70cFvXSh_Q1YnxGkpoWK1HF6hhy/it/u=25668084,2889217189&fm=26&gp=0.jpg" />
|
||||
</div>
|
||||
<div class="bubble bubble-left">您好,我在武汉,你可以直接送过来吗,我有时间的话,可以自己过去拿<br/>!!!<br/>123
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="item item-right">
|
||||
<div class="bubble bubble-right">hello<br/>你好呀</div>
|
||||
<div class="avatar">
|
||||
<img src="https://ss3.bdstatic.com/70cFv8Sh_Q1YnxGkpoWK1HF6hhy/it/u=3313909130,2406410525&fm=15&gp=0.jpg" />
|
||||
</div>
|
||||
</div>
|
||||
<div class="item item-center">
|
||||
<span>昨天 13:15</span>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div></div>
|
||||
<div>
|
||||
<button onclick="prevPage()">上一页</button>
|
||||
<div id = "paginationInfo"></div>
|
||||
<button onclick="nextPage()">下一页</button>
|
||||
<div></div>
|
||||
<input type="number" id="gotoPageInput" placeholder="跳转到第几页">
|
||||
<button onclick="gotoPage()">跳转</button>
|
||||
</div>
|
||||
<script>
|
||||
const chatContainer = document.getElementById('chat-container');
|
||||
// Sample chat messages (replace this with your actual data)
|
||||
const chatMessages = [
|
||||
'''
|
||||
f.write(html_head)
|
||||
MePC().avatar.save(os.path.join(origin_docx_path, 'myhead.png'))
|
||||
self.contact.avatar.save(os.path.join(origin_docx_path, 'tahead.png'))
|
||||
self.rangeSignal.emit(len(messages))
|
||||
for index, message in enumerate(messages):
|
||||
type_ = message[2]
|
||||
str_content = message[7]
|
||||
str_time = message[8]
|
||||
# print(type_, type(type_))
|
||||
is_send = message[4]
|
||||
# avatar = MePC().avatar_path if is_send else self.contact.avatar_path
|
||||
# avatar = avatar.replace('\\', '\\\\')
|
||||
avatar = 'myhead.png' if is_send else 'tahead.png'
|
||||
timestamp = message[5]
|
||||
self.progressSignal.emit(index)
|
||||
str_content = str_content.replace('"', '\\"').replace('{', '\\{').replace('}', '\\}').replace('\n',
|
||||
'\\n').replace(
|
||||
"'", "\\'")
|
||||
if type_ == 1:
|
||||
if self.is_5_min(timestamp):
|
||||
f.write(
|
||||
f'''{{ type:0, text: '{str_time}',is_send:0,avatar_path:''}},'''
|
||||
)
|
||||
f.write(
|
||||
f'''{{ type:{type_}, text: '{str_content}',is_send:{is_send},avatar_path:'{avatar}'}},'''
|
||||
)
|
||||
html_end = '''
|
||||
];
|
||||
function renderMessages(messages) {
|
||||
for (const message of messages) {
|
||||
const messageElement = document.createElement('div');
|
||||
if (message.type == 1){
|
||||
if (message.is_send == 1){
|
||||
messageElement.className = "item item-right";
|
||||
messageElement.innerHTML = `<div class='bubble bubble-right'>${message.text}</div><div class='avatar'><img src="${message.avatar_path}" /></div>`
|
||||
}
|
||||
else if(message.is_send==0){
|
||||
messageElement.className = "item item-left";
|
||||
messageElement.innerHTML = `<div class='avatar'><img src="${message.avatar_path}" /></div><div class='bubble bubble-right'>${message.text}</div>`
|
||||
}
|
||||
}
|
||||
else if(message.type == 0){
|
||||
messageElement.className = "item item-center";
|
||||
messageElement.innerHTML = `<span>${message.text}</span>`
|
||||
}
|
||||
chatContainer.appendChild(messageElement);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
const itemsPerPage = 100; // 每页显示的元素个数
|
||||
let currentPage = 1; // 当前页
|
||||
|
||||
function renderPage(page) {
|
||||
const container = document.getElementById('chat-container');
|
||||
container.innerHTML = ''; // 清空容器
|
||||
|
||||
// 计算当前页应该显示的元素范围
|
||||
const startIndex = (page - 1) * itemsPerPage;
|
||||
const endIndex = startIndex + itemsPerPage;
|
||||
console.log(page);
|
||||
// 从数据列表中取出对应范围的元素并添加到容器中
|
||||
for (let i = startIndex; i < endIndex && i < chatMessages.length; i++) {
|
||||
const message = chatMessages[i];
|
||||
const messageElement = document.createElement('div');
|
||||
if (message.type == 1){
|
||||
if (message.is_send == 1){
|
||||
messageElement.className = "item item-right";
|
||||
messageElement.innerHTML = `<div class='bubble bubble-right'>${message.text}</div><div class='avatar'><img src="${message.avatar_path}" /></div>`
|
||||
}
|
||||
else if(message.is_send==0){
|
||||
messageElement.className = "item item-left";
|
||||
messageElement.innerHTML = `<div class='avatar'><img src="${message.avatar_path}" /></div><div class='bubble bubble-right'>${message.text}</div>`
|
||||
}
|
||||
}
|
||||
else if(message.type == 0){
|
||||
messageElement.className = "item item-center";
|
||||
messageElement.innerHTML = `<span>${message.text}</span>`
|
||||
}
|
||||
chatContainer.appendChild(messageElement);
|
||||
}
|
||||
updatePaginationInfo();
|
||||
}
|
||||
|
||||
function prevPage() {
|
||||
if (currentPage > 1) {
|
||||
currentPage--;
|
||||
renderPage(currentPage);
|
||||
}
|
||||
}
|
||||
|
||||
function nextPage() {
|
||||
const totalPages = Math.ceil(chatMessages.length / itemsPerPage);
|
||||
if (currentPage < totalPages) {
|
||||
currentPage++;
|
||||
renderPage(currentPage);
|
||||
}
|
||||
}
|
||||
function updatePaginationInfo() {
|
||||
const totalPages = Math.ceil(chatMessages.length / itemsPerPage);
|
||||
const paginationInfo = document.getElementById('paginationInfo');
|
||||
paginationInfo.textContent = `共 ${totalPages} 页,当前第 ${currentPage} 页`;
|
||||
}
|
||||
function gotoPage() {
|
||||
const totalPages = Math.ceil(chatMessages.length / itemsPerPage);
|
||||
const inputElement = document.getElementById('gotoPageInput');
|
||||
const targetPage = parseInt(inputElement.value);
|
||||
|
||||
if (targetPage >= 1 && targetPage <= totalPages) {
|
||||
currentPage = targetPage;
|
||||
renderPage(currentPage);
|
||||
} else {
|
||||
alert('请输入有效的页码');
|
||||
}
|
||||
}
|
||||
|
||||
// 初始化页面
|
||||
renderPage(currentPage);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
'''
|
||||
f.write(html_end)
|
||||
f.close()
|
||||
self.okSignal.emit(1)
|
||||
|
||||
def run(self):
|
||||
if self.output_type == self.DOCX:
|
||||
return
|
||||
elif self.output_type == self.CSV:
|
||||
return
|
||||
elif self.output_type == self.HTML:
|
||||
self.to_html_()
|
||||
|
||||
@@ -104,25 +104,35 @@ class OpenImageThread(QThread):
|
||||
|
||||
|
||||
class ImageMessage(QLabel):
|
||||
def __init__(self, image, image_link='', max_width=480, max_height=720, parent=None):
|
||||
def __init__(self, image, image_link='', max_width=480, max_height=240, parent=None):
|
||||
"""
|
||||
param:image 图像路径或者QPixmap对象
|
||||
param:image_link='' 点击图像打开的文件路径
|
||||
"""
|
||||
super().__init__(parent)
|
||||
self.image = QLabel(self)
|
||||
|
||||
self.max_width = max_width
|
||||
self.max_height = max_height
|
||||
if isinstance(image, str):
|
||||
self.setPixmap(QPixmap(image))
|
||||
pixmap = QPixmap(image)
|
||||
self.image_path = image
|
||||
elif isinstance(image, QPixmap):
|
||||
self.setPixmap(image)
|
||||
pixmap = image
|
||||
self.set_image(pixmap)
|
||||
if image_link:
|
||||
self.image_path = image_link
|
||||
self.setMaximumWidth(max_width)
|
||||
self.setMaximumHeight(max_height)
|
||||
self.setMaximumWidth(self.max_width)
|
||||
self.setMaximumHeight(self.max_height)
|
||||
# self.setScaledContents(True)
|
||||
|
||||
def set_image(self, pixmap):
|
||||
# 计算调整后的大小
|
||||
adjusted_width = min(pixmap.width(), self.max_width)
|
||||
adjusted_height = min(pixmap.height(), self.max_height)
|
||||
self.setPixmap(pixmap.scaled(adjusted_width, adjusted_height, Qt.KeepAspectRatio))
|
||||
# 调整QLabel的大小以适应图片的宽高,但不超过最大宽高
|
||||
self.setFixedSize(adjusted_width, adjusted_height)
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
if event.buttons() == Qt.LeftButton: # 左键按下
|
||||
print('打开图像', self.image_path)
|
||||
|
||||
+1
-1
@@ -3,6 +3,6 @@ contact = '474379264'
|
||||
description = [
|
||||
'1. 支持获取个人信息\n',
|
||||
'2. 支持显示聊天界面\n',
|
||||
'3. 支持导出scv格式的聊天记录\n',
|
||||
'3. 支持导出聊天记录\n * csv\n * html\n',
|
||||
'4. 查找联系人\n',
|
||||
]
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,252 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8"/>
|
||||
<script src="https://cdn.bootcss.com/jquery/1.10.2/jquery.min.js"></script>
|
||||
<title></title>
|
||||
<!--
|
||||
@time: 2018-08-04
|
||||
@version: 0.0.1
|
||||
@author: Mortal
|
||||
-->
|
||||
<style type="text/css">
|
||||
/*
|
||||
* 说明:
|
||||
* 标注为慎删的属性暂时认定可以删除,即在作者测试的环境下删除暂时没有影响,但不代表所有环境下删除都没有影响
|
||||
* 其他属性一概不可以删除
|
||||
*/
|
||||
|
||||
html,
|
||||
body {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
body,
|
||||
ul,
|
||||
li,
|
||||
a,
|
||||
p,
|
||||
div {
|
||||
/*慎删*/
|
||||
padding: 0px;
|
||||
margin: 0px;
|
||||
}
|
||||
|
||||
#wrap {
|
||||
overflow: hidden;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#main {
|
||||
top: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.page {
|
||||
/*谨删*/
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#pageUl {
|
||||
position: fixed;
|
||||
right: 10px;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</style>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!--
|
||||
每个全屏页面div的class为page,其中的图片的class为pageImg
|
||||
ul为右侧的导航栏
|
||||
pageUlLi和page的数目必须相等,修改数目时还应修改最下面js鼠标悬停的跳转代码
|
||||
-->
|
||||
<div id="wrap">
|
||||
<div id="main">
|
||||
<ul id="pageUl" type="circle">
|
||||
<li id="pageUlLi1" class="pageUlLi" style="color: red;"> </li>
|
||||
<li id="pageUlLi2" class="pageUlLi"> </li>
|
||||
<li id="pageUlLi3" class="pageUlLi"> </li>
|
||||
<li id="pageUlLi4" class="pageUlLi"> </li>
|
||||
<li id="pageUlLi5" class="pageUlLi"> </li>
|
||||
<li id="pageUlLi6" class="pageUlLi"> </li>
|
||||
<li id="pageUlLi7" class="pageUlLi"> </li>
|
||||
</ul>
|
||||
<div id="page1" class="page">
|
||||
<iframe src="0.html" frameborder="0" height="100%"
|
||||
width="100%"></iframe>
|
||||
</div>
|
||||
<div id="page2" class="page">
|
||||
<iframe src="1.html" frameborder="0" height="100%"
|
||||
width="100%"></iframe>
|
||||
</div>
|
||||
<div style="background-color: #8a6d3b" id="page3" class="page">
|
||||
<iframe src="2.html" frameborder="0" id="iframe0" height="100%"
|
||||
width="100%"></iframe>
|
||||
</div>
|
||||
<div style="background-color: #337ab7" id="page4" class="page">
|
||||
<iframe src="3.html" frameborder="0" id="iframe3" height="100%"
|
||||
width="100%"></iframe>
|
||||
</div>
|
||||
<div style="background-color: #337ab7" id="page5" class="page">
|
||||
<iframe src="4.html" frameborder="0" id="iframe4" height="100%"
|
||||
width="100%"></iframe>
|
||||
</div>
|
||||
<div style="background-color: #337ab7" id="page6" class="page">
|
||||
<iframe src="5.html" frameborder="0" id="iframe5" height="100%"
|
||||
width="100%"></iframe>
|
||||
</div>
|
||||
<div style="background-color: #337ab7" id="page7" class="page">
|
||||
<iframe src="6.html" frameborder="0" id="iframe6" height="100%"
|
||||
width="100%"></iframe>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
<script type="text/javascript">
|
||||
//改变窗口大小时调整图片大小
|
||||
window.onload = resizeImages;
|
||||
window.onresize = resizeImages;
|
||||
|
||||
function resizeImages() {
|
||||
$(function (e) {
|
||||
var screenWeight = document.documentElement.clientWidth;
|
||||
var screenHeight = document.documentElement.clientHeight;
|
||||
$("[name=pageImg]").css("width", screenWeight).css("height", screenHeight);
|
||||
$("#pageUl").css("bottom", screenHeight >> 1);
|
||||
});
|
||||
}
|
||||
|
||||
var index = 1;
|
||||
var curIndex = 1;
|
||||
var wrap = document.getElementById("wrap");
|
||||
var main = document.getElementById("main");
|
||||
var hei = document.body.clientHeight;
|
||||
wrap.style.height = hei + "px";
|
||||
var obj = document.getElementsByTagName("div");
|
||||
for (var i = 0; i < obj.length; i++) {
|
||||
if (obj[i].className == 'page') {
|
||||
obj[i].style.height = hei + "px";
|
||||
}
|
||||
}
|
||||
var pageNum = document.querySelectorAll(".page").length;
|
||||
//如果不加时间控制,滚动会过度灵敏,一次翻好几屏
|
||||
var startTime = 0, //翻屏起始时间
|
||||
endTime = 0,
|
||||
now = 0;
|
||||
//浏览器兼容
|
||||
if ((navigator.userAgent.toLowerCase().indexOf("firefox") != -1)) {
|
||||
document.addEventListener("DOMMouseScroll", scrollFun, false);
|
||||
} else if (document.addEventListener) {
|
||||
document.addEventListener("mousewheel", scrollFun, false);
|
||||
} else if (document.attachEvent) {
|
||||
document.attachEvent("onmousewheel", scrollFun);
|
||||
} else {
|
||||
document.onmousewheel = scrollFun;
|
||||
}
|
||||
|
||||
//滚动事件处理函数
|
||||
function scrollFun(event) {
|
||||
startTime = new Date().getTime();
|
||||
var delta = event.detail || (-event.wheelDelta);
|
||||
//mousewheel事件中的 “event.wheelDelta” 属性值:返回的如果是正值说明滚轮是向上滚动
|
||||
//DOMMouseScroll事件中的 “event.detail” 属性值:返回的如果是负值说明滚轮是向上滚动
|
||||
if ((endTime - startTime) < -1000) {
|
||||
if (delta > 0 && parseInt(main.offsetTop) > -(hei * (pageNum - 1))) {
|
||||
//向下滚动
|
||||
index++;
|
||||
toPage(index);
|
||||
}
|
||||
if (delta < 0 && parseInt(main.offsetTop) < 0) {
|
||||
//向上滚动
|
||||
index--;
|
||||
toPage(index);
|
||||
}
|
||||
endTime = new Date().getTime();
|
||||
} else {
|
||||
event.preventDefault();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function toPage(idx) {
|
||||
//jquery实现动画效果
|
||||
if(idx!=curIndex){
|
||||
index=idx
|
||||
var delta=idx - curIndex;
|
||||
now = now - delta * hei;
|
||||
$("#main").animate({
|
||||
top: (now + 'px')
|
||||
}, 500);
|
||||
curIndex = idx;
|
||||
//更改列表的选中项
|
||||
$(".pageUlLi").css("color", "black");
|
||||
$("#pageUlLi" + idx).css("color", "red");
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// //鼠标悬停翻页
|
||||
// document.getElementById("pageUlLi1").onmouseover = function () {
|
||||
// toPage(1);
|
||||
// }
|
||||
// document.getElementById("pageUlLi2").onmouseover = function () {
|
||||
// toPage(2);
|
||||
// }
|
||||
// document.getElementById("pageUlLi3").onmouseover = function () {
|
||||
// toPage(3);
|
||||
// }
|
||||
// document.getElementById("pageUlLi4").onmouseover = function () {
|
||||
// toPage(4);
|
||||
// }
|
||||
// document.getElementById("pageUlLi5").onmouseover = function () {
|
||||
// toPage(5);
|
||||
// }
|
||||
//鼠标点击翻页
|
||||
document.getElementById("pageUlLi1").onclick = function () {
|
||||
toPage(1);
|
||||
}
|
||||
document.getElementById("pageUlLi2").onclick = function () {
|
||||
toPage(2);
|
||||
}
|
||||
document.getElementById("pageUlLi3").onclick = function () {
|
||||
toPage(3);
|
||||
}
|
||||
document.getElementById("pageUlLi4").onclick = function () {
|
||||
toPage(4);
|
||||
}
|
||||
document.getElementById("pageUlLi5").onclick = function () {
|
||||
toPage(5);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
</html>
|
||||
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 7.5 KiB |
+15
-17
@@ -1,5 +1,5 @@
|
||||
|
||||
import os
|
||||
|
||||
# 图片字节头信息,
|
||||
# [0][1]为jpg头信息,
|
||||
# [2][3]为png头信息,
|
||||
@@ -21,7 +21,7 @@ def get_code(file_path):
|
||||
return -1, -1
|
||||
dat_file = open(file_path, "rb")
|
||||
dat_read = dat_file.read(2)
|
||||
print(dat_read)
|
||||
# print(dat_read)
|
||||
head_index = 0
|
||||
while head_index < len(pic_head):
|
||||
# 使用第一个头信息字节来计算加密码
|
||||
@@ -33,7 +33,7 @@ def get_code(file_path):
|
||||
dat_file.close()
|
||||
return head_index, code
|
||||
head_index = head_index + 1
|
||||
|
||||
dat_file.close()
|
||||
print("not jpg, png, gif")
|
||||
return -1, -1
|
||||
|
||||
@@ -49,26 +49,24 @@ def decode_dat(file_path, out_path):
|
||||
if decode_code == -1:
|
||||
return
|
||||
if file_type == 1:
|
||||
pic_name = file_path.split("\\")[-1][:-4] + ".jpg"
|
||||
pic_name = os.path.basename(file_path)[:-4] + ".jpg"
|
||||
elif file_type == 3:
|
||||
pic_name = file_path[:-4] + ".png"
|
||||
elif file_type == 5:
|
||||
pic_name = file_path[:-4] + ".gif"
|
||||
else:
|
||||
pic_name = file_path[:-4] + ".jpg"
|
||||
|
||||
dat_file = open(file_path, "rb")
|
||||
file_outpath = os.path.join(out_path, pic_name)
|
||||
print(pic_name)
|
||||
print(file_outpath)
|
||||
pic_write = open(file_outpath, "wb")
|
||||
for dat_data in dat_file:
|
||||
for dat_byte in dat_data:
|
||||
pic_data = dat_byte ^ decode_code
|
||||
pic_write.write(bytes([pic_data]))
|
||||
print(pic_name + "完成")
|
||||
dat_file.close()
|
||||
pic_write.close()
|
||||
if os.path.exists(file_outpath):
|
||||
return file_outpath
|
||||
with open(file_path, 'rb') as file_in:
|
||||
data = file_in.read()
|
||||
# 对数据进行异或加密/解密
|
||||
encrypted_data = bytes([byte ^ decode_code for byte in data])
|
||||
with open(file_outpath, 'wb') as file_out:
|
||||
file_out.write(encrypted_data)
|
||||
print(file_path, '->', file_outpath)
|
||||
return file_outpath
|
||||
|
||||
|
||||
def find_datfile(dir_path, out_path):
|
||||
@@ -88,4 +86,4 @@ if __name__ == "__main__":
|
||||
outpath = "D:\\test"
|
||||
if not os.path.exists(outpath):
|
||||
os.mkdir(outpath)
|
||||
find_datfile(path, outpath)
|
||||
find_datfile(path, outpath)
|
||||
|
||||
@@ -123,13 +123,25 @@ def read_info(version_list, is_logging=False):
|
||||
return result
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
def resource_path(relative_path):
|
||||
""" Get absolute path to resource, works for dev and for PyInstaller """
|
||||
base_path = getattr(sys, '_MEIPASS', os.path.dirname(os.path.abspath(__file__)))
|
||||
return os.path.join(base_path, relative_path)
|
||||
|
||||
|
||||
@log
|
||||
def get_info():
|
||||
VERSION_LIST_PATH = "app/decrypt/version_list.json"
|
||||
|
||||
with open(VERSION_LIST_PATH, "r", encoding="utf-8") as f:
|
||||
VERSION_LIST = json.load(f)
|
||||
|
||||
try:
|
||||
with open(VERSION_LIST_PATH, "r", encoding="utf-8") as f:
|
||||
VERSION_LIST = json.load(f)
|
||||
except:
|
||||
with open(resource_path(VERSION_LIST_PATH), "r", encoding="utf-8") as f:
|
||||
VERSION_LIST = json.load(f)
|
||||
result = read_info(VERSION_LIST, True) # 读取微信信息
|
||||
return result
|
||||
|
||||
|
||||
+7
-5
@@ -5,19 +5,21 @@ import traceback
|
||||
from functools import wraps
|
||||
|
||||
filename = time.strftime("%Y-%m-%d", time.localtime(time.time()))
|
||||
if not os.path.exists('./app/log/logs'):
|
||||
os.mkdir('./app/log/logs')
|
||||
logger = logging.getLogger('test')
|
||||
logger.setLevel(level=logging.DEBUG)
|
||||
formatter = logging.Formatter('%(asctime)s - %(filename)s[line:%(lineno)d] - %(levelname)s: %(message)s')
|
||||
file_handler = logging.FileHandler(f'./app/log/logs/{filename}-log.log')
|
||||
try:
|
||||
if not os.path.exists('./app/log/logs'):
|
||||
os.mkdir('./app/log/logs')
|
||||
file_handler = logging.FileHandler(f'./app/log/logs/{filename}-log.log')
|
||||
except:
|
||||
file_handler = logging.FileHandler(f'{filename}-log.log')
|
||||
|
||||
file_handler.setLevel(level=logging.INFO)
|
||||
file_handler.setFormatter(formatter)
|
||||
|
||||
stream_handler = logging.StreamHandler()
|
||||
stream_handler.setLevel(logging.DEBUG)
|
||||
stream_handler.setFormatter(formatter)
|
||||
|
||||
logger.addHandler(file_handler)
|
||||
logger.addHandler(stream_handler)
|
||||
|
||||
|
||||
@@ -55,6 +55,7 @@ def singleton(cls):
|
||||
class MePC:
|
||||
def __init__(self):
|
||||
self.avatar = QPixmap(Icon.Default_avatar_path)
|
||||
self.avatar_path = 'D:\Project\Python\WeChatMsg\\app\data\icons\default_avatar.svg'
|
||||
self.wxid = ''
|
||||
self.wx_dir = ''
|
||||
self.name = ''
|
||||
@@ -82,6 +83,7 @@ class ContactPC:
|
||||
self.smallHeadImgUrl = contact_info.get('smallHeadImgUrl')
|
||||
self.smallHeadImgBLOG = b''
|
||||
self.avatar = QPixmap()
|
||||
self.avatar_path = 'D:\Project\Python\WeChatMsg\\app\data\icons\default_avatar.svg'
|
||||
|
||||
def set_avatar(self, img_bytes):
|
||||
if not img_bytes:
|
||||
@@ -91,6 +93,7 @@ class ContactPC:
|
||||
self.avatar.loadFromData(img_bytes, format='PNG')
|
||||
else:
|
||||
self.avatar.loadFromData(img_bytes, format='jfif')
|
||||
|
||||
self.avatar.scaled(60, 60, Qt.IgnoreAspectRatio, Qt.SmoothTransformation)
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
from . import mainview
|
||||
|
||||
__all__ = ['mainview']
|
||||
|
||||
@@ -74,7 +74,6 @@ class ChatInfo(QWidget):
|
||||
def is_5_min(self, timestamp):
|
||||
if abs(timestamp - self.last_timestamp) > 300:
|
||||
self.last_timestamp = timestamp
|
||||
|
||||
return True
|
||||
return False
|
||||
|
||||
@@ -100,6 +99,7 @@ class ChatInfo(QWidget):
|
||||
)
|
||||
self.chat_window.add_message_item(bubble_message, 0)
|
||||
elif type_ == 3:
|
||||
# return
|
||||
if self.is_5_min(timestamp):
|
||||
time_message = Notice(self.last_str_time)
|
||||
self.last_str_time = str_time
|
||||
|
||||
@@ -114,12 +114,8 @@ class ContactInfo(QWidget, Ui_Form):
|
||||
self.outputThread = Output(self.contact, type_=Output.CSV)
|
||||
print('导出csv')
|
||||
elif self.sender() == self.toHtmlAct:
|
||||
print('功能暂未实现')
|
||||
QMessageBox.warning(self,
|
||||
"别急别急",
|
||||
"马上就实现该功能"
|
||||
)
|
||||
return
|
||||
self.outputThread = Output(self.contact, type_=Output.HTML)
|
||||
|
||||
self.outputThread.progressSignal.connect(self.output_progress)
|
||||
self.outputThread.rangeSignal.connect(self.set_progressBar_range)
|
||||
self.outputThread.okSignal.connect(self.hide_progress_bar)
|
||||
@@ -139,5 +135,6 @@ class ContactInfo(QWidget, Ui_Form):
|
||||
self.view_userinfo.progressBar.setProperty('value', value)
|
||||
|
||||
def set_progressBar_range(self, value):
|
||||
print('进度条范围', value)
|
||||
self.view_userinfo.progressBar.setVisible(True)
|
||||
self.view_userinfo.progressBar.setRange(0, value)
|
||||
|
||||
+39
-42
@@ -9,10 +9,9 @@
|
||||
"""
|
||||
import json
|
||||
import os.path
|
||||
from random import randint
|
||||
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import QPixmap
|
||||
from PyQt5.QtGui import QPixmap, QFont
|
||||
from PyQt5.QtWidgets import *
|
||||
|
||||
from app import config
|
||||
@@ -21,7 +20,7 @@ from app.Ui.Icon import Icon
|
||||
from . import mainwindow
|
||||
from .chat import ChatWindow
|
||||
from .contact import ContactWindow
|
||||
from .tool import ToolWindow
|
||||
from .tool.tool_window import ToolWindow
|
||||
from ..person import MePC
|
||||
|
||||
# 美化样式表
|
||||
@@ -63,7 +62,8 @@ HistoryPanel::item:hover {
|
||||
|
||||
|
||||
class MainWinController(QMainWindow, mainwindow.Ui_MainWindow):
|
||||
exitSignal = pyqtSignal()
|
||||
exitSignal = pyqtSignal(bool)
|
||||
okSignal = pyqtSignal(bool)
|
||||
|
||||
# username = ''
|
||||
def __init__(self, username, parent=None):
|
||||
@@ -75,8 +75,11 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow):
|
||||
self.resize(QSize(800, 600))
|
||||
self.action_desc.triggered.connect(self.about)
|
||||
self.load_data()
|
||||
self.init_ui()
|
||||
self.load_num = 0
|
||||
self.label = QLabel(self)
|
||||
|
||||
self.label.setGeometry((self.width() - 300) // 2, (self.height() - 100) // 2, 300, 100)
|
||||
self.label.setPixmap(QPixmap('./app/data/icons/loading.svg'))
|
||||
|
||||
def load_data(self):
|
||||
if os.path.exists('./app/data/info.json'):
|
||||
@@ -98,12 +101,8 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow):
|
||||
)
|
||||
|
||||
def init_ui(self):
|
||||
# self.movie = QMovie("./app/data/loading.gif")
|
||||
self.label = QLabel(self)
|
||||
self.label.setGeometry(0, 0, self.width(), self.height())
|
||||
self.label.setVisible(False)
|
||||
# self.label.setMovie(self.movie)
|
||||
# self.movie.start()
|
||||
self.listWidget.setVisible(False)
|
||||
self.stackedWidget.setVisible(False)
|
||||
self.listWidget.currentRowChanged.connect(self.setCurrentIndex)
|
||||
tool_item = QListWidgetItem(Icon.MyInfo_Icon, '工具', self.listWidget)
|
||||
chat_item = QListWidgetItem(Icon.Chat_Icon, '聊天', self.listWidget)
|
||||
@@ -116,24 +115,18 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow):
|
||||
self.stackedWidget.addWidget(tool_window)
|
||||
self.listWidget.setCurrentRow(0)
|
||||
self.stackedWidget.setCurrentIndex(0)
|
||||
chat_window = ChatWindow()
|
||||
self.chat_window = ChatWindow()
|
||||
# chat_window = QWidget()
|
||||
self.stackedWidget.addWidget(chat_window)
|
||||
contact_window = ContactWindow()
|
||||
self.stackedWidget.addWidget(contact_window)
|
||||
label = QLabel('我是页面')
|
||||
self.stackedWidget.addWidget(self.chat_window)
|
||||
self.contact_window = ContactWindow()
|
||||
self.stackedWidget.addWidget(self.contact_window)
|
||||
label = QLabel('该功能暂不支持哦')
|
||||
label.setFont(QFont("微软雅黑", 50))
|
||||
label.setAlignment(Qt.AlignCenter)
|
||||
# 设置label的背景颜色(这里随机)
|
||||
# 这里加了一个margin边距(方便区分QStackedWidget和QLabel的颜色)
|
||||
label.setStyleSheet('background: rgb(%d, %d, %d);margin: 50px;' % (
|
||||
randint(0, 255), randint(0, 255), randint(0, 255)))
|
||||
self.stackedWidget.addWidget(label)
|
||||
tool_window.load_finish_signal.connect(self.loading)
|
||||
contact_window.load_finish_signal.connect(self.loading)
|
||||
# chat_window.load_finish_signal.connect(self.loading)
|
||||
# self.load_window_thread = LoadWindowThread(self.stackedWidget)
|
||||
# self.load_window_thread.okSignal.connect(self.stop_loading)
|
||||
# self.load_window_thread.start()
|
||||
self.contact_window.load_finish_signal.connect(self.loading)
|
||||
self.chat_window.load_finish_signal.connect(self.loading)
|
||||
|
||||
def setCurrentIndex(self, row):
|
||||
self.stackedWidget.setCurrentIndex(row)
|
||||
@@ -170,11 +163,15 @@ class MainWinController(QMainWindow, mainwindow.Ui_MainWindow):
|
||||
|
||||
def loading(self, a0):
|
||||
self.load_num += 1
|
||||
self.label.setVisible(False)
|
||||
# print('加载一个了')
|
||||
# self.label.setVisible(False)
|
||||
print('加载一个了')
|
||||
if self.load_num == 2:
|
||||
# print('ok了')
|
||||
self.label.setVisible(False)
|
||||
print('ok了')
|
||||
self.label.clear()
|
||||
self.label.hide()
|
||||
self.okSignal.emit(True)
|
||||
self.listWidget.setVisible(True)
|
||||
self.stackedWidget.setVisible(True)
|
||||
|
||||
def about(self):
|
||||
"""
|
||||
@@ -198,20 +195,20 @@ class LoadWindowThread(QThread):
|
||||
windowSignal = pyqtSignal(QWidget)
|
||||
okSignal = pyqtSignal(bool)
|
||||
|
||||
def __init__(self, stackedWidget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.stackedWidget = stackedWidget
|
||||
self.num = 0
|
||||
|
||||
def loading(self):
|
||||
self.num += 1
|
||||
print('加载一个了')
|
||||
if self.num == 2:
|
||||
self.okSignal.emit(True)
|
||||
|
||||
def run(self):
|
||||
chat_window = ChatWindow()
|
||||
self.stackedWidget.addWidget(chat_window)
|
||||
contact_window = ContactWindow()
|
||||
self.stackedWidget.addWidget(contact_window)
|
||||
label = QLabel('我是页面')
|
||||
label.setAlignment(Qt.AlignCenter)
|
||||
# 设置label的背景颜色(这里随机)
|
||||
# 这里加了一个margin边距(方便区分QStackedWidget和QLabel的颜色)
|
||||
label.setStyleSheet('background: rgb(%d, %d, %d);margin: 50px;' % (
|
||||
randint(0, 255), randint(0, 255), randint(0, 255)))
|
||||
self.stackedWidget.addWidget(label)
|
||||
self.chat_window = ChatWindow()
|
||||
self.contact_window = ContactWindow()
|
||||
self.contact_window.load_finish_signal.connect(self.loading)
|
||||
self.chat_window.load_finish_signal.connect(self.loading)
|
||||
print('加载完成')
|
||||
self.okSignal.emit(True)
|
||||
|
||||
@@ -1,3 +1 @@
|
||||
from .tool_window import ToolWindow
|
||||
|
||||
__all__ = ['ToolWindow']
|
||||
|
||||
@@ -1,4 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from PyQt5.QtCore import Qt, QSize, QCoreApplication, QMetaObject
|
||||
from PyQt5.QtGui import QFont
|
||||
from PyQt5.QtWidgets import QHBoxLayout, QVBoxLayout, QSpacerItem, QSizePolicy, QLabel, QGridLayout, QPushButton, \
|
||||
QCheckBox, QLineEdit, QProgressBar
|
||||
|
||||
|
||||
# Form implementation generated from reading ui file 'decryptUi.ui'
|
||||
#
|
||||
@@ -8,49 +13,46 @@
|
||||
# run again. Do not edit this file unless you know what you are doing.
|
||||
|
||||
|
||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||
|
||||
|
||||
class Ui_Dialog(object):
|
||||
def setupUi(self, Dialog):
|
||||
Dialog.setObjectName("Dialog")
|
||||
Dialog.resize(611, 519)
|
||||
font = QtGui.QFont()
|
||||
font = QFont()
|
||||
font.setFamily("微软雅黑")
|
||||
Dialog.setFont(font)
|
||||
Dialog.setLayoutDirection(QtCore.Qt.LeftToRight)
|
||||
self.horizontalLayout_4 = QtWidgets.QHBoxLayout(Dialog)
|
||||
Dialog.setLayoutDirection(Qt.LeftToRight)
|
||||
self.horizontalLayout_4 = QHBoxLayout(Dialog)
|
||||
self.horizontalLayout_4.setObjectName("horizontalLayout_4")
|
||||
self.verticalLayout_2 = QtWidgets.QVBoxLayout()
|
||||
self.verticalLayout_2 = QVBoxLayout()
|
||||
self.verticalLayout_2.setObjectName("verticalLayout_2")
|
||||
spacerItem = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
spacerItem = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
|
||||
self.verticalLayout_2.addItem(spacerItem)
|
||||
self.horizontalLayout_3 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_3 = QHBoxLayout()
|
||||
self.horizontalLayout_3.setObjectName("horizontalLayout_3")
|
||||
spacerItem1 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
spacerItem1 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
||||
self.horizontalLayout_3.addItem(spacerItem1)
|
||||
self.verticalLayout = QtWidgets.QVBoxLayout()
|
||||
self.verticalLayout = QVBoxLayout()
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.label_3 = QtWidgets.QLabel(Dialog)
|
||||
font = QtGui.QFont()
|
||||
self.label_3 = QLabel(Dialog)
|
||||
font = QFont()
|
||||
font.setFamily("一纸情书")
|
||||
font.setPointSize(20)
|
||||
self.label_3.setFont(font)
|
||||
self.label_3.setAlignment(QtCore.Qt.AlignCenter)
|
||||
self.label_3.setAlignment(Qt.AlignCenter)
|
||||
self.label_3.setObjectName("label_3")
|
||||
self.verticalLayout.addWidget(self.label_3)
|
||||
self.gridLayout_2 = QtWidgets.QGridLayout()
|
||||
self.gridLayout_2 = QGridLayout()
|
||||
self.gridLayout_2.setObjectName("gridLayout_2")
|
||||
self.gridLayout = QtWidgets.QGridLayout()
|
||||
self.gridLayout = QGridLayout()
|
||||
self.gridLayout.setObjectName("gridLayout")
|
||||
self.label_phone = QtWidgets.QLabel(Dialog)
|
||||
self.label_phone = QLabel(Dialog)
|
||||
self.label_phone.setText("")
|
||||
self.label_phone.setObjectName("label_phone")
|
||||
self.gridLayout.addWidget(self.label_phone, 2, 1, 1, 1)
|
||||
self.label_7 = QtWidgets.QLabel(Dialog)
|
||||
self.label_7 = QLabel(Dialog)
|
||||
self.label_7.setObjectName("label_7")
|
||||
self.gridLayout.addWidget(self.label_7, 1, 0, 1, 1)
|
||||
self.lineEdit = QtWidgets.QLineEdit(Dialog)
|
||||
self.lineEdit = QLineEdit(Dialog)
|
||||
self.lineEdit.setStyleSheet("background:transparent;\n"
|
||||
"\n"
|
||||
" border-radius:5px;\n"
|
||||
@@ -65,43 +67,43 @@ class Ui_Dialog(object):
|
||||
self.lineEdit.setFrame(False)
|
||||
self.lineEdit.setObjectName("lineEdit")
|
||||
self.gridLayout.addWidget(self.lineEdit, 4, 1, 1, 1)
|
||||
self.label_5 = QtWidgets.QLabel(Dialog)
|
||||
self.label_5 = QLabel(Dialog)
|
||||
self.label_5.setObjectName("label_5")
|
||||
self.gridLayout.addWidget(self.label_5, 3, 0, 1, 1)
|
||||
self.label_6 = QtWidgets.QLabel(Dialog)
|
||||
self.label_6 = QLabel(Dialog)
|
||||
self.label_6.setObjectName("label_6")
|
||||
self.gridLayout.addWidget(self.label_6, 5, 0, 1, 1)
|
||||
self.label_key = QtWidgets.QLabel(Dialog)
|
||||
self.label_key.setMaximumSize(QtCore.QSize(400, 16777215))
|
||||
self.label_key = QLabel(Dialog)
|
||||
self.label_key.setMaximumSize(QSize(400, 16777215))
|
||||
self.label_key.setText("")
|
||||
self.label_key.setObjectName("label_key")
|
||||
self.gridLayout.addWidget(self.label_key, 5, 1, 1, 1)
|
||||
self.label = QtWidgets.QLabel(Dialog)
|
||||
self.label = QLabel(Dialog)
|
||||
self.label.setObjectName("label")
|
||||
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
|
||||
self.label_2 = QtWidgets.QLabel(Dialog)
|
||||
self.label_2 = QLabel(Dialog)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
|
||||
self.label_pid = QtWidgets.QLabel(Dialog)
|
||||
self.label_pid = QLabel(Dialog)
|
||||
self.label_pid.setText("")
|
||||
self.label_pid.setObjectName("label_pid")
|
||||
self.gridLayout.addWidget(self.label_pid, 0, 1, 1, 1)
|
||||
self.label_name = QtWidgets.QLabel(Dialog)
|
||||
self.label_name = QLabel(Dialog)
|
||||
self.label_name.setText("")
|
||||
self.label_name.setObjectName("label_name")
|
||||
self.gridLayout.addWidget(self.label_name, 3, 1, 1, 1)
|
||||
self.label_4 = QtWidgets.QLabel(Dialog)
|
||||
self.label_4 = QLabel(Dialog)
|
||||
self.label_4.setObjectName("label_4")
|
||||
self.gridLayout.addWidget(self.label_4, 4, 0, 1, 1)
|
||||
self.label_version = QtWidgets.QLabel(Dialog)
|
||||
self.label_version = QLabel(Dialog)
|
||||
self.label_version.setText("")
|
||||
self.label_version.setObjectName("label_version")
|
||||
self.gridLayout.addWidget(self.label_version, 1, 1, 1, 1)
|
||||
self.label_8 = QtWidgets.QLabel(Dialog)
|
||||
self.label_8 = QLabel(Dialog)
|
||||
self.label_8.setObjectName("label_8")
|
||||
self.gridLayout.addWidget(self.label_8, 6, 0, 1, 1)
|
||||
self.label_db_dir = QtWidgets.QLabel(Dialog)
|
||||
self.label_db_dir.setMaximumSize(QtCore.QSize(400, 300))
|
||||
self.label_db_dir = QLabel(Dialog)
|
||||
self.label_db_dir.setMaximumSize(QSize(400, 300))
|
||||
self.label_db_dir.setText("")
|
||||
self.label_db_dir.setObjectName("label_db_dir")
|
||||
self.gridLayout.addWidget(self.label_db_dir, 6, 1, 1, 1)
|
||||
@@ -109,58 +111,58 @@ class Ui_Dialog(object):
|
||||
self.gridLayout.setColumnStretch(0, 1)
|
||||
self.gridLayout.setColumnStretch(1, 10)
|
||||
self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 2, 1)
|
||||
self.btn_getinfo = QtWidgets.QPushButton(Dialog)
|
||||
self.btn_getinfo.setMinimumSize(QtCore.QSize(0, 60))
|
||||
self.btn_getinfo = QPushButton(Dialog)
|
||||
self.btn_getinfo.setMinimumSize(QSize(0, 60))
|
||||
self.btn_getinfo.setObjectName("btn_getinfo")
|
||||
self.gridLayout_2.addWidget(self.btn_getinfo, 0, 1, 1, 1)
|
||||
self.checkBox = QtWidgets.QCheckBox(Dialog)
|
||||
self.checkBox = QCheckBox(Dialog)
|
||||
self.checkBox.setText("")
|
||||
self.checkBox.setObjectName("checkBox")
|
||||
self.gridLayout_2.addWidget(self.checkBox, 0, 2, 1, 1)
|
||||
self.btn_db_dir = QtWidgets.QPushButton(Dialog)
|
||||
self.btn_db_dir.setMinimumSize(QtCore.QSize(0, 60))
|
||||
self.btn_db_dir = QPushButton(Dialog)
|
||||
self.btn_db_dir.setMinimumSize(QSize(0, 60))
|
||||
self.btn_db_dir.setObjectName("btn_db_dir")
|
||||
self.gridLayout_2.addWidget(self.btn_db_dir, 1, 1, 1, 1)
|
||||
self.checkBox_2 = QtWidgets.QCheckBox(Dialog)
|
||||
self.checkBox_2 = QCheckBox(Dialog)
|
||||
self.checkBox_2.setText("")
|
||||
self.checkBox_2.setObjectName("checkBox_2")
|
||||
self.gridLayout_2.addWidget(self.checkBox_2, 1, 2, 1, 1)
|
||||
self.verticalLayout.addLayout(self.gridLayout_2)
|
||||
self.horizontalLayout_2 = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout_2 = QHBoxLayout()
|
||||
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||
spacerItem2 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
spacerItem2 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
||||
self.horizontalLayout_2.addItem(spacerItem2)
|
||||
self.pushButton_3 = QtWidgets.QPushButton(Dialog)
|
||||
self.pushButton_3.setMinimumSize(QtCore.QSize(0, 60))
|
||||
self.pushButton_3.setMaximumSize(QtCore.QSize(100, 16777215))
|
||||
self.pushButton_3 = QPushButton(Dialog)
|
||||
self.pushButton_3.setMinimumSize(QSize(0, 60))
|
||||
self.pushButton_3.setMaximumSize(QSize(100, 16777215))
|
||||
self.pushButton_3.setObjectName("pushButton_3")
|
||||
self.horizontalLayout_2.addWidget(self.pushButton_3)
|
||||
spacerItem3 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
spacerItem3 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
||||
self.horizontalLayout_2.addItem(spacerItem3)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout_2)
|
||||
self.horizontalLayout = QtWidgets.QHBoxLayout()
|
||||
self.horizontalLayout = QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.label_ready = QtWidgets.QLabel(Dialog)
|
||||
self.label_ready = QLabel(Dialog)
|
||||
self.label_ready.setObjectName("label_ready")
|
||||
self.horizontalLayout.addWidget(self.label_ready)
|
||||
self.progressBar = QtWidgets.QProgressBar(Dialog)
|
||||
self.progressBar = QProgressBar(Dialog)
|
||||
self.progressBar.setProperty("value", 50)
|
||||
self.progressBar.setObjectName("progressBar")
|
||||
self.horizontalLayout.addWidget(self.progressBar)
|
||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||
self.horizontalLayout_3.addLayout(self.verticalLayout)
|
||||
spacerItem4 = QtWidgets.QSpacerItem(40, 20, QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Minimum)
|
||||
spacerItem4 = QSpacerItem(40, 20, QSizePolicy.Expanding, QSizePolicy.Minimum)
|
||||
self.horizontalLayout_3.addItem(spacerItem4)
|
||||
self.verticalLayout_2.addLayout(self.horizontalLayout_3)
|
||||
spacerItem5 = QtWidgets.QSpacerItem(20, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
|
||||
spacerItem5 = QSpacerItem(20, 40, QSizePolicy.Minimum, QSizePolicy.Expanding)
|
||||
self.verticalLayout_2.addItem(spacerItem5)
|
||||
self.horizontalLayout_4.addLayout(self.verticalLayout_2)
|
||||
|
||||
self.retranslateUi(Dialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(Dialog)
|
||||
QMetaObject.connectSlotsByName(Dialog)
|
||||
|
||||
def retranslateUi(self, Dialog):
|
||||
_translate = QtCore.QCoreApplication.translate
|
||||
_translate = QCoreApplication.translate
|
||||
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
|
||||
self.label_3.setText(_translate("Dialog", "解密数据库"))
|
||||
self.label_7.setText(_translate("Dialog", "版本"))
|
||||
|
||||
@@ -3,10 +3,9 @@ import os.path
|
||||
import time
|
||||
import traceback
|
||||
|
||||
from PyQt5 import QtWidgets
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5.QtCore import pyqtSignal, QThread
|
||||
from PyQt5.QtGui import QIcon
|
||||
from PyQt5.QtWidgets import QWidget, QMessageBox, QFileDialog
|
||||
|
||||
from app.decrypt import get_wx_info, decrypt
|
||||
from app.log import logger
|
||||
@@ -21,7 +20,7 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog):
|
||||
super(DecryptControl, self).__init__(parent)
|
||||
self.setupUi(self)
|
||||
self.setWindowTitle('解密')
|
||||
self.setWindowIcon(QIcon('./app/data/icons/logo.svg'))
|
||||
self.setWindowIcon(QIcon(':/icons/logo.svg'))
|
||||
self.pushButton_3.clicked.connect(self.decrypt)
|
||||
self.btn_getinfo.clicked.connect(self.get_info)
|
||||
self.btn_db_dir.clicked.connect(self.select_db_dir)
|
||||
@@ -71,8 +70,8 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog):
|
||||
QMessageBox.information(self, "ok", f"wxid修改成功{self.info['wxid']}")
|
||||
|
||||
def select_db_dir(self):
|
||||
directory = QtWidgets.QFileDialog.getExistingDirectory(
|
||||
self, "选取微信安装目录——能看到All Users文件夹",
|
||||
directory = QFileDialog.getExistingDirectory(
|
||||
self, "选取微信安装目录——能看到Msg文件夹",
|
||||
"C:/") # 起始路径
|
||||
db_dir = os.path.join(directory, 'Msg')
|
||||
if not os.path.exists(db_dir):
|
||||
@@ -136,8 +135,12 @@ class DecryptControl(QWidget, decryptUi.Ui_Dialog):
|
||||
'name': self.info['name'],
|
||||
'mobile': self.info['mobile']
|
||||
}
|
||||
with open('./app/data/info.json', 'w', encoding='utf-8') as f:
|
||||
f.write(json.dumps(dic))
|
||||
try:
|
||||
with open('./app/data/info.json', 'w', encoding='utf-8') as f:
|
||||
f.write(json.dumps(dic))
|
||||
except:
|
||||
with open('./info.json', 'w', encoding='utf-8') as f:
|
||||
f.write(json.dumps(dic))
|
||||
self.DecryptSignal.emit('ok')
|
||||
self.close()
|
||||
|
||||
@@ -159,8 +162,13 @@ class DecryptThread(QThread):
|
||||
def run(self):
|
||||
# data.decrypt(self.db_path, self.key)
|
||||
output_dir = 'app/DataBase/Msg'
|
||||
if not os.path.exists(output_dir):
|
||||
os.mkdir(output_dir)
|
||||
try:
|
||||
if not os.path.exists(output_dir):
|
||||
os.mkdir(output_dir)
|
||||
except:
|
||||
os.mkdir('app')
|
||||
os.mkdir('app/DataBase')
|
||||
os.mkdir('app/DataBase/Msg')
|
||||
tasks = []
|
||||
if os.path.exists(self.db_path):
|
||||
for root, dirs, files in os.walk(self.db_path):
|
||||
|
||||
+8
-2
@@ -1,11 +1,17 @@
|
||||
import os
|
||||
|
||||
from app.decrypt import dat2pic
|
||||
from app.person import MePC
|
||||
|
||||
if not os.path.exists('./data/image'):
|
||||
os.mkdir('./data/image')
|
||||
|
||||
|
||||
def get_abs_path(path):
|
||||
return os.path.join(os.getcwd(), 'app/data/icons/404.png')
|
||||
# return os.path.join(os.getcwd(), 'app/data/icons/404.png')
|
||||
if path:
|
||||
return os.path.join(MePC().wx_dir, path)
|
||||
# if os.path.exists(os.path.join())
|
||||
output_path = dat2pic.decode_dat(os.path.join(MePC().wx_dir, path), './data/image')
|
||||
return output_path
|
||||
else:
|
||||
return os.path.join(os.getcwd(), 'app/data/icons/404.png')
|
||||
|
||||
+2
-4
@@ -1,8 +1,7 @@
|
||||
import ctypes
|
||||
import sys
|
||||
|
||||
from PyQt5.QtGui import QIcon
|
||||
from PyQt5.QtWidgets import *
|
||||
from PyQt5.QtWidgets import QApplication, QMessageBox, QWidget
|
||||
|
||||
from app.ui_pc.tool.pc_decrypt import pc_decrypt
|
||||
|
||||
@@ -12,8 +11,7 @@ ctypes.windll.shell32.SetCurrentProcessExplicitAppUserModelID("WeChatReport")
|
||||
class ViewController(QWidget):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
self.setWindowTitle('解密')
|
||||
self.setWindowIcon(QIcon('./app/data/icons/logo.svg'))
|
||||
|
||||
self.viewMainWIn = None
|
||||
self.viewDecrypt = None
|
||||
|
||||
|
||||
+14
-6
@@ -2,7 +2,7 @@ import ctypes
|
||||
import sys
|
||||
import time
|
||||
|
||||
from PyQt5.QtGui import QIcon
|
||||
from PyQt5.QtGui import QIcon, QMovie
|
||||
from PyQt5.QtWidgets import *
|
||||
|
||||
from app.ui_pc import mainview
|
||||
@@ -16,8 +16,13 @@ class ViewController(QWidget):
|
||||
super().__init__()
|
||||
self.setWindowTitle('解密')
|
||||
self.setWindowIcon(QIcon('./app/data/icons/logo.svg'))
|
||||
self.viewMainWIn = None
|
||||
self.viewMainWIndow = None
|
||||
self.viewDecrypt = None
|
||||
# 创建加载动画
|
||||
loading_label = QLabel()
|
||||
movie = QMovie("./app/data/loading.gif") # 替换为你的加载动画文件路径
|
||||
loading_label.setMovie(movie)
|
||||
movie.start()
|
||||
|
||||
def loadPCDecryptView(self):
|
||||
"""
|
||||
@@ -36,14 +41,16 @@ class ViewController(QWidget):
|
||||
"""
|
||||
username = ''
|
||||
start = time.time()
|
||||
self.viewMainWIn = mainview.MainWinController(username=username)
|
||||
self.viewMainWIn.setWindowTitle("Chat")
|
||||
self.viewMainWIndow = mainview.MainWinController(username=username)
|
||||
self.viewMainWIndow.setWindowTitle("Chat")
|
||||
# print(username)
|
||||
self.viewMainWIn.username = username
|
||||
self.viewMainWIndow.username = username
|
||||
# self.viewMainWIn.exitSignal.connect(self.loadDecryptView) # 不需要回到登录界面可以省略
|
||||
self.viewMainWIn.show()
|
||||
|
||||
self.viewMainWIndow.show()
|
||||
end = time.time()
|
||||
print('ok', end - start)
|
||||
self.viewMainWIndow.init_ui()
|
||||
|
||||
def show_success(self):
|
||||
QMessageBox.about(self, "解密成功", "数据库文件存储在\napp/DataBase/Msg\n文件夹下")
|
||||
@@ -54,5 +61,6 @@ if __name__ == '__main__':
|
||||
view = ViewController()
|
||||
# view.loadPCDecryptView()
|
||||
view.loadMainWinView()
|
||||
# view.show()
|
||||
# view.show_success()
|
||||
sys.exit(app.exec_())
|
||||
|
||||
@@ -22,7 +22,10 @@
|
||||
- 安卓 or 苹果都可以哦
|
||||
- 破解💻PC端微信数据库
|
||||
- 还原微信聊天界面
|
||||
- 文本
|
||||
- 图片
|
||||
- 导出聊天记录
|
||||
- HTML(文本)
|
||||
- Word文档
|
||||
- CSV文档
|
||||
- 分析聊天数据,做成可视化年报
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
PyQt5
|
||||
psutil
|
||||
pycryptodomex
|
||||
pywin32
|
||||
pymem
|
||||
silk-python
|
||||
pyaudio
|
||||
fuzzywuzzy
|
||||
python-Levenshtein
|
||||
Reference in New Issue
Block a user