Skip to content

Commit

Permalink
Merge pull request #8 from Yiyiyimu/dev
Browse files Browse the repository at this point in the history
support new emoticon
  • Loading branch information
Yiyiyimu authored Jan 4, 2021
2 parents 038cbfb + 6f14e30 commit b42e18c
Show file tree
Hide file tree
Showing 407 changed files with 2,802 additions and 27 deletions.
24 changes: 14 additions & 10 deletions GUI.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,17 @@
def Enter():
dir, qq_self, qq = e1.get(), e2.get(), e3.get()
group = 1 if e4.get() == '私聊' else 2
emoji = 1 if e5.get() == '新' else 2
if (dir == "" or qq_self == "" or qq == ""):
info.set("信息不完整!")
return ()
info.set("开始导出")
try:
QQ_History.main(dir, qq_self, qq, group)
QQ_History.main(dir, qq_self, qq, group, emoji)
info.set("完成")
except Exception as e:
info.set(repr(e))
return ()
return ()


def SelectPath():
Expand All @@ -44,7 +46,7 @@ def url():

ttk.Label(root, text="*com.tencent.mobileqq:").grid(row=0, column=0, sticky="e")
e1 = ttk.Entry(root, textvariable=pathGet)
e1.grid(row=0, column=1)
e1.grid(row=0, column=1, columnspan=2, sticky="ew", pady=3)
ttk.Button(root, text="选择", command=SelectPath, width=5).grid(row=0, column=3)

ttk.Label(root, text="*自己QQ号:").grid(row=1, column=0, sticky="e")
Expand All @@ -61,11 +63,15 @@ def url():
e4.current(0)
e4.grid(row=3, column=1, columnspan=3, sticky="ew", pady=3)

root.grid_columnconfigure(2, weight=1)
ttk.Label(root, text="表情版本:").grid(row=4, column=0, sticky="e")
e5 = ttk.Combobox(root)
e5['values'] = ('新', '旧')
e5.current(0)
e5.grid(row=4, column=1, columnspan=3, sticky="ew", pady=3)

ttk.Button(root, text="确认", command=Enter).grid(row=4, column=1)
l1 = ttk.Label(root, textvariable=info)
l1.grid(row=4, column=1)
root.grid_columnconfigure(2, weight=1)
info.set("开始")
ttk.Button(root, textvariable=info, command=Enter).grid(row=5, column=1)

tmp = open("tmp.png", "wb+")
tmp.write(base64.b64decode(github_mark))
Expand All @@ -74,8 +80,6 @@ def url():
os.remove("tmp.png")

button_img = tk.Button(root, image=github, text='b', command=url, bd=0)
button_img.grid(row=6, rowspan=7, column=0, sticky="ws")
button_img.grid(row=5, rowspan=7, column=0, sticky="ws")

root.mainloop()

# pyinstaller -F -w -i icon.ico GUI.py
38 changes: 29 additions & 9 deletions QQ_History.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,23 @@
import time
import os
import traceback
import json


class QQoutput():
def __init__(self, dir, qq_self, qq, mode):
def __init__(self, dir, qq_self, qq, mode, emoji):
self.dir = dir
self.key = self.get_key() # 解密用的密钥
db = os.path.join(dir, "databases", qq_self + ".db")
self.c1 = sqlite3.connect(db).cursor()
db = os.path.join(dir, "databases", "slowtable_" + qq_self + ".db")
self.c2 = sqlite3.connect(db).cursor()

self.qq_self = qq_self
self.qq = qq
self.mode = mode
self.emoji = emoji

self.num_to_name = {}

def decrypt(self, data):
Expand All @@ -39,13 +43,19 @@ def decrypt(self, data):
return NULL

def add_emoji(self, msg):
emoji_map = self.map_new_emoji()
pos = msg.find('\x14')
while (pos != -1):
lastpos = pos
num = ord(msg[pos + 1])
index = emoji_map[str(num)]
if self.emoji == 1:
filename = "new/s" + index + ".png"
else:
filename = "old/" + index + ".gif"
msg = msg.replace(
msg[pos:pos + 2],
"<img src='./gif/" + str(num) + ".gif' alt=" + str(num) + ">")
"<img src='./emoticon/" + filename + "' alt=" + index + ">")
pos = msg.find('\x14')
if (pos == lastpos):
break
Expand Down Expand Up @@ -109,10 +119,7 @@ def fill_cursors(self, cmd):
cursors.append(self.c2.execute(cmd))
except:
pass
try:
cursors.append(self.c1.execute(cmd))
except:
pass
cursors.append(self.c1.execute(cmd))
return cursors

def output(self):
Expand Down Expand Up @@ -166,10 +173,23 @@ def unify_path(self):
raise OSError(
"File not found. Please report your directory layout.")

def map_new_emoji(self):
with open('./emoticon/face_config.json', encoding='utf-8') as f:
emojis = json.load(f)
new_emoji_map = {}

for e in emojis['sysface']:
if self.emoji == 1:
new_emoji_map[e["AQLid"]] = e["QSid"]
else:
if(len(e["EMCode"]) == 3):
new_emoji_map[e["AQLid"]] = str(int(e["EMCode"])-100)
return new_emoji_map


def main(dir, qq_self, qq, mode):
def main(dir, qq_self, qq, mode, emoji):
try:
q = QQoutput(dir, qq_self, qq, mode)
q = QQoutput(dir, qq_self, qq, mode, emoji)
q.output()
except Exception as e:
with open('log.txt', 'w') as f:
Expand All @@ -179,6 +199,6 @@ def main(dir, qq_self, qq, mode):
err_info = repr(e).split(":")[0] == "OperationalError('no such table"
print(traceback.format_exc())
if (err_info):
raise ValueError("QQ号/私聊群聊选择/db地址/错误")
raise ValueError("信息填入错误")
else:
raise BaseException("Error! See log.txt")
15 changes: 8 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
# QQ聊天记录导出

可执行文件[Github下载链接](https://github.com/Yiyiyimu/QQ_History_Backup/releases/download/v2.0/QQ_History_Backup-v2.0.zip)[百度网盘下载链接](https://pan.baidu.com/s/1nbJcP5RVc1ID1IFGsN1-yQw)(i4cv) ,可直接运行。
可执行文件[Github下载链接](https://github.com/Yiyiyimu/QQ_History_Backup/releases/download/v2.1/QQ_History_Backup-v2.1.zip)[百度网盘下载链接](https://pan.baidu.com/s/1zp3Cg724B-Z65eJjGuKHVQ)(86y6) ,可直接运行。

## 简介

本项目 fork 自大佬的项目[roadwide/qqmessageoutput](https://github.com/roadwide/qqmessageoutput) 在此非常感谢。因为改动较多,不再作为 fork 分支开发
作为国内最常用的聊天工具之一,QQ 为了用户留存度,默认聊天记录备份无法脱离 QQ 被独立打开。本项目 fork 自大佬的项目[roadwide/qqmessageoutput](https://github.com/roadwide/qqmessageoutput) 在此非常感谢。因为改动较多,不再作为 fork 分支开发

在之前版本的基础上完成了自动提取密钥解密的方法,自动填入备注/昵称,添加了QQ表情的一并导出,并制作了GUI方便使用
在之前版本的基础上完成了自动提取密钥解密的方法,自动填入备注/昵称,添加了QQ表情的一并导出,并制作了GUI方便使用

## 获取聊天记录文件夹方法

Expand All @@ -21,33 +21,34 @@ data\data\com.tencent.mobileqq
> 怎样导出手机中的QQ聊天记录? - 益新软件的回答 - 知乎
> https://www.zhihu.com/question/28574047/answer/964813560

## GUI使用方法

![GUI_image](./img/GUI.png)

com.tencent.mobileqq:选择备份后的相应文件夹,一般为`apps/com.tencent.mobileqq`
表情版本:默认为新版QQ表情。如果你的聊天记录来自很早以前(比如我),可以切换为旧版的表情

## 输出截图

为了方便离线查看,qq表情gif选择保存在本地,注意移动聊天记录的时候需要同时移动gif文件
为了方便离线查看,qq表情gif选择保存在本地,注意移动聊天记录的时候需要同时移动`emoticon`文件

![screenshot](./img/screenshot.png)

有bug的话提issue,记得附上log.txt里的内容

## v2.0 更新
## v2 更新
- 直接从 `files/kc` 提取明文的密钥,不用再手动输入或解密
- 支持群聊记录导出
- 支持 私聊/群聊 的 备注/昵称 自动填入
- 支持 slowtable 的直接整合
- 支持新版 QQ 表情

## TODO
- [x] support troop message output
- [x] use com.tencent.mobileqq/f/kc as key
- [x] decode friend/troop name, to use in result
- [x] auto-combine db and slow-table
- [ ] update to new qq emoji
- [x] update to new qq emoji
- [ ] add desensitization data to create e2e test
- [ ] add Makefile, to run build/test
- [ ] use pic in mobile folder, to better present result
Loading

0 comments on commit b42e18c

Please sign in to comment.