Repository: QQBackup/QQ-History-Backup
Branch: master
Commit: edc6653a7043
Files: 14
Total size: 133.5 KB
Directory structure:
gitextract_56qtarj0/
├── .gitignore
├── GUI.py
├── GUI.spec
├── LICENSE
├── QQ_History.py
├── README.md
├── emoticon/
│ └── face_config.json
├── icon.py
├── install.ps1
├── proto/
│ ├── RichMsg.proto
│ ├── RichMsg_pb2.py
│ ├── __init__.py
│ └── compile
└── requirements.txt
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
*.txt
!requirements.txt
*.db
*.html
*.db-shm
*.db-wal
*.zip
*.exe
*.spec
!GUI.spec
build/
dist/
__pycache__/
qq/
QQ*/
com.tencent.mobileqq/
chatimg/
output_*
test_qq_files/
================================================
FILE: GUI.py
================================================
import tkinter as tk
from tkinter import filedialog
import tkinter.ttk as ttk
from icon import qq_icon_png, github_mark
# 防止加载不出图标
import base64
import QQ_History
import os
import webbrowser
from time import sleep
class GUI_CONST:
TITLE = "QQ聊天记录导出"
URL = "https://github.com/Young-Lord/QQ_History_Backup"
def Enter():
base_path, qq_self, qq = e1.get(), e2.get(), e3.get()
for i in (e4, e5, e6, e7, e8):
if i.get() not in i['values']:
info.set(f"某个输入框的值{i.get()}不在允许的取值{i['values']}内!")
return ()
group = 1 if e4.get() == '私聊' else 2
emoji = 1 if e5.get() == '新' else 2
dump_all = True if e8.get() == '是' else False
with_img = True if e6.get() == '是' else False
combine_img = True if e7.get() == '是' else False
if (base_path == "" or qq_self == "") or (qq == "" and (not dump_all)):
info.set("信息不完整!")
return ()
# info.set("开始导出……")
# if dump_all:
# info.set("批量导出较慢,请耐心等待……")
# 只要界面未更新 用户就看不到
try:
config = (base_path, qq_self, qq, group,
emoji, with_img, combine_img, dump_all)
QQ_History.main(base_path, qq_self, qq, group,
emoji, with_img, combine_img, dump_all=dump_all)
info.set("导出完成。")
except Exception as e:
info.set(str(config)+"\r\n"+str(repr(e)))
return ()
def SelectDBPath():
dir = filedialog.askdirectory()
base_path_get.set(dir)
def SelectImgPath():
dir = filedialog.askdirectory()
img_path_get.set(dir)
def url():
webbrowser.open_new(GUI_CONST.URL)
root = tk.Tk()
base_path_get, img_path_get, key_get, info = tk.StringVar(
), tk.StringVar(), tk.StringVar(), tk.StringVar()
tmp = open("tmp.png", "wb+")
tmp.write(base64.b64decode(qq_icon_png))
tmp.close()
root.call('wm', 'iconphoto', root._w,tk.PhotoImage(file='tmp.png'))
os.remove("tmp.png")
root.title(GUI_CONST.TITLE)
ttk.Label(root, text="*com.tencent.mobileqq:").grid(row=0, column=0, sticky="e")
e1 = ttk.Entry(root, textvariable=base_path_get)
e1.grid(row=0, column=1, columnspan=2, sticky="ew", pady=3)
ttk.Button(root, text="选择", command=SelectDBPath,
width=5).grid(row=0, column=3)
ttk.Label(root, text="*自己QQ号:").grid(row=1, column=0, sticky="e")
e2 = ttk.Entry(root)
e2.grid(row=1, column=1, columnspan=3, sticky="ew", pady=3)
ttk.Label(root, text="导出所有记录:").grid(
row=2, column=0, sticky="e") # 每个row属性都得更改,什么离谱布局
e8 = ttk.Combobox(root)
e8['values'] = ('是', '否')
e8.current(1)
e8.grid(row=2, column=1, columnspan=3, sticky="ew", pady=3)
ttk.Label(root, text="QQ号/群号:").grid(row=3, column=0, sticky="e")
e3 = ttk.Entry(root)
e3.grid(row=3, column=1, columnspan=3, sticky="ew", pady=3)
ttk.Label(root, text="私聊/群聊:").grid(row=4, column=0, sticky="e")
e4 = ttk.Combobox(root)
e4['values'] = ('私聊', '群聊')
e4.current(0)
e4.grid(row=4, column=1, columnspan=3, sticky="ew", pady=3)
ttk.Label(root, text="表情版本:").grid(row=5, column=0, sticky="e")
e5 = ttk.Combobox(root)
e5['values'] = ('新', '旧')
e5.current(0)
e5.grid(row=5, column=1, columnspan=3, sticky="ew", pady=3)
ttk.Label(root, text="导出图片:").grid(row=6, column=0, sticky="e")
e6 = ttk.Combobox(root)
e6['values'] = ('是', '否')
e6.current(0)
e6.grid(row=6, column=1, columnspan=3, sticky="ew", pady=3)
ttk.Label(root, text="合并图片:").grid(row=7, column=0, sticky="e")
e7 = ttk.Combobox(root)
e7['values'] = ('是', '否')
e7.current(1)
e7.grid(row=7, column=1, columnspan=3, sticky="ew", pady=3)
root.grid_columnconfigure(2, weight=1)
info.set("开始")
ttk.Button(root, textvariable=info, command=Enter).grid(row=8, column=1)
tmp = open("tmp.png", "wb+")
tmp.write(base64.b64decode(github_mark))
tmp.close()
github = tk.PhotoImage(file='tmp.png')
os.remove("tmp.png")
button_img = tk.Button(root, image=github, text='b', command=url, bd=0)
button_img.grid(row=9, rowspan=7, column=0, sticky="ws")
root.mainloop()
================================================
FILE: GUI.spec
================================================
# -*- mode: python ; coding: utf-8 -*-
block_cipher = None
a = Analysis(
['GUI.py'],
pathex=[],
binaries=[],
datas=[],
hiddenimports=[],
hookspath=[],
hooksconfig={},
runtime_hooks=[],
excludes=[],
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher,
noarchive=False,
)
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
exe = EXE(
pyz,
a.scripts,
a.binaries,
a.zipfiles,
a.datas,
[],
name='GUI',
debug=False,
bootloader_ignore_signals=False,
strip=False,
upx=True,
upx_exclude=[],
runtime_tmpdir=None,
console=False,
disable_windowed_traceback=False,
argv_emulation=False,
target_arch=None,
codesign_identity=None,
entitlements_file=None,
icon=['icon.ico'],
)
================================================
FILE: LICENSE
================================================
MIT License
Copyright (c) 2023 Young-Lord
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: QQ_History.py
================================================
import hashlib
import sqlite3
import time
import os
import traceback
import json
import base64
from proto.RichMsg_pb2 import PicRec
from proto.RichMsg_pb2 import Elem
from proto.RichMsg_pb2 import Msg
from proto.RichMsg_pb2 import PttRec
from html import escape
from tempfile import NamedTemporaryFile
_crc64_init = False
_crc64_table = [0] * 256
def crc64(s):
global _crc64_init
if not _crc64_init:
for i in range(256):
bf = i
for j in range(8):
if bf & 1 != 0:
bf = bf >> 1 ^ -7661587058870466123
else:
bf >>= 1
_crc64_table[i] = bf
_crc64_init = True
v = -1
for i in range(len(s)):
v = _crc64_table[(ord(s[i]) ^ v) & 255] ^ v >> 8
return v
def tempFilename() -> str:
f = NamedTemporaryFile(delete=False)
f.close()
return f.name
def isEmpty(s):
if s is None:
return True
if type(s) == int and s == 0:
return True
if type(s) == str and s == '':
return True
return False
class QQoutput():
def __init__(self, base_path: str, qq_self: str, emoji: int = 1, with_img: bool = True, combine_img: bool = False):
# 真正用到的文件只有[f"{QQ}.db", f"slowtable_{QQ}.db", "kc"],这里我直接合并到一个层级下了
self.IS_TIM = False # TIM会缺少一些字段
self.base_path = base_path
if type(qq_self) == int:
qq_self = str(qq_self)
assert(type(qq_self) == str)
self.qq_self: str = qq_self # 自己的QQ号
self.uin_to_username = {}
self.troopuin_to_troopname = {}
self.troopuin_to_troopmembers = {}
self.init_paths()
self.init_key() # 解密用的密钥
self.c1 = sqlite3.connect(self.db_main_path).cursor()
try:
self.c2 = sqlite3.connect(self.db_slow_path).cursor()
except:
pass
self.detect_TIM()
self.init_friend_list()
self.init_troop_list()
# self.qq: str = qq # 导出对象的QQ号
# self.mode = mode # 1为私聊,2为群聊
assert(emoji in (1, 2))
self.emoji = emoji # 1为新表情,2为旧表情
assert(type(with_img) == bool)
self.with_img = with_img # True为生成图片,False为不生成图片
assert(type(combine_img) == bool)
self.combine_img = combine_img # True为将图片嵌入HTML文件中,False为在HTML中存储图片的相对路径
# self.num_to_name = {}
# 双重映射,即self.troop_members_name[群号][发言人QQ号]
self.troop_members_name = {}
self.emoji_map = self.map_new_emoji()
@staticmethod
def getDisplayName(friend: list) -> str:
if isEmpty(friend[1]):
ans = friend[2]
else:
ans = friend[1]
return ans
@staticmethod
def getSafePath(ans: str) -> str:
ban_words = "\\ / : * ? \" ' < > | $ \r \n".replace(
' ', '')
ban_strips = "#/~"
while True:
ans_bak = ans
for i in ban_words:
ans = ans.replace(i, "")
for i in ban_strips:
ans = ans.strip(i)
if ans == ans_bak: # 多次匹配
break
return ans
def detect_TIM(self):
try:
self.fill_cursor("select troopRemark from TroopInfoV2")
except sqlite3.OperationalError:
self.IS_TIM = True
print("检测到 TIM,部分功能可能缺失!")
else:
self.IS_TIM = False
return self.IS_TIM
def mydecrypt(self, data):
# 综合一下
s = self.fix(data, 1)
if s != "":
return s
return self.decrypt(data)
def fix(self, data, mode):
# msgdata mode=0
# other mode=1
# https://github.com/roadwide/qqmessageoutput/blob/master/q.py
# decrypt处理Emoji时会出问题,而这个不会
if (mode == 0):
rowbyte = []
# 这么做是为了解决汉字的utf-8是三字节
for i in range(0, len(data)):
rowbyte.append(data[i] ^ ord(self.key[i % len(self.key)]))
rowbyte = bytes(rowbyte)
try:
msg = rowbyte.decode(encoding='utf-8')
except:
msg = ""
return msg
elif (mode == 1):
str = ''
try:
j = 0
for i in range(0, len(data)):
# 获取unicode码
unicode = ord(data[i])
# 如果大于ffff 处理emoji
if (unicode > 0xffff):
# 分为2个10位二进制与两个密码进行异或
code = unicode ^ (
(ord(self.key[i+j % len(self.key)]) << 10) + ord(self.key[i+j+1 % len(self.key)]))
str += chr(code)
j = j + 1
else:
str += chr(ord(data[i]) ^
ord(self.key[i+j % len(self.key)]))
except:
str = ""
return str
def decrypt(self, data, msg_type=-1000):
# fix处理**一些东西**会出问题,这个不会
try:
msg = b''
if type(data) == bytes:
msg = b''
for i in range(0, len(data)):
msg += bytes([data[i] ^ ord(self.key[i % len(self.key)])])
elif type(data) == str:
msg = ''
for i in range(0, len(data)):
msg += chr(ord(data[i]) ^ ord(self.key[i % len(self.key)]))
return msg
if msg_type == -1000 or msg_type == -1049 or msg_type == -1051:
try:
return escape(msg.decode('utf-8'))
except:
# print(msg)
pass
return '[decode error]'
if not self.with_img:
return None
elif msg_type == -2000:
return self.decode_pic(msg)
elif msg_type == -1035:
return self.decode_mix_msg(msg)
elif msg_type == -5008:
return self.decode_share_url(msg)
elif msg_type == -5012 or msg_type == -5018:
return '[戳一戳]'
elif msg_type == -2002: # 语音消息
return self.decode_silk(msg)
except:
return f'[解码失败({msg_type})]'
# for debug
return '[unknown msg_type {}]'.format(msg_type)
# return ''
def add_emoji(self, msg):
pos = msg.find('\x14')
while pos != -1:
lastpos = pos
num = ord(msg[pos + 1])
if str(num) in self.emoji_map:
index = self.emoji_map[str(num)]
if self.emoji == 1:
filename = "new/s" + index + ".png"
else:
filename = "old/" + index + ".gif"
emoticon_path = os.path.join('emoticon', filename)
if self.combine_img:
try:
emoticon_path = self.get_base64_from_pic(emoticon_path)
except:
pass
msg = msg.replace(
msg[pos:pos + 2], ' '.format(emoticon_path, index))
else:
msg = msg.replace(msg[pos:pos + 2],
'[emoji:{}]'.format(str(num)))
pos = msg.find('\x14')
if pos == lastpos:
break
return msg
def message(self, qq: str, mode: int):
# mode=1 friend
# mode=2 troop
num = qq.encode("utf-8")
md5num = hashlib.md5(num).hexdigest().upper()
if mode == 1:
cmd = "select msgData,senderuin,time,msgtype from mr_friend_{}_New order by time".format(
md5num)
# self.get_friends()
else:
cmd = "select msgData,senderuin,time,msgtype from mr_troop_{}_New order by time".format(
md5num)
# print('Groups {} -> {}'.format(num, md5num))
self.get_troop_members(qq)
cursor = self.fill_cursor(cmd)
allmsg = []
for row in cursor:
msgdata: bytes = row[0]
if not msgdata:
continue
uin = row[1]
ltime = time.localtime(row[2])
sendtime = time.strftime("%Y-%m-%d %H:%M:%S", ltime)
msg_type = row[3]
msg_final = self.decrypt(msgdata, msg_type)
if msg_final is None:
continue
allmsg.append(
[sendtime, msg_type, self.decrypt(uin), msg_final])
return allmsg
def get_friends(self):
raise NotImplementedError
def get_troop_members(self, qq: str):
self.troopuin_to_troopmembers[qq] = {}
cmd = "SELECT troopuin, memberuin, autoremark, troopnick, friendnick, recommendRemark, mUniqueTitle FROM TroopMemberInfo"
cursor = self.fill_cursor(cmd)
for row in cursor:
if self.fix(row[0], 1) != qq:
continue
num = self.fix(row[1], 1)
names = [self.fix(i, 1) for i in row[2:6]]
# 2是你给好友的备注,3是好友的群昵称,4是好友名字,5是好友的群昵称,mUniqueTitle是群头衔
# xxx 我不知道这个顺序怎么搞的 一部分是猜
try:
final_name = [i for i in names[1:] if not isEmpty(i)][0]
except IndexError:
try:
final_name = names[0]
except IndexError:
print(f"{qq}群中{num}好友无法匹配名字。names={names}")
print("开Issue!")
if num in self.uin_to_username: # 是你对话过的人
if not isEmpty(names[0]):
final_name = names[0]
else:
# print(names)
# print("↑你这个好友怎么没有备注的?开Issue!")
pass
self.troopuin_to_troopmembers[qq][num] = final_name
# print([self.fix(i, 1) for i in row[2:6]])
if not isEmpty(row[6]): # 添加头衔
self.troopuin_to_troopmembers[qq][num] = f"【{row[6]}】" + \
self.troopuin_to_troopmembers[qq][num]
def _fill_cursors(self, cmd):
cursors = []
# slowtable might not contain related message, so just skip it
try:
cursors.append(self.c2.execute(cmd))
except:
pass
try:
cursors.append(self.c1.execute(cmd))
except sqlite3.OperationalError:
pass
return cursors
def fill_cursor(self, cmd):
cursors = self._fill_cursors(cmd)
ans = []
for cs in cursors:
for row in cs:
ans.append(row)
return ans
def output(self, qq: str, mode: int, output_path: str = "."):
self.outut_path = output_path
if type(qq) == int:
qq = str(qq)
assert(type(qq) == str)
assert(mode in (1, 2))
name1 = "我"
fileprefix = ""
if mode == 1:
fileprefix = "私聊"
filebasename = self.getSafePath(self.uin_to_username.get(qq, str(qq)))
if qq not in self.uin_to_username:
print(f"警告:{qq}无法在好友列表内找到,请检查聊天类型是否填写正确")
else:
fileprefix = "群聊"
filebasename = self.getSafePath(self.troopuin_to_troopname.get(qq, str(qq)))
if qq not in self.troopuin_to_troopname:
print(f"警告:{qq}无法在群聊列表内找到,请检查聊天类型是否填写正确")
file = f"{fileprefix}-{filebasename}-{qq}.html"
file = os.path.join(output_path, file)
allmsg = self.message(qq, mode)
if len(allmsg) == 0:
print(f"{qq}_{mode}没有聊天记录,跳过。")
return
f2 = open(file, "w", encoding="utf-8")
f2.write(
"
"
)
f2.write("")
if mode == 1:
table = self.uin_to_username
else:
table = self.troopuin_to_troopmembers.get(qq, {})
for ts, _, uid, msg in allmsg:
if not msg:
continue
if uid == str(self.qq_self):
f2.write("
")
f2.write("")
f2.write(ts)
f2.write(" -----")
f2.write(name1)
f2.write(" ")
else:
f2.write("
")
f2.write("")
f2.write(escape("{}({})".format(
table.get(uid, "???未知???"), uid)))
f2.write(" -----")
f2.write(ts)
f2.write(" ")
f2.write(self.add_emoji(msg))
f2.write("")
f2.write("
")
f2.write("
")
f2.close()
print("导出已完成。文件目录:" + file)
def init_key(self):
kc_file = open(self.kc_path, "r")
self.key = kc_file.read().strip('\r \n')
kc_file.close()
def init_paths(self):
join = os.path.join
mainb = self.qq_self + ".db"
slowb = "slowtable_" + self.qq_self + ".db"
db_main_paths = [mainb, join("databases", mainb), join("db", mainb)]
db_slow_paths = [slowb, join("databases", slowb), join("db", slowb)]
kc_paths = ["kc", join("files", "kc"), join("f", "kc")]
self.kc_path = self.db_main_path = self.db_slow_path = None
for i in db_main_paths:
current_file = join(self.base_path, i)
if os.path.isfile(current_file):
self.db_main_path = current_file
for i in db_slow_paths:
current_file = join(self.base_path, i)
if os.path.isfile(current_file):
self.db_slow_path = current_file
for i in kc_paths:
current_file = join(self.base_path, i)
if os.path.isfile(current_file):
self.kc_path = current_file
if self.kc_path is None or self.db_main_path is None: # 很少记录的号没有slowtable,故不判断
raise FileNotFoundError(
f"无法找到目标文件!\n路径:{self.base_path}\n当前匹配列表:{[self.kc_path, self.db_main_path, self.db_slow_path]}")
def init_friend_list(self):
self.FriendsData = []
# uin-QQ号,remark-备注,name-昵称
execute = "select uin,remark,name from Friends"
cursor = self.fill_cursor(execute)
for i in cursor:
uin, remark, name = i[0], i[1], i[2]
decode_uin = self.mydecrypt(uin)
decode_remark = self.mydecrypt(remark)
decode_name = self.mydecrypt(name)
friend = [decode_uin, decode_remark, decode_name]
self.FriendsData.append(friend)
self.uin_to_username[decode_uin] = self.getDisplayName(friend)
def init_troop_list(self):
self.TroopsData = []
# troopuin-群号,troopRemark-群备注,troopname-群名
execute = "select troopuin,troopRemark,troopname from TroopInfoV2"
if self.IS_TIM:
execute = execute.replace(
"troopRemark", "troopname") # TIM无法给群聊设备注
cursor = self.fill_cursor(execute)
for i in cursor:
uin, remark, name = i[0], i[1], i[2]
# print([self.fix(ii,1) for ii in i])
decode_uin = self.mydecrypt(uin)
decode_remark = self.mydecrypt(remark)
decode_name = self.mydecrypt(name)
troop = [decode_uin, decode_remark, decode_name]
self.TroopsData.append(troop)
# print(troop)
self.troopuin_to_troopname[decode_uin] = self.getDisplayName(troop)
def map_new_emoji(self):
with open(os.path.join(os.path.dirname(os.path.abspath(__file__)), './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 get_base64_from_pic(self, path):
with open(path, "rb") as image_file:
return (b'data:image/png;base64,' + base64.b64encode(image_file.read())).decode("utf-8")
def decode_pic(self, data):
try:
doc = PicRec()
doc.ParseFromString(data)
url = 'chatimg:' + doc.md5
filename = hex(crc64(url))
filename = 'Cache_' + filename.replace('0x', '')
chatimg_basepath = os.path.join(self.base_path, "chatimg")
if not os.path.isdir(chatimg_basepath):
chatimg_basepath = "chatimg"
rel_path = os.path.join(chatimg_basepath, filename[-3:], filename)
if os.path.exists(rel_path):
print(rel_path)
w = 'auto' if doc.uint32_thumb_width == 0 else str(
doc.uint32_thumb_width)
h = 'auto' if doc.uint32_thumb_height == 0 else str(
doc.uint32_thumb_height)
if self.combine_img:
rel_path = self.get_base64_from_pic(rel_path)
return ' '.format(rel_path, w, h)
# 最后这里必须用相对路径
except Exception as e:
pass
return '[图片]'
def decode_mix_msg(self, data):
try:
doc = Msg()
doc.ParseFromString(data)
message = ''
for elem in doc.elems:
if elem.picMsg:
message += self.decode_pic(elem.picMsg)
else:
message += escape(elem.textMsg.decode('utf-8'))
return message
except:
pass
return '[混合消息]'
def decode_silk(self, data):
# TODO
try:
import pilk
import av
av.logging.set_level(av.logging.ERROR)
doc = PttRec()
doc.ParseFromString(data)
print(doc.sttText)
voiceLength = doc.voiceLength # 以秒为单位
filename = doc.localPath[doc.localPath.find("/ptt/")+5:]
ptt_basepath = os.path.join(self.base_path, "ptt")
if not os.path.isdir(ptt_basepath):
ptt_basepath = "ptt"
if not os.path.isdir(ptt_basepath):
return '[语音消息](目录不存在)'
rel_path = os.path.join(ptt_basepath, filename)
if not os.path.exists(rel_path):
p = [".amr", ".slk"]
if rel_path.endswith(p[0]) and os.path.exists(rel_path[:-4]+p[1]): # 试着更改后缀匹配
filename = filename[:-4]+p[1]
rel_path = rel_path[:-4]+p[1]
elif rel_path.endswith(p[1]) and os.path.exists(rel_path[:-4]+p[0]):
filename = filename[:-4]+p[0]
rel_path = rel_path[:-4]+p[0]
else:
# 摆了!
return f"[语音消息](文件{rel_path}不存在)"
voice_path = os.path.join(self.outut_path, "voice")
if not os.path.exists(voice_path):
os.makedirs(voice_path)
pcm = tempFilename()
pilk.decode(rel_path, pcm)
absolute_output = os.path.join(voice_path, filename[:-4]+".mp3")
relative_output = os.path.join("voice", filename[:-4]+".mp3")
rate=24000# pilk源码写的,不管了
with av.open(pcm,format='s16le',options={'ar':str(rate),'ac':'1'}) as in_container:
in_stream = in_container.streams.audio[0]
with av.open(absolute_output, 'w') as out_container:
out_stream = out_container.add_stream(
'mp3',
rate=rate,
layout='mono'
)
try:
for frame in in_container.decode(in_stream):
frame.pts = None
for packet in out_stream.encode(frame):
out_container.mux(packet)
except Exception as ee:
raise ee
pass
os.remove(pcm)
return ' '.format(relative_output, f"时长 {voiceLength} 秒的语音消息")
# 最后这里必须用相对路径
except Exception as e:
print(traceback.format_exc())
return '[语音消息]'
def decode_share_url(self, msg):
# TODO
return '[分享卡片]'
def main(base_path, qq_self, qq, mode, emoji, with_img, combine_img, dump_all):
try:
f = open('log.txt', 'w', encoding="utf-8")
except:
class ff:
def write(): pass
def close(): pass
f = ff()
global print
print_bak = print
def print(*arg, **kwarg):
print_bak(*arg, **kwarg)
f.write("[PRINT]: "+' '.join([str(i) for i in arg])+"\n")
try:
q = QQoutput(base_path, str(qq_self), emoji, with_img, combine_img)
if dump_all:
print("正在批量导出……")
dest = "output_" + \
time.strftime("%Y%m%d-%H%M%S", time.localtime(time.time()))
try:
os.mkdir(dest)
except:
raise ValueError("目录创建失败,退出。")
for i in q.FriendsData:
try:
q.output(i[0], 1, dest)
except Exception as e:
f.write(repr(e))
f.write(traceback.format_exc())
for i in q.TroopsData:
try:
q.output(i[0], 2, dest)
except Exception as e:
f.write(repr(e))
f.write(traceback.format_exc())
print("")
print("="*30)
print("所有记录导出完成。")
print("="*30)
else:
q.output(qq, mode)
except Exception as e:
f.write(repr(e))
f.write(traceback.format_exc())
print(traceback.format_exc())
if repr(e).split(":")[0] == "OperationalError('no such table":
raise ValueError("信息填入错误")
else:
raise BaseException("Error! See log.txt")
def run_directly():
base_path = r"修改这里!" # com.tencent.mobileqq 路径
qq_self = "修改这里!" # 自己的QQ号
batch = True # 是否导出所有记录
q = QQoutput(base_path, str(qq_self))
f = open('log.txt', 'w', encoding="utf-8")
if batch:
print("正在批量导出……")
dest = "output_" + \
time.strftime("%Y%m%d-%H%M%S", time.localtime(time.time()))
try:
os.mkdir(dest)
except:
raise ValueError("目录创建失败,退出。")
for i in q.FriendsData:
try:
q.output(i[0], 1, dest)
except Exception as e:
f.write(repr(e))
f.write(traceback.format_exc())
for i in q.TroopsData:
try:
q.output(i[0], 2, dest)
except Exception as e:
f.write(repr(e))
f.write(traceback.format_exc())
print("")
print("="*30)
print("所有记录导出完成。")
print("="*30)
else:
qq = "修改这里!"
mode = 1 # 修改这里!私聊为1,群聊为2
q.output(qq, mode)
f.close()
if __name__ == '__main__':
run_directly()
================================================
FILE: README.md
================================================
# QQ聊天记录导出
本项目用于将 **非 QQNT** 的 Android 端 QQ/TIM 的聊天记录数据库转换为 HTML 文件,并转换图片、语音等部分特殊消息。
## 关于其他平台(Windows, MacOS, iOS…)
请看 [QQBackup/qq-win-db-key](https://github.com/QQBackup/qq-win-db-key)。
## 维护情况
省流:没时间维护,欢迎新 maintainer 与 PR(或者可以自行开个fork)。请提交到`dev`分支。
同时,请参看[qq-win-db-key 中列出的改进版](https://github.com/QQBackup/qq-win-db-key/blob/master/%E6%95%99%E7%A8%8B%20-%20%E5%AE%89%E5%8D%93%E7%89%88QQ%E5%8F%8ATIM.md#%E8%A7%A3%E5%AF%86%E8%BD%AC%E6%8D%A2)。
## 运行方式
1. 一切操作之前,你需要先安装 Python 3.x(建议使用可下载的最高版本,已知支持`3.12`),可参考[此文章(Windows)](https://zhuanlan.zhihu.com/p/458428159)。
2. 然后,在当前目录打开终端,Windows 用户若不懂可以看[这篇博文](https://blog.csdn.net/Lzy410992/article/details/105937780)
3. 输入以下命令永久加速相关依赖的下载(换源):`pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple`
3. 安装依赖:`pip install -r requirements.txt`
4. 若是运行 GUI,就`python GUI.py`
5. 若是直接运行命令行版,就修改好`QQ_History.py`最下面的内容,并运行:`python QQ_History.py`
## 声明
本项目仅供学习交流使用,严禁用于任何违反中国大陆法律法规、您所在地区法律法规、[QQ软件许可及服务协议](https://rule.tencent.com/rule/preview/46a15f24-e42c-4cb6-a308-2347139b1201)的行为,本人不承担任何相关行为导致的直接或间接责任。
本项目理论仅能将可以通过正常方法查看的聊天记录**导出**,而不能进行包括但不限于已删除聊天记录恢复在内的操作。
本项目不对生成内容的完整性、准确性作任何担保,因此生成的一切内容**没有法律效力**,您不应当将其用于学习与交流外的任何用途。
## 简介
作为国内最常用的聊天工具之一,QQ 为了用户留存度,默认聊天记录备份无法脱离 QQ 被独立打开。
目前版本往往需要通过命令行运行,本方法在之前版本的基础上简化了操作,制作了GUI方便使用;并且不再需要提供密钥,自动填入备注/昵称,添加了QQ表情、图片和语音的一并导出。
如果你不使用打包后的版本,请首先运行以下命令以安装依赖:`pip install -r requirements.txt`
## 获取聊天记录文件夹方法
> 注:以下提到的“电脑”泛指一切可以运行此程序的环境,如安卓手机上的 Termux 也属于此列
> 注:以下内容假设您使用的是 QQ 而非 TIM,如果您在使用 TIM,请将`com.tencent.mobileqq`改为`com.tencent.tim`,将`MobileQQ`改为`Tim`
如果手机已获得 root 权限,聊天记录可在以下路径找到。
```
/data/data/com.tencent.mobileqq/
```
我们需要的文件只有`databases/.db`,`databases/slowtable_.db`,`files/kc`,因此您可以将整个文件夹压缩后传输到电脑上,亦或将这三个文件单独放在同一个目录中传输。本程序会自动识别这两种不同的目录结构。
如果没有 root 权限,可以通过手机自带的备份工具备份整个 QQ,拷贝备份文件到电脑,解压找到 `com.tencent.mobileqq`。
具体方法可以参见
> 怎样导出手机中的QQ聊天记录? - 益新软件的回答 - 知乎
>
关于苹果设备导出,参见[此讨论](https://github.com/Yiyiyimu/QQ-History-Backup/issues/42);对于安卓系统导出内容的提取,请自行在互联网查询。
如果同时需要在聊天记录中显示图片,拷贝手机中 `/sdcard/Android/data/com.tencent.mobileqq/Tencent/MobileQQ/chatpic/chatimg` 至 `GUI.exe` 同一文件夹中或者拷贝过来的`com.tencent.mobileqq`目录下。
(QQ)如果同时需要在聊天记录中显示语音,拷贝手机中 `/sdcard/Android/data/com.tencent.mobileqq/Tencent/MobileQQ//ptt` 至 `GUI.exe` 同一文件夹中或者拷贝过来的`com.tencent.mobileqq`目录下。
(TIM)如果同时需要在聊天记录中显示语音,拷贝手机中 `/sdcard/Android/data/com.tencent.tim/Tencent/Tim/ptt/` 至 `GUI.exe` 同一文件夹中或者拷贝过来的`com.tencent.mobileqq`目录下,并重命名为`ptt`。
## GUI使用方法

- `com.tencent.mobileqq`:选择导出的相应文件夹,对于备份方式,一般为`apps/com.tencent.mobileqq`
- 表情版本:默认为新版QQ表情。如果你的聊天记录来自很早以前,可以切换为旧版的表情
- 导出所有记录:若此项选择“是”,则`QQ号/群号:`与`私聊/群聊:`选项会被忽略。
- 导出图片:若此项与前一项均选择“是”,必须把`chatimg`目录复制到生成的`output_xxx`目录下,图片才能正常显示
- 合并图片:默认为否
- 不启用合并图片好处在于:1. 使导出的 HTML 文件具有可读性;2. 减小 HTML 文件体积方便打开
- 启用合并图片好处:拷贝时不需要和 `emoticon` 以及 `chatimg` 文件夹一起拷贝,更加方便
## 输出截图


如果没有启用合并图片,拷贝生成的聊天记录时需要一起拷贝 `emoticon` 以及 `chatimg` 文件夹.
有 bug 的话提 issue,记得附上 log.txt 里的内容以及终端的报错内容。
## TODO
- [x] 支持群聊导出
- [x] 支持自动查找密钥
- [x] 使用好友/群聊昵称作为默认用户名
- [x] 自动合并 db 和 slow-table
- [x] 支持新 QQ emoji
- [x] 支持单一文件导出
- [x] 支持音频导出
- [ ] 支持视频导出
- [ ] 支持合并转发消息导出
- [ ] 支持戳一戳导出
- [ ] 支持缩略图
- [ ] 支持卡片分享
- [ ] 重构代码
- [ ] 加入 i18n 与自定义翻译支持
- [ ] 支持使用[silk-v3-decoder](https://github.com/ZhangJun2017/QQChatHistoryExporter)转换音频文件
- [ ] 使用 Jinja2 生成 HTML 文件
- [ ] 允许插入自定义 CSS 与 自定义 JS
- [ ] 分析并试图优化解密相关函数
- [ ] 更新预览图
- [ ] 基于 GitHub Actions 以 PyInstaller 生成在 Windows 下的可执行文件
## FAQ
- **聊天记录中显示 `[图片]` 是因为什么?**
解码出的图片路径在 `chatimg` 找不到相应文件。可能原因为在手机中没有加载过该文件,导致图片没有存在手机里。
## CHANGELOG
### v2
- 直接从 `files/kc` 提取明文的密钥,不用再手动输入或解密
- 支持群聊记录导出
- 支持 私聊/群聊 的 备注/昵称 自动填入
- 支持 slowtable 的直接整合
- 支持新版 QQ 表情
### v2.2
- 支持导出图片至聊天记录
- 支持合并图片至单一文件方便传输
### v2.3
- 支持读取不同的目录结构
- 支持单独导出一个私聊对话或群聊对话
- 部分修复解密函数存在的 bug
- 支持批量导出
- 修复导出的 HTML 中的字符转义
### v2.4
- 支持读取音频
## 致谢
1. [roadwide/qqmessageoutput](https://github.com/roadwide/qqmessageoutput)
2. [WincerChan/export.py](https://gist.github.com/WincerChan/362331456a6e0417c5aa1cf3ff7be2b7)
3. [Yiyiyimu/QQ-History-Backup](https://github.com/Yiyiyimu/QQ-History-Backup) (本仓库的来源,致敬!同时,源代码基于 MIT 协议使用。)
4. [ZhangJun2017/QQChatHistoryExporter](https://github.com/ZhangJun2017/QQChatHistoryExporter) (参考了 Protobuf 相关内容)
## 适配新类型笔记
1. 下载 [protoc](https://github.com/protocolbuffers/protobuf/releases) 这一可执行文件,设置可执行权限(仅 Linux 类系统)并移动到适当位置(位于 PATH 环境变量中的目录)
2. 编辑`proto/RichMsg.proto`,增加新类型(可以参照[此项目](https://github.com/ZhangJun2017/QQChatHistoryExporter/blob/f97eb64581229a30514d55aa0a8423b138b09437/src/RawMessage.java#L41))
3. 切换到目录`proto`中,运行`compile`,在 Windows 下需先将其改名为`compile.bat`
4. 编辑`QQ_History.py`中的`decrypt`,加入`msgtype`对应判断与处理代码
5. **记得写文档**
================================================
FILE: emoticon/face_config.json
================================================
{
"sysface": [
{
"QSid": "14",
"QDes": "/微笑",
"IQLid": "23",
"AQLid": "23",
"EMCode": "100"
},
{
"QSid": "1",
"QDes": "/撇嘴",
"IQLid": "40",
"AQLid": "40",
"EMCode": "101"
},
{
"QSid": "2",
"QDes": "/色",
"IQLid": "19",
"AQLid": "19",
"EMCode": "102"
},
{
"QSid": "3",
"QDes": "/发呆",
"IQLid": "43",
"AQLid": "43",
"EMCode": "103"
},
{
"QSid": "4",
"QDes": "/得意",
"IQLid": "21",
"AQLid": "21",
"EMCode": "104"
},
{
"QSid": "5",
"QDes": "/流泪",
"IQLid": "9",
"AQLid": "9",
"EMCode": "105"
},
{
"QSid": "6",
"QDes": "/害羞",
"IQLid": "20",
"AQLid": "20",
"EMCode": "106"
},
{
"QSid": "7",
"QDes": "/闭嘴",
"IQLid": "104",
"AQLid": "106",
"EMCode": "107"
},
{
"QSid": "8",
"QDes": "/睡",
"IQLid": "35",
"AQLid": "35",
"EMCode": "108"
},
{
"QSid": "9",
"QDes": "/大哭",
"IQLid": "10",
"AQLid": "10",
"EMCode": "109"
},
{
"QSid": "10",
"QDes": "/尴尬",
"IQLid": "25",
"AQLid": "25",
"EMCode": "110"
},
{
"QSid": "11",
"QDes": "/发怒",
"IQLid": "24",
"AQLid": "24",
"EMCode": "111"
},
{
"QSid": "12",
"QDes": "/调皮",
"IQLid": "1",
"AQLid": "1",
"EMCode": "112"
},
{
"QSid": "13",
"QDes": "/呲牙",
"IQLid": "0",
"AQLid": "0",
"EMCode": "113"
},
{
"QSid": "0",
"QDes": "/惊讶",
"IQLid": "33",
"AQLid": "33",
"EMCode": "114"
},
{
"QSid": "15",
"QDes": "/难过",
"isStatic": "1",
"IQLid": "32",
"AQLid": "32",
"EMCode": "115"
},
{
"QSid": "16",
"QDes": "/酷",
"IQLid": "12",
"AQLid": "12",
"EMCode": "116"
},
{
"QSid": "96",
"QDes": "/冷汗",
"IQLid": "27",
"AQLid": "27",
"EMCode": "117"
},
{
"QSid": "18",
"QDes": "/抓狂",
"IQLid": "13",
"AQLid": "13",
"EMCode": "118"
},
{
"QSid": "19",
"QDes": "/吐",
"IQLid": "22",
"AQLid": "22",
"EMCode": "119"
},
{
"QSid": "20",
"QDes": "/偷笑",
"IQLid": "3",
"AQLid": "3",
"EMCode": "120"
},
{
"QSid": "21",
"QDes": "/可爱",
"IQLid": "18",
"AQLid": "18",
"EMCode": "121"
},
{
"QSid": "22",
"QDes": "/白眼",
"IQLid": "30",
"AQLid": "30",
"EMCode": "122"
},
{
"QSid": "23",
"QDes": "/傲慢",
"IQLid": "31",
"AQLid": "31",
"EMCode": "123"
},
{
"QSid": "24",
"QDes": "/饥饿",
"IQLid": "79",
"AQLid": "81",
"EMCode": "124"
},
{
"QSid": "25",
"QDes": "/困",
"IQLid": "80",
"AQLid": "82",
"EMCode": "125"
},
{
"QSid": "26",
"QDes": "/惊恐",
"IQLid": "26",
"AQLid": "26",
"EMCode": "126"
},
{
"QSid": "27",
"QDes": "/流汗",
"IQLid": "2",
"AQLid": "2",
"EMCode": "127"
},
{
"QSid": "28",
"QDes": "/憨笑",
"IQLid": "37",
"AQLid": "37",
"EMCode": "128"
},
{
"QSid": "29",
"QDes": "/悠闲",
"IQLid": "50",
"AQLid": "50",
"EMCode": "129"
},
{
"QSid": "30",
"QDes": "/奋斗",
"IQLid": "42",
"AQLid": "42",
"EMCode": "130"
},
{
"QSid": "31",
"QDes": "/咒骂",
"IQLid": "81",
"AQLid": "83",
"EMCode": "131"
},
{
"QSid": "32",
"QDes": "/疑问",
"IQLid": "34",
"AQLid": "34",
"EMCode": "132"
},
{
"QSid": "33",
"QDes": "/嘘",
"IQLid": "11",
"AQLid": "11",
"EMCode": "133"
},
{
"QSid": "34",
"QDes": "/晕",
"IQLid": "49",
"AQLid": "49",
"EMCode": "134"
},
{
"QSid": "35",
"QDes": "/折磨",
"IQLid": "82",
"AQLid": "84",
"EMCode": "135"
},
{
"QSid": "36",
"QDes": "/衰",
"isStatic": "1",
"IQLid": "39",
"AQLid": "39",
"EMCode": "136"
},
{
"QSid": "37",
"QDes": "/骷髅",
"isStatic": "1",
"IQLid": "76",
"AQLid": "78",
"EMCode": "137"
},
{
"QSid": "38",
"QDes": "/敲打",
"IQLid": "5",
"AQLid": "5",
"EMCode": "138"
},
{
"QSid": "39",
"QDes": "/再见",
"IQLid": "4",
"AQLid": "4",
"EMCode": "139"
},
{
"QSid": "97",
"QDes": "/擦汗",
"IQLid": "6",
"AQLid": "6",
"EMCode": "140"
},
{
"QSid": "98",
"QDes": "/抠鼻",
"IQLid": "83",
"AQLid": "85",
"EMCode": "141"
},
{
"QSid": "99",
"QDes": "/鼓掌",
"IQLid": "84",
"AQLid": "86",
"EMCode": "142"
},
{
"QSid": "100",
"QDes": "/糗大了",
"IQLid": "85",
"AQLid": "87",
"EMCode": "143"
},
{
"QSid": "101",
"QDes": "/坏笑",
"IQLid": "46",
"AQLid": "46",
"EMCode": "144"
},
{
"QSid": "102",
"QDes": "/左哼哼",
"IQLid": "86",
"AQLid": "88",
"EMCode": "145"
},
{
"QSid": "103",
"QDes": "/右哼哼",
"IQLid": "44",
"AQLid": "44",
"EMCode": "146"
},
{
"QSid": "104",
"QDes": "/哈欠",
"IQLid": "87",
"AQLid": "89",
"EMCode": "147"
},
{
"QSid": "105",
"QDes": "/鄙视",
"IQLid": "48",
"AQLid": "48",
"EMCode": "148"
},
{
"QSid": "106",
"QDes": "/委屈",
"IQLid": "14",
"AQLid": "14",
"EMCode": "149"
},
{
"QSid": "107",
"QDes": "/快哭了",
"IQLid": "88",
"AQLid": "90",
"EMCode": "150"
},
{
"QSid": "108",
"QDes": "/阴险",
"IQLid": "41",
"AQLid": "41",
"EMCode": "151"
},
{
"QSid": "109",
"QDes": "/亲亲",
"IQLid": "36",
"AQLid": "36",
"EMCode": "152"
},
{
"QSid": "110",
"QDes": "/吓",
"IQLid": "89",
"AQLid": "91",
"EMCode": "153"
},
{
"QSid": "111",
"QDes": "/可怜",
"IQLid": "51",
"AQLid": "51",
"EMCode": "154"
},
{
"QSid": "172",
"QDes": "/眨眼睛",
"IQLid": "142",
"AQLid": "164",
"EMCode": "242"
},
{
"QSid": "182",
"QDes": "/笑哭",
"IQLid": "152",
"AQLid": "174",
"EMCode": "252"
},
{
"QSid": "179",
"QDes": "/doge",
"IQLid": "149",
"AQLid": "171",
"EMCode": "249"
},
{
"QSid": "173",
"QDes": "/泪奔",
"IQLid": "143",
"AQLid": "165",
"EMCode": "243"
},
{
"QSid": "174",
"QDes": "/无奈",
"IQLid": "144",
"AQLid": "166",
"EMCode": "244"
},
{
"QSid": "212",
"QDes": "/托腮",
"IQLid": "182",
"AQLid": "161",
"EMCode": "282"
},
{
"QSid": "175",
"QDes": "/卖萌",
"IQLid": "145",
"AQLid": "167",
"EMCode": "245"
},
{
"QSid": "178",
"QDes": "/斜眼笑",
"IQLid": "148",
"AQLid": "170",
"EMCode": "248"
},
{
"QSid": "177",
"QDes": "/喷血",
"IQLid": "147",
"AQLid": "169",
"EMCode": "247"
},
{
"QSid": "180",
"QDes": "/惊喜",
"IQLid": "150",
"AQLid": "172",
"EMCode": "250"
},
{
"QSid": "181",
"QDes": "/骚扰",
"IQLid": "151",
"AQLid": "173",
"EMCode": "251"
},
{
"QSid": "176",
"QDes": "/小纠结",
"IQLid": "146",
"AQLid": "168",
"EMCode": "246"
},
{
"QSid": "183",
"QDes": "/我最美",
"IQLid": "153",
"AQLid": "175",
"EMCode": "253"
},
{
"QSid": "245",
"QDes": "/加油必胜",
"IQLid": "245",
"AQLid": "217",
"EMCode": "202001"
},
{
"QSid": "246",
"QDes": "/加油抱抱",
"IQLid": "246",
"AQLid": "218",
"EMCode": "202002"
},
{
"QSid": "247",
"QDes": "/口罩护体",
"IQLid": "247",
"AQLid": "219",
"EMCode": "202003"
},
{
"QSid": "260",
"QDes": "/搬砖中",
"isStatic": "1",
"IQLid": "260",
"AQLid": "260",
"EMCode": "10260"
},
{
"QSid": "261",
"QDes": "/忙到飞起",
"IQLid": "261",
"AQLid": "261",
"EMCode": "10261"
},
{
"QSid": "262",
"QDes": "/脑阔疼",
"IQLid": "262",
"AQLid": "262",
"EMCode": "10262"
},
{
"QSid": "263",
"QDes": "/沧桑",
"IQLid": "263",
"AQLid": "263",
"EMCode": "10263"
},
{
"QSid": "264",
"QDes": "/捂脸",
"IQLid": "264",
"AQLid": "264",
"EMCode": "10264"
},
{
"QSid": "265",
"QDes": "/辣眼睛",
"IQLid": "265",
"AQLid": "265",
"EMCode": "10265"
},
{
"QSid": "266",
"QDes": "/哦哟",
"IQLid": "266",
"AQLid": "266",
"EMCode": "10266"
},
{
"QSid": "267",
"QDes": "/头秃",
"IQLid": "267",
"AQLid": "267",
"EMCode": "10267"
},
{
"QSid": "268",
"QDes": "/问号脸",
"IQLid": "268",
"AQLid": "268",
"EMCode": "10268"
},
{
"QSid": "269",
"QDes": "/暗中观察",
"IQLid": "269",
"AQLid": "269",
"EMCode": "10269"
},
{
"QSid": "270",
"QDes": "/emm",
"IQLid": "270",
"AQLid": "270",
"EMCode": "10270"
},
{
"QSid": "271",
"QDes": "/吃瓜",
"IQLid": "271",
"AQLid": "271",
"EMCode": "10271"
},
{
"QSid": "272",
"QDes": "/呵呵哒",
"IQLid": "272",
"AQLid": "272",
"EMCode": "10272"
},
{
"QSid": "277",
"QDes": "/汪汪",
"isStatic": "1",
"IQLid": "277",
"AQLid": "277",
"EMCode": "10277"
},
{
"QSid": "281",
"QDes": "/无眼笑",
"IQLid": "281",
"AQLid": "281",
"EMCode": "10281"
},
{
"QSid": "282",
"QDes": "/敬礼",
"IQLid": "282",
"AQLid": "282",
"EMCode": "10282"
},
{
"QSid": "283",
"QDes": "/狂笑",
"IQLid": "283",
"AQLid": "283",
"EMCode": "10283"
},
{
"QSid": "284",
"QDes": "/面无表情",
"IQLid": "284",
"AQLid": "284",
"EMCode": "10284"
},
{
"QSid": "285",
"QDes": "/摸鱼",
"IQLid": "285",
"AQLid": "285",
"EMCode": "10285"
},
{
"QSid": "286",
"QDes": "/魔鬼笑",
"IQLid": "286",
"AQLid": "286",
"EMCode": "10286"
},
{
"QSid": "287",
"QDes": "/哦",
"IQLid": "287",
"AQLid": "287",
"EMCode": "10287"
},
{
"QSid": "288",
"QDes": "/请",
"IQLid": "288",
"AQLid": "288",
"EMCode": "10288"
},
{
"QSid": "289",
"QDes": "/睁眼",
"IQLid": "289",
"AQLid": "289",
"EMCode": "10289"
},
{
"QSid": "273",
"QDes": "/我酸了",
"isStatic": "1",
"IQLid": "273",
"AQLid": "273",
"EMCode": "10273"
},
{
"QSid": "274",
"QDes": "/太南了",
"isStatic": "1",
"IQLid": "274",
"AQLid": "274",
"EMCode": "10274"
},
{
"QSid": "112",
"QDes": "/菜刀",
"IQLid": "17",
"AQLid": "17",
"EMCode": "155"
},
{
"QSid": "89",
"QDes": "/西瓜",
"isStatic": "1",
"IQLid": "60",
"AQLid": "60",
"EMCode": "156"
},
{
"QSid": "276",
"QDes": "/辣椒酱",
"isStatic": "1",
"IQLid": "276",
"AQLid": "276",
"QHide": "1",
"EMCode": "10276"
},
{
"QSid": "113",
"QDes": "/啤酒",
"IQLid": "61",
"AQLid": "61",
"EMCode": "157"
},
{
"QSid": "114",
"QDes": "/篮球",
"IQLid": "90",
"AQLid": "92",
"EMCode": "158"
},
{
"QSid": "115",
"QDes": "/乒乓",
"IQLid": "91",
"AQLid": "93",
"EMCode": "159"
},
{
"QSid": "171",
"QDes": "/茶",
"IQLid": "141",
"AQLid": "163",
"EMCode": "241"
},
{
"QSid": "60",
"QDes": "/咖啡",
"IQLid": "66",
"AQLid": "66",
"EMCode": "160"
},
{
"QSid": "61",
"QDes": "/饭",
"isStatic": "1",
"IQLid": "58",
"AQLid": "58",
"EMCode": "161"
},
{
"QSid": "46",
"QDes": "/猪头",
"isStatic": "1",
"IQLid": "7",
"AQLid": "7",
"EMCode": "162"
},
{
"QSid": "63",
"QDes": "/玫瑰",
"isStatic": "1",
"IQLid": "8",
"AQLid": "8",
"EMCode": "163"
},
{
"QSid": "64",
"QDes": "/凋谢",
"isStatic": "1",
"IQLid": "57",
"AQLid": "57",
"EMCode": "164"
},
{
"QSid": "116",
"QDes": "/示爱",
"IQLid": "29",
"AQLid": "29",
"EMCode": "165"
},
{
"QSid": "66",
"QDes": "/爱心",
"IQLid": "28",
"AQLid": "28",
"EMCode": "166"
},
{
"QSid": "67",
"QDes": "/心碎",
"IQLid": "72",
"AQLid": "74",
"EMCode": "167"
},
{
"QSid": "53",
"QDes": "/蛋糕",
"IQLid": "59",
"AQLid": "59",
"EMCode": "168"
},
{
"QSid": "54",
"QDes": "/闪电",
"isStatic": "1",
"IQLid": "78",
"AQLid": "80",
"EMCode": "169"
},
{
"QSid": "55",
"QDes": "/炸弹",
"isStatic": "1",
"IQLid": "16",
"AQLid": "16",
"EMCode": "170"
},
{
"QSid": "56",
"QDes": "/刀",
"IQLid": "68",
"AQLid": "70",
"EMCode": "171"
},
{
"QSid": "145",
"QDes": "/祈祷",
"isStatic": "1",
"IQLid": "115",
"AQLid": "117",
"EMCode": "121010"
},
{
"QSid": "57",
"QDes": "/足球",
"IQLid": "75",
"AQLid": "77",
"EMCode": "172"
},
{
"QSid": "117",
"QDes": "/瓢虫",
"IQLid": "62",
"AQLid": "62",
"EMCode": "173"
},
{
"QSid": "59",
"QDes": "/便便",
"IQLid": "15",
"AQLid": "15",
"EMCode": "174"
},
{
"QSid": "75",
"QDes": "/月亮",
"isStatic": "1",
"IQLid": "67",
"AQLid": "68",
"EMCode": "175"
},
{
"QSid": "74",
"QDes": "/太阳",
"isStatic": "1",
"IQLid": "73",
"AQLid": "75",
"EMCode": "176"
},
{
"QSid": "69",
"QDes": "/礼物",
"isStatic": "1",
"IQLid": "74",
"AQLid": "76",
"EMCode": "177"
},
{
"QSid": "49",
"QDes": "/拥抱",
"IQLid": "45",
"AQLid": "45",
"EMCode": "178"
},
{
"QSid": "76",
"QDes": "/赞",
"IQLid": "52",
"AQLid": "52",
"EMCode": "179"
},
{
"QSid": "77",
"QDes": "/踩",
"IQLid": "53",
"AQLid": "53",
"EMCode": "180"
},
{
"QSid": "78",
"QDes": "/握手",
"IQLid": "54",
"AQLid": "54",
"EMCode": "181"
},
{
"QSid": "79",
"QDes": "/胜利",
"IQLid": "55",
"AQLid": "55",
"EMCode": "182"
},
{
"QSid": "118",
"QDes": "/抱拳",
"IQLid": "56",
"AQLid": "56",
"EMCode": "183"
},
{
"QSid": "119",
"QDes": "/勾引",
"IQLid": "63",
"AQLid": "63",
"EMCode": "184"
},
{
"QSid": "120",
"QDes": "/拳头",
"IQLid": "71",
"AQLid": "73",
"EMCode": "185"
},
{
"QSid": "121",
"QDes": "/差劲",
"IQLid": "70",
"AQLid": "72",
"EMCode": "186"
},
{
"QSid": "122",
"QDes": "/爱你",
"IQLid": "65",
"AQLid": "65",
"EMCode": "187"
},
{
"QSid": "123",
"QDes": "/NO",
"IQLid": "92",
"AQLid": "94",
"EMCode": "188"
},
{
"QSid": "124",
"QDes": "/OK",
"isStatic": "1",
"IQLid": "64",
"AQLid": "64",
"EMCode": "189"
},
{
"QSid": "42",
"QDes": "/爱情",
"IQLid": "38",
"AQLid": "38",
"EMCode": "190"
},
{
"QSid": "85",
"QDes": "/飞吻",
"isStatic": "1",
"IQLid": "47",
"AQLid": "47",
"EMCode": "191"
},
{
"QSid": "43",
"QDes": "/跳跳",
"IQLid": "93",
"AQLid": "95",
"EMCode": "192"
},
{
"QSid": "41",
"QDes": "/发抖",
"isStatic": "1",
"IQLid": "69",
"AQLid": "71",
"EMCode": "193"
},
{
"QSid": "86",
"QDes": "/怄火",
"IQLid": "94",
"AQLid": "96",
"EMCode": "194"
},
{
"QSid": "125",
"QDes": "/转圈",
"IQLid": "95",
"AQLid": "97",
"EMCode": "195"
},
{
"QSid": "126",
"QDes": "/磕头",
"IQLid": "96",
"AQLid": "98",
"EMCode": "196"
},
{
"QSid": "127",
"QDes": "/回头",
"IQLid": "97",
"AQLid": "99",
"EMCode": "197"
},
{
"QSid": "128",
"QDes": "/跳绳",
"IQLid": "98",
"AQLid": "100",
"EMCode": "198"
},
{
"QSid": "129",
"QDes": "/挥手",
"IQLid": "77",
"AQLid": "79",
"EMCode": "199"
},
{
"QSid": "130",
"QDes": "/激动",
"IQLid": "99",
"AQLid": "101",
"EMCode": "200"
},
{
"QSid": "131",
"QDes": "/街舞",
"IQLid": "100",
"AQLid": "102",
"EMCode": "201"
},
{
"QSid": "132",
"QDes": "/献吻",
"IQLid": "101",
"AQLid": "103",
"EMCode": "202"
},
{
"QSid": "133",
"QDes": "/左太极",
"IQLid": "102",
"AQLid": "104",
"EMCode": "203"
},
{
"QSid": "134",
"QDes": "/右太极",
"IQLid": "103",
"AQLid": "105",
"EMCode": "204"
},
{
"QSid": "136",
"QDes": "/双喜",
"isStatic": "1",
"IQLid": "106",
"AQLid": "108",
"EMCode": "121001"
},
{
"QSid": "137",
"QDes": "/鞭炮",
"isStatic": "1",
"IQLid": "107",
"AQLid": "109",
"EMCode": "121002"
},
{
"QSid": "138",
"QDes": "/灯笼",
"isStatic": "1",
"IQLid": "108",
"AQLid": "110",
"EMCode": "121003"
},
{
"QSid": "140",
"QDes": "/K歌",
"isStatic": "1",
"IQLid": "110",
"AQLid": "112",
"EMCode": "121005"
},
{
"QSid": "144",
"QDes": "/喝彩",
"isStatic": "1",
"IQLid": "114",
"AQLid": "116",
"EMCode": "121009"
},
{
"QSid": "146",
"QDes": "/爆筋",
"isStatic": "1",
"IQLid": "116",
"AQLid": "118",
"EMCode": "121011"
},
{
"QSid": "147",
"QDes": "/棒棒糖",
"isStatic": "1",
"IQLid": "117",
"AQLid": "119",
"EMCode": "121012"
},
{
"QSid": "148",
"QDes": "/喝奶",
"isStatic": "1",
"IQLid": "118",
"AQLid": "120",
"EMCode": "121013"
},
{
"QSid": "151",
"QDes": "/飞机",
"isStatic": "1",
"IQLid": "121",
"AQLid": "123",
"EMCode": "121016"
},
{
"QSid": "158",
"QDes": "/钞票",
"isStatic": "1",
"IQLid": "128",
"AQLid": "130",
"EMCode": "121023"
},
{
"QSid": "168",
"QDes": "/药",
"isStatic": "1",
"IQLid": "138",
"AQLid": "140",
"EMCode": "121033"
},
{
"QSid": "169",
"QDes": "/手枪",
"isStatic": "1",
"IQLid": "139",
"AQLid": "141",
"EMCode": "121034"
},
{
"QSid": "188",
"QDes": "/蛋",
"IQLid": "158",
"AQLid": "180",
"EMCode": "258"
},
{
"QSid": "192",
"QDes": "/红包",
"IQLid": "162",
"AQLid": "184",
"EMCode": "262"
},
{
"QSid": "184",
"QDes": "/河蟹",
"IQLid": "154",
"AQLid": "176",
"EMCode": "254"
},
{
"QSid": "185",
"QDes": "/羊驼",
"IQLid": "155",
"AQLid": "177",
"EMCode": "255"
},
{
"QSid": "190",
"QDes": "/菊花",
"IQLid": "160",
"AQLid": "182",
"EMCode": "260"
},
{
"QSid": "187",
"QDes": "/幽灵",
"IQLid": "157",
"AQLid": "179",
"EMCode": "257"
},
{
"QSid": "193",
"QDes": "/大笑",
"IQLid": "163",
"AQLid": "185",
"EMCode": "263"
},
{
"QSid": "194",
"QDes": "/不开心",
"IQLid": "164",
"AQLid": "143",
"EMCode": "264"
},
{
"QSid": "197",
"QDes": "/冷漠",
"IQLid": "167",
"AQLid": "146",
"EMCode": "267"
},
{
"QSid": "198",
"QDes": "/呃",
"IQLid": "168",
"AQLid": "147",
"EMCode": "268"
},
{
"QSid": "199",
"QDes": "/好棒",
"IQLid": "169",
"AQLid": "148",
"EMCode": "269"
},
{
"QSid": "200",
"QDes": "/拜托",
"IQLid": "170",
"AQLid": "149",
"EMCode": "270"
},
{
"QSid": "201",
"QDes": "/点赞",
"IQLid": "171",
"AQLid": "150",
"EMCode": "271"
},
{
"QSid": "202",
"QDes": "/无聊",
"IQLid": "172",
"AQLid": "151",
"EMCode": "272"
},
{
"QSid": "203",
"QDes": "/托脸",
"IQLid": "173",
"AQLid": "152",
"EMCode": "273"
},
{
"QSid": "204",
"QDes": "/吃",
"IQLid": "174",
"AQLid": "153",
"EMCode": "274"
},
{
"QSid": "205",
"QDes": "/送花",
"IQLid": "175",
"AQLid": "154",
"EMCode": "275"
},
{
"QSid": "206",
"QDes": "/害怕",
"IQLid": "176",
"AQLid": "155",
"EMCode": "276"
},
{
"QSid": "207",
"QDes": "/花痴",
"IQLid": "177",
"AQLid": "156",
"EMCode": "277"
},
{
"QSid": "208",
"QDes": "/小样儿",
"IQLid": "178",
"AQLid": "157",
"EMCode": "278"
},
{
"QSid": "210",
"QDes": "/飙泪",
"IQLid": "180",
"AQLid": "159",
"EMCode": "280"
},
{
"QSid": "211",
"QDes": "/我不看",
"IQLid": "181",
"AQLid": "160",
"EMCode": "281"
},
{
"QSid": "278",
"QDes": "/汗",
"IQLid": "278",
"isCMEmoji": "1",
"AQLid": "278",
"EMCode": "20237"
},
{
"QSid": "279",
"QDes": "/打脸",
"IQLid": "279",
"isCMEmoji": "1",
"AQLid": "279",
"EMCode": "20238"
},
{
"QSid": "280",
"QDes": "/击掌",
"IQLid": "280",
"isCMEmoji": "1",
"AQLid": "280",
"EMCode": "20239"
},
{
"QSid": "242",
"QDes": "/头撞击",
"IQLid": "212",
"isCMEmoji": "1",
"AQLid": "214",
"EMCode": "314"
},
{
"QSid": "243",
"QDes": "/甩头",
"IQLid": "213",
"isCMEmoji": "1",
"AQLid": "215",
"EMCode": "313"
},
{
"QSid": "244",
"QDes": "/扔狗",
"IQLid": "214",
"isCMEmoji": "1",
"AQLid": "216",
"EMCode": "312"
},
{
"QSid": "215",
"QDes": "/糊脸",
"IQLid": "185",
"isCMEmoji": "1",
"AQLid": "187",
"EMCode": "285"
},
{
"QSid": "237",
"QDes": "/偷看",
"IQLid": "207",
"isCMEmoji": "1",
"AQLid": "209",
"EMCode": "307"
},
{
"QSid": "226",
"QDes": "/拍桌",
"IQLid": "196",
"isCMEmoji": "1",
"AQLid": "198",
"EMCode": "297"
},
{
"QSid": "214",
"QDes": "/啵啵",
"IQLid": "184",
"isCMEmoji": "1",
"AQLid": "186",
"EMCode": "284"
},
{
"QSid": "217",
"QDes": "/扯一扯",
"IQLid": "187",
"isCMEmoji": "1",
"AQLid": "189",
"EMCode": "287"
},
{
"QSid": "240",
"QDes": "/喷脸",
"IQLid": "210",
"isCMEmoji": "1",
"AQLid": "212",
"EMCode": "310"
},
{
"QSid": "216",
"QDes": "/拍头",
"IQLid": "186",
"isCMEmoji": "1",
"AQLid": "188",
"EMCode": "286"
},
{
"QSid": "218",
"QDes": "/舔一舔",
"IQLid": "188",
"isCMEmoji": "1",
"AQLid": "190",
"EMCode": "288"
},
{
"QSid": "229",
"QDes": "/干杯",
"IQLid": "199",
"isCMEmoji": "1",
"AQLid": "201",
"EMCode": "299"
},
{
"QSid": "238",
"QDes": "/扇脸",
"IQLid": "208",
"isCMEmoji": "1",
"AQLid": "210",
"EMCode": "308"
},
{
"QSid": "219",
"QDes": "/蹭一蹭",
"IQLid": "189",
"isCMEmoji": "1",
"AQLid": "191",
"EMCode": "289"
},
{
"QSid": "225",
"QDes": "/撩一撩",
"IQLid": "195",
"isCMEmoji": "1",
"AQLid": "197",
"EMCode": "296"
},
{
"QSid": "231",
"QDes": "/哼",
"IQLid": "201",
"isCMEmoji": "1",
"AQLid": "203",
"EMCode": "301"
},
{
"QSid": "233",
"QDes": "/掐一掐",
"IQLid": "203",
"isCMEmoji": "1",
"AQLid": "205",
"EMCode": "303"
},
{
"QSid": "221",
"QDes": "/顶呱呱",
"IQLid": "191",
"isCMEmoji": "1",
"AQLid": "193",
"EMCode": "291"
},
{
"QSid": "222",
"QDes": "/抱抱",
"IQLid": "192",
"isCMEmoji": "1",
"AQLid": "194",
"EMCode": "292"
},
{
"QSid": "239",
"QDes": "/原谅",
"IQLid": "209",
"isCMEmoji": "1",
"AQLid": "211",
"EMCode": "309"
},
{
"QSid": "232",
"QDes": "/佛系",
"IQLid": "202",
"isCMEmoji": "1",
"AQLid": "204",
"EMCode": "302"
},
{
"QSid": "220",
"QDes": "/拽炸天",
"IQLid": "190",
"isCMEmoji": "1",
"AQLid": "192",
"EMCode": "290"
},
{
"QSid": "235",
"QDes": "/颤抖",
"IQLid": "205",
"isCMEmoji": "1",
"AQLid": "207",
"EMCode": "305"
},
{
"QSid": "241",
"QDes": "/生日快乐",
"IQLid": "211",
"isCMEmoji": "1",
"AQLid": "213",
"EMCode": "311"
},
{
"QSid": "230",
"QDes": "/嘲讽",
"IQLid": "200",
"isCMEmoji": "1",
"AQLid": "202",
"EMCode": "300"
},
{
"QSid": "224",
"QDes": "/开枪",
"IQLid": "194",
"isCMEmoji": "1",
"AQLid": "196",
"EMCode": "295"
},
{
"QSid": "236",
"QDes": "/啃头",
"IQLid": "206",
"isCMEmoji": "1",
"AQLid": "208",
"EMCode": "306"
},
{
"QSid": "228",
"QDes": "/恭喜",
"IQLid": "198",
"isCMEmoji": "1",
"AQLid": "200",
"EMCode": "298"
},
{
"QSid": "234",
"QDes": "/惊呆",
"IQLid": "204",
"isCMEmoji": "1",
"AQLid": "206",
"EMCode": "304"
},
{
"QSid": "223",
"QDes": "/暴击",
"IQLid": "193",
"isCMEmoji": "1",
"AQLid": "195",
"EMCode": "293"
},
{
"QSid": "227",
"QDes": "/拍手",
"IQLid": "197",
"isCMEmoji": "1",
"AQLid": "199",
"EMCode": "294"
}
],
"emoji": [
{
"QSid": "😊",
"QCid": "128522",
"AQLid": "0",
"QDes": "/嘿嘿",
"EMCode": "400832"
},
{
"QSid": "😌",
"QCid": "128524",
"AQLid": "1",
"QDes": "/羞涩",
"EMCode": "400834"
},
{
"QSid": "😚",
"QCid": "128538",
"AQLid": "2",
"QDes": "/亲亲",
"EMCode": "400848"
},
{
"QSid": "😓",
"QCid": "128531",
"AQLid": "3",
"QDes": "/汗",
"EMCode": "400841"
},
{
"QSid": "😰",
"QCid": "128560",
"AQLid": "4",
"QDes": "/紧张",
"EMCode": "400870"
},
{
"QSid": "😝",
"QCid": "128541",
"AQLid": "5",
"QDes": "/吐舌",
"EMCode": "400851"
},
{
"QSid": "😁",
"QCid": "128513",
"AQLid": "6",
"QDes": "/呲牙",
"EMCode": "400823"
},
{
"QSid": "😜",
"QCid": "128540",
"AQLid": "7",
"QDes": "/淘气",
"EMCode": "400850"
},
{
"QSid": "☺",
"QCid": "9786",
"AQLid": "8",
"QDes": "/可爱",
"EMCode": "401181"
},
{
"QSid": "😉",
"QCid": "128521",
"AQLid": "9",
"QDes": "/媚眼",
"EMCode": "400831"
},
{
"QSid": "😍",
"QCid": "128525",
"AQLid": "10",
"QDes": "/花痴",
"EMCode": "400835"
},
{
"QSid": "😔",
"QCid": "128532",
"AQLid": "11",
"QDes": "/失落",
"EMCode": "400842"
},
{
"QSid": "😄",
"QCid": "128516",
"AQLid": "12",
"QDes": "/高兴",
"EMCode": "400826"
},
{
"QSid": "😏",
"QCid": "128527",
"AQLid": "13",
"QDes": "/哼哼",
"EMCode": "400837"
},
{
"QSid": "😒",
"QCid": "128530",
"AQLid": "14",
"QDes": "/不屑",
"EMCode": "400840"
},
{
"QSid": "😳",
"QCid": "128563",
"AQLid": "15",
"QDes": "/瞪眼",
"EMCode": "400873"
},
{
"QSid": "😘",
"QCid": "128536",
"AQLid": "16",
"QDes": "/飞吻",
"EMCode": "400846"
},
{
"QSid": "😭",
"QCid": "128557",
"AQLid": "17",
"QDes": "/大哭",
"EMCode": "400867"
},
{
"QSid": "😱",
"QCid": "128561",
"AQLid": "18",
"QDes": "/害怕",
"EMCode": "400871"
},
{
"QSid": "😂",
"QCid": "128514",
"AQLid": "19",
"QDes": "/激动",
"EMCode": "400824"
},
{
"QSid": "💪",
"QCid": "128170",
"AQLid": "20",
"QDes": "/肌肉",
"EMCode": "400644"
},
{
"QSid": "👊",
"QCid": "128074",
"AQLid": "21",
"QDes": "/拳头",
"EMCode": "400390"
},
{
"QSid": "👍",
"QCid": "128077",
"AQLid": "22",
"QDes": "/厉害",
"EMCode": "400408"
},
{
"QSid": "☝",
"QCid": "9757",
"AQLid": "23",
"QDes": "/向上",
"EMCode": "401203"
},
{
"QSid": "👏",
"QCid": "128079",
"AQLid": "24",
"QDes": "/鼓掌",
"EMCode": "400420"
},
{
"QSid": "✌",
"QCid": "9996",
"AQLid": "25",
"QDes": "/胜利",
"EMCode": "401210"
},
{
"QSid": "👎",
"QCid": "128078",
"AQLid": "26",
"QDes": "/鄙视",
"EMCode": "400414"
},
{
"QSid": "🙏",
"QCid": "128591",
"AQLid": "27",
"QDes": "/合十",
"EMCode": "400396"
},
{
"QSid": "👌",
"QCid": "128076",
"AQLid": "28",
"QDes": "/好的",
"EMCode": "400402"
},
{
"QSid": "👈",
"QCid": "128072",
"AQLid": "29",
"QDes": "/向左",
"EMCode": "400378"
},
{
"QSid": "👉",
"QCid": "128073",
"AQLid": "30",
"QDes": "/向右",
"EMCode": "400384"
},
{
"QSid": "👆",
"QCid": "128070",
"AQLid": "31",
"QDes": "/向上",
"EMCode": "400366"
},
{
"QSid": "👇",
"QCid": "128071",
"AQLid": "32",
"QDes": "/向下",
"EMCode": "400372"
},
{
"QSid": "👀",
"QCid": "128064",
"AQLid": "33",
"QDes": "/眼睛",
"EMCode": "400351"
},
{
"QSid": "👃",
"QCid": "128067",
"AQLid": "34",
"QDes": "/鼻子",
"EMCode": "400358"
},
{
"QSid": "👄",
"QCid": "128068",
"AQLid": "35",
"QDes": "/嘴唇",
"EMCode": "400364"
},
{
"QSid": "👂",
"QCid": "128066",
"AQLid": "36",
"QDes": "/耳朵",
"EMCode": "400352"
},
{
"QSid": "🍚",
"QCid": "127834",
"AQLid": "37",
"QDes": "/米饭",
"EMCode": "400149"
},
{
"QSid": "🍝",
"QCid": "127837",
"AQLid": "38",
"QDes": "/意面",
"EMCode": "400152"
},
{
"QSid": "🍜",
"QCid": "127836",
"AQLid": "39",
"QDes": "/拉面",
"EMCode": "400151"
},
{
"QSid": "🍙",
"QCid": "127833",
"AQLid": "40",
"QDes": "/饭团",
"EMCode": "400148"
},
{
"QSid": "🍧",
"QCid": "127847",
"AQLid": "41",
"QDes": "/刨冰",
"EMCode": "400162"
},
{
"QSid": "🍣",
"QCid": "127843",
"AQLid": "42",
"QDes": "/寿司",
"EMCode": "400158"
},
{
"QSid": "🎂",
"QCid": "127874",
"AQLid": "43",
"QDes": "/蛋糕",
"EMCode": "400186"
},
{
"QSid": "🍞",
"QCid": "127838",
"AQLid": "44",
"QDes": "/面包",
"EMCode": "400153"
},
{
"QSid": "🍔",
"QCid": "127828",
"AQLid": "45",
"QDes": "/汉堡",
"EMCode": "400143"
},
{
"QSid": "🍳",
"QCid": "127859",
"AQLid": "46",
"QDes": "/煎蛋",
"EMCode": "400174"
},
{
"QSid": "🍟",
"QCid": "127839",
"AQLid": "47",
"QDes": "/薯条",
"EMCode": "400154"
},
{
"QSid": "🍺",
"QCid": "127866",
"AQLid": "48",
"QDes": "/啤酒",
"EMCode": "400181"
},
{
"QSid": "🍻",
"QCid": "127867",
"AQLid": "49",
"QDes": "/干杯",
"EMCode": "400182"
},
{
"QSid": "🍸",
"QCid": "127864",
"AQLid": "50",
"QDes": "/高脚杯",
"EMCode": "400179"
},
{
"QSid": "☕",
"QCid": "9749",
"AQLid": "51",
"QDes": "/咖啡",
"EMCode": "401262"
},
{
"QSid": "🍎",
"QCid": "127822",
"AQLid": "52",
"QDes": "/苹果",
"EMCode": "400137"
},
{
"QSid": "🍊",
"QCid": "127818",
"AQLid": "53",
"QDes": "/橙子",
"EMCode": "400133"
},
{
"QSid": "🍓",
"QCid": "127827",
"AQLid": "54",
"QDes": "/草莓",
"EMCode": "400142"
},
{
"QSid": "🍉",
"QCid": "127817",
"AQLid": "55",
"QDes": "/西瓜",
"EMCode": "400132"
},
{
"QSid": "💊",
"QCid": "128138",
"AQLid": "56",
"QDes": "/药丸",
"EMCode": "400612"
},
{
"QSid": "🚬",
"QCid": "128684",
"AQLid": "57",
"QDes": "/吸烟",
"EMCode": "400987"
},
{
"QSid": "🎄",
"QCid": "127876",
"AQLid": "58",
"QDes": "/圣诞树",
"EMCode": "400188"
},
{
"QSid": "🌹",
"QCid": "127801",
"AQLid": "59",
"QDes": "/玫瑰",
"EMCode": "400116"
},
{
"QSid": "🎉",
"QCid": "127881",
"AQLid": "60",
"QDes": "/庆祝",
"EMCode": "400198"
},
{
"QSid": "🌴",
"QCid": "127796",
"AQLid": "61",
"QDes": "/椰子树",
"EMCode": "400112"
},
{
"QSid": "💝",
"QCid": "128157",
"AQLid": "62",
"QDes": "/礼物",
"EMCode": "400631"
},
{
"QSid": "🎀",
"QCid": "127872",
"AQLid": "63",
"QDes": "/蝴蝶结",
"EMCode": "400184"
},
{
"QSid": "🎈",
"QCid": "127880",
"AQLid": "64",
"QDes": "/气球",
"EMCode": "400197"
},
{
"QSid": "🐚",
"QCid": "128026",
"AQLid": "65",
"QDes": "/海螺",
"EMCode": "400314"
},
{
"QSid": "💍",
"QCid": "128141",
"AQLid": "66",
"QDes": "/戒指",
"EMCode": "400615"
},
{
"QSid": "💣",
"QCid": "128163",
"AQLid": "67",
"QDes": "/炸弹",
"EMCode": "400637"
},
{
"QSid": "👑",
"QCid": "128081",
"AQLid": "68",
"QDes": "/皇冠",
"EMCode": "400432"
},
{
"QSid": "🔔",
"QCid": "128276",
"AQLid": "69",
"QDes": "/铃铛",
"EMCode": "400751"
},
{
"QSid": "⭐",
"QCid": "11088",
"AQLid": "70",
"QDes": "/星星",
"EMCode": "401686"
},
{
"QSid": "✨",
"QCid": "10024",
"AQLid": "71",
"QDes": "/闪光",
"EMCode": "401137"
},
{
"QSid": "💨",
"QCid": "128168",
"AQLid": "72",
"QDes": "/吹气",
"EMCode": "400642"
},
{
"QSid": "💦",
"QCid": "128166",
"AQLid": "73",
"QDes": "/水",
"EMCode": "400640"
},
{
"QSid": "🔥",
"QCid": "128293",
"AQLid": "74",
"QDes": "/火",
"EMCode": "400768"
},
{
"QSid": "🏆",
"QCid": "127942",
"AQLid": "75",
"QDes": "/奖杯",
"EMCode": "400256"
},
{
"QSid": "💰",
"QCid": "128176",
"AQLid": "76",
"QDes": "/钱",
"EMCode": "400655"
},
{
"QSid": "💤",
"QCid": "128164",
"AQLid": "77",
"QDes": "/睡觉",
"EMCode": "400638"
},
{
"QSid": "⚡",
"QCid": "9889",
"AQLid": "78",
"QDes": "/闪电",
"EMCode": "401685"
},
{
"QSid": "👣",
"QCid": "128099",
"AQLid": "79",
"QDes": "/脚印",
"EMCode": "400450"
},
{
"QSid": "💩",
"QCid": "128169",
"AQLid": "80",
"QDes": "/便便",
"EMCode": "400643"
},
{
"QSid": "💉",
"QCid": "128137",
"AQLid": "81",
"QDes": "/打针",
"EMCode": "400611"
},
{
"QSid": "♨",
"QCid": "9832",
"AQLid": "82",
"QDes": "/热",
"EMCode": "401287"
},
{
"QSid": "📫",
"QCid": "128235",
"AQLid": "83",
"QDes": "/邮箱",
"EMCode": "400714"
},
{
"QSid": "🔑",
"QCid": "128273",
"AQLid": "84",
"QDes": "/钥匙",
"EMCode": "400748"
},
{
"QSid": "🔒",
"QCid": "128274",
"AQLid": "85",
"QDes": "/锁",
"EMCode": "400749"
},
{
"QSid": "✈",
"QCid": "9992",
"AQLid": "86",
"QDes": "/飞机",
"EMCode": "401298"
},
{
"QSid": "🚄",
"QCid": "128644",
"AQLid": "87",
"QDes": "/列车",
"EMCode": "400942"
},
{
"QSid": "🚗",
"QCid": "128663",
"AQLid": "88",
"QDes": "/汽车",
"EMCode": "400961"
},
{
"QSid": "🚤",
"QCid": "128676",
"AQLid": "89",
"QDes": "/快艇",
"EMCode": "400979"
},
{
"QSid": "🚲",
"QCid": "128690",
"AQLid": "90",
"QDes": "/自行车",
"EMCode": "400993"
},
{
"QSid": "🐎",
"QCid": "128014",
"AQLid": "91",
"QDes": "/骑马",
"EMCode": "400302"
},
{
"QSid": "🚀",
"QCid": "128640",
"AQLid": "92",
"QDes": "/火箭",
"EMCode": "400938"
},
{
"QSid": "🚌",
"QCid": "128652",
"AQLid": "93",
"QDes": "/公交",
"EMCode": "400950"
},
{
"QSid": "⛵",
"QCid": "9973",
"AQLid": "94",
"QDes": "/船",
"EMCode": "401294"
},
{
"QSid": "👩",
"QCid": "128105",
"AQLid": "95",
"QDes": "/妈妈",
"EMCode": "400482"
},
{
"QSid": "👨",
"QCid": "128104",
"AQLid": "96",
"QDes": "/爸爸",
"EMCode": "400465"
},
{
"QSid": "👧",
"QCid": "128103",
"AQLid": "97",
"QDes": "/女孩",
"EMCode": "400459"
},
{
"QSid": "👦",
"QCid": "128102",
"AQLid": "98",
"QDes": "/男孩",
"EMCode": "400453"
},
{
"QSid": "🐵",
"QCid": "128053",
"AQLid": "99",
"QDes": "/猴",
"EMCode": "400341"
},
{
"QSid": "🐙",
"QCid": "128025",
"AQLid": "100",
"QDes": "/章鱼",
"EMCode": "400313"
},
{
"QSid": "🐷",
"QCid": "128055",
"AQLid": "101",
"QDes": "/猪",
"EMCode": "400343"
},
{
"QSid": "💀",
"QCid": "128128",
"AQLid": "102",
"QDes": "/骷髅",
"EMCode": "400572"
},
{
"QSid": "🐤",
"QCid": "128036",
"AQLid": "103",
"QDes": "/小鸡",
"EMCode": "400324"
},
{
"QSid": "🐨",
"QCid": "128040",
"AQLid": "104",
"QDes": "/树懒",
"EMCode": "400328"
},
{
"QSid": "🐮",
"QCid": "128046",
"AQLid": "105",
"QDes": "/牛",
"EMCode": "400334"
},
{
"QSid": "🐔",
"QCid": "128020",
"AQLid": "106",
"QDes": "/公鸡",
"EMCode": "400308"
},
{
"QSid": "🐸",
"QCid": "128056",
"AQLid": "107",
"QDes": "/青蛙",
"EMCode": "400344"
},
{
"QSid": "👻",
"QCid": "128123",
"AQLid": "108",
"QDes": "/幽灵",
"EMCode": "400562"
},
{
"QSid": "🐛",
"QCid": "128027",
"AQLid": "109",
"QDes": "/虫",
"EMCode": "400315"
},
{
"QSid": "🐠",
"QCid": "128032",
"AQLid": "110",
"QDes": "/鱼",
"EMCode": "400320"
},
{
"QSid": "🐶",
"QCid": "128054",
"AQLid": "111",
"QDes": "/狗",
"EMCode": "400342"
},
{
"QSid": "🐯",
"QCid": "128047",
"AQLid": "112",
"QDes": "/老虎",
"EMCode": "400335"
},
{
"QSid": "👼",
"QCid": "128124",
"AQLid": "113",
"QDes": "/天使",
"EMCode": "400563"
},
{
"QSid": "🐧",
"QCid": "128039",
"AQLid": "114",
"QDes": "/企鹅",
"EMCode": "400327"
},
{
"QSid": "🐳",
"QCid": "128051",
"AQLid": "115",
"QDes": "/鲸鱼",
"EMCode": "400339"
},
{
"QSid": "🐭",
"QCid": "128045",
"AQLid": "116",
"QDes": "/老鼠",
"EMCode": "400333"
},
{
"QSid": "👒",
"QCid": "128082",
"AQLid": "117",
"QDes": "/帽子",
"EMCode": "400433"
},
{
"QSid": "👗",
"QCid": "128087",
"AQLid": "118",
"QDes": "/连衣裙",
"EMCode": "400438"
},
{
"QSid": "💄",
"QCid": "128132",
"AQLid": "119",
"QDes": "/口红",
"EMCode": "400591"
},
{
"QSid": "👠",
"QCid": "128096",
"AQLid": "120",
"QDes": "/高跟鞋",
"EMCode": "400447"
},
{
"QSid": "👢",
"QCid": "128098",
"AQLid": "121",
"QDes": "/靴子",
"EMCode": "400449"
},
{
"QSid": "🌂",
"QCid": "127746",
"AQLid": "122",
"QDes": "/雨伞",
"EMCode": "400077"
},
{
"QSid": "👜",
"QCid": "128092",
"AQLid": "123",
"QDes": "/包",
"EMCode": "400443"
},
{
"QSid": "👙",
"QCid": "128089",
"AQLid": "124",
"QDes": "/内衣",
"EMCode": "400440"
},
{
"QSid": "👕",
"QCid": "128085",
"AQLid": "125",
"QDes": "/衣服",
"EMCode": "400436"
},
{
"QSid": "👟",
"QCid": "128095",
"AQLid": "126",
"QDes": "/鞋子",
"EMCode": "400446"
},
{
"QSid": "☁",
"QCid": "9729",
"AQLid": "127",
"QDes": "/云朵",
"EMCode": "401329"
},
{
"QSid": "☀",
"QCid": "9728",
"AQLid": "128",
"QDes": "/晴天",
"EMCode": "401328"
},
{
"QSid": "☔",
"QCid": "9748",
"AQLid": "129",
"QDes": "/雨天",
"EMCode": "401342"
},
{
"QSid": "🌙",
"QCid": "127769",
"AQLid": "130",
"QDes": "/月亮",
"EMCode": "400100"
},
{
"QSid": "⛄",
"QCid": "9924",
"AQLid": "131",
"QDes": "/雪人",
"EMCode": "401346"
},
{
"QSid": "⭕",
"QCid": "11093",
"AQLid": "132",
"QDes": "/正确",
"EMCode": "401687"
},
{
"QSid": "❌",
"QCid": "10060",
"AQLid": "133",
"QDes": "/错误",
"EMCode": "401142"
},
{
"QSid": "❔",
"QCid": "10068",
"AQLid": "134",
"QDes": "/问号",
"EMCode": "401145"
},
{
"QSid": "❕",
"QCid": "10069",
"AQLid": "135",
"QDes": "/叹号",
"EMCode": "401146"
},
{
"QSid": "☎",
"QCid": "9742",
"AQLid": "136",
"QDes": "/电话",
"EMCode": "401398"
},
{
"QSid": "📷",
"QCid": "128247",
"AQLid": "137",
"QDes": "/相机",
"EMCode": "400726"
},
{
"QSid": "📱",
"QCid": "128241",
"AQLid": "138",
"QDes": "/手机",
"EMCode": "400720"
},
{
"QSid": "📠",
"QCid": "128224",
"AQLid": "139",
"QDes": "/传真",
"EMCode": "400703"
},
{
"QSid": "💻",
"QCid": "128187",
"AQLid": "140",
"QDes": "/电脑",
"EMCode": "400666"
},
{
"QSid": "🎥",
"QCid": "127909",
"AQLid": "141",
"QDes": "/摄影机",
"EMCode": "400214"
},
{
"QSid": "🎤",
"QCid": "127908",
"AQLid": "142",
"QDes": "/话筒",
"EMCode": "400213"
},
{
"QSid": "🔫",
"QCid": "128299",
"AQLid": "143",
"QDes": "/手枪",
"EMCode": "400774"
},
{
"QSid": "💿",
"QCid": "128191",
"AQLid": "144",
"QDes": "/光碟",
"EMCode": "400670"
},
{
"QSid": "💓",
"QCid": "128147",
"AQLid": "145",
"QDes": "/爱心",
"EMCode": "400621"
},
{
"QSid": "♣",
"QCid": "9827",
"AQLid": "146",
"QDes": "/扑克",
"EMCode": "401385"
},
{
"QSid": "🀄",
"QCid": "126980",
"AQLid": "147",
"QDes": "/麻将",
"EMCode": "401386"
},
{
"QSid": "〽",
"QCid": "12349",
"AQLid": "148",
"QDes": "/股票",
"EMCode": "401691"
},
{
"QSid": "🎰",
"QCid": "127920",
"AQLid": "149",
"QDes": "/老虎机",
"EMCode": "400225"
},
{
"QSid": "🚥",
"QCid": "128677",
"AQLid": "150",
"QDes": "/信号灯",
"EMCode": "400980"
},
{
"QSid": "🚧",
"QCid": "128679",
"AQLid": "151",
"QDes": "/路障",
"EMCode": "400982"
},
{
"QSid": "🎸",
"QCid": "127928",
"AQLid": "152",
"QDes": "/吉他",
"EMCode": "400233"
},
{
"QSid": "💈",
"QCid": "128136",
"AQLid": "153",
"QDes": "/理发厅",
"EMCode": "400610"
},
{
"QSid": "🛀",
"QCid": "128704",
"AQLid": "154",
"QDes": "/浴缸",
"EMCode": "401022"
},
{
"QSid": "🚽",
"QCid": "128701",
"AQLid": "155",
"QDes": "/马桶",
"EMCode": "401019"
},
{
"QSid": "🏠",
"QCid": "127968",
"AQLid": "156",
"QDes": "/家",
"EMCode": "400271"
},
{
"QSid": "⛪",
"QCid": "9962",
"AQLid": "157",
"QDes": "/教堂",
"EMCode": "401281"
},
{
"QSid": "🏦",
"QCid": "127974",
"AQLid": "158",
"QDes": "/银行",
"EMCode": "400277"
},
{
"QSid": "🏥",
"QCid": "127973",
"AQLid": "159",
"QDes": "/医院",
"EMCode": "400276"
},
{
"QSid": "🏨",
"QCid": "127976",
"AQLid": "160",
"QDes": "/酒店",
"EMCode": "400279"
},
{
"QSid": "🏧",
"QCid": "127975",
"AQLid": "161",
"QDes": "/取款机",
"EMCode": "400278"
},
{
"QSid": "🏪",
"QCid": "127978",
"AQLid": "162",
"QDes": "/便利店",
"EMCode": "400281"
},
{
"QSid": "🚹",
"QCid": "128697",
"AQLid": "163",
"QDes": "/男性",
"EMCode": "401015"
},
{
"QSid": "🚺",
"QCid": "128698",
"AQLid": "164",
"QDes": "/女性",
"EMCode": "401016"
}
]
}
================================================
FILE: icon.py
================================================
qq_icon_png = b'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'
github_mark = b'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'
================================================
FILE: install.ps1
================================================
pyinstaller -i icon.ico -w -F ./GUI.py
sleep 5
================================================
FILE: proto/RichMsg.proto
================================================
syntax = "proto3";
message ForwardExtra {
int32 forward_orgId = 1;
string forward_orgUin = 2;
int32 forward_orgUinType = 3;
string forward_orgUrl = 4;
string forward_thumbPath = 5;
int32 forward_orgFileSizeType = 6;
}
message PicRec {
string localPath = 1;
int32 size = 2;
int32 type = 3;
bool isRead = 4;
string uuid = 5;
string md5 = 6;
string serverStorageSource = 7;
string thumbMsgUrl = 8;
string bigMsgUrl = 9;
string rawMsgUrl = 10;
int32 fileSizeFlag = 11;
int32 uiOperatorFlag = 12;
ForwardExtra forwardInfo = 13;
int32 version = 14;
int32 isReport = 15;
uint64 groupFileID = 16;
string localUUID = 17;
int32 preDownState = 18;
int32 preDownNetwork = 19;
int32 previewed = 20;
uint32 uint32_thumb_width = 21;
uint32 uint32_thumb_height = 22;
uint32 uint32_width = 23;
uint32 uint32_height = 24;
uint32 uint32_image_type = 25;
uint32 uint32_show_len = 26;
uint32 uint32_download_len = 27;
uint32 uint32_current_len = 28;
uint32 notPreDownloadReason = 29;
bool enableEnc = 30;
string bigThumbMsgUrl = 31;
bytes bytes_pb_reserved = 32;
bool bool_story_pic_send_to_recent = 33;
}
message MarketFaceRec {
}
message Msg {
repeated Elem elems = 1;
}
message Elem {
bytes textMsg = 1;
bytes picMsg = 2;
MarketFaceRec markfaceMsg = 3;
string sourceMsgInfo = 4;
}
message SafeMoreInfo {
string strMsgTxt = 1;
string strFromMobile = 2;
string strFromName = 3;
}
message Test {
string str = 16;
}
message PttRec {
string localPath = 1;
uint64 size = 2;
uint32 type = 3;
bool isRead = 4;
string uuid = 5;
string md5 = 6;
string serverStorageSource = 7;
int32 version = 8;
int32 isReport = 9;
int32 pttFlag = 10;
uint64 groupFileID = 11;
string sttText = 12;
int32 longPttVipFlag = 13;
bool expandStt = 14;
string group_file_key = 15;
uint64 msgRecTime = 16;
uint64 msgTime = 17;
uint32 voiceType = 18;
uint32 voiceLength = 19;
uint32 voiceChangeFlag = 20;
string directUrl = 21;
uint32 busiType = 22;
string fullLocalPath = 23;
uint64 extFlag = 24;
uint32 redpack_type = 25;
uint32 autototext_voice = 26;
}
================================================
FILE: proto/RichMsg_pb2.py
================================================
# -*- coding: utf-8 -*-
# Generated by the protocol buffer compiler. DO NOT EDIT!
# source: RichMsg.proto
"""Generated protocol buffer code."""
from google.protobuf.internal import builder as _builder
from google.protobuf import descriptor as _descriptor
from google.protobuf import descriptor_pool as _descriptor_pool
from google.protobuf import symbol_database as _symbol_database
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\rRichMsg.proto\"\xad\x01\n\x0c\x46orwardExtra\x12\x15\n\rforward_orgId\x18\x01 \x01(\x05\x12\x16\n\x0e\x66orward_orgUin\x18\x02 \x01(\t\x12\x1a\n\x12\x66orward_orgUinType\x18\x03 \x01(\x05\x12\x16\n\x0e\x66orward_orgUrl\x18\x04 \x01(\t\x12\x19\n\x11\x66orward_thumbPath\x18\x05 \x01(\t\x12\x1f\n\x17\x66orward_orgFileSizeType\x18\x06 \x01(\x05\"\xf6\x05\n\x06PicRec\x12\x11\n\tlocalPath\x18\x01 \x01(\t\x12\x0c\n\x04size\x18\x02 \x01(\x05\x12\x0c\n\x04type\x18\x03 \x01(\x05\x12\x0e\n\x06isRead\x18\x04 \x01(\x08\x12\x0c\n\x04uuid\x18\x05 \x01(\t\x12\x0b\n\x03md5\x18\x06 \x01(\t\x12\x1b\n\x13serverStorageSource\x18\x07 \x01(\t\x12\x13\n\x0bthumbMsgUrl\x18\x08 \x01(\t\x12\x11\n\tbigMsgUrl\x18\t \x01(\t\x12\x11\n\trawMsgUrl\x18\n \x01(\t\x12\x14\n\x0c\x66ileSizeFlag\x18\x0b \x01(\x05\x12\x16\n\x0euiOperatorFlag\x18\x0c \x01(\x05\x12\"\n\x0b\x66orwardInfo\x18\r \x01(\x0b\x32\r.ForwardExtra\x12\x0f\n\x07version\x18\x0e \x01(\x05\x12\x10\n\x08isReport\x18\x0f \x01(\x05\x12\x13\n\x0bgroupFileID\x18\x10 \x01(\x04\x12\x11\n\tlocalUUID\x18\x11 \x01(\t\x12\x14\n\x0cpreDownState\x18\x12 \x01(\x05\x12\x16\n\x0epreDownNetwork\x18\x13 \x01(\x05\x12\x11\n\tpreviewed\x18\x14 \x01(\x05\x12\x1a\n\x12uint32_thumb_width\x18\x15 \x01(\r\x12\x1b\n\x13uint32_thumb_height\x18\x16 \x01(\r\x12\x14\n\x0cuint32_width\x18\x17 \x01(\r\x12\x15\n\ruint32_height\x18\x18 \x01(\r\x12\x19\n\x11uint32_image_type\x18\x19 \x01(\r\x12\x17\n\x0fuint32_show_len\x18\x1a \x01(\r\x12\x1b\n\x13uint32_download_len\x18\x1b \x01(\r\x12\x1a\n\x12uint32_current_len\x18\x1c \x01(\r\x12\x1c\n\x14notPreDownloadReason\x18\x1d \x01(\r\x12\x11\n\tenableEnc\x18\x1e \x01(\x08\x12\x16\n\x0e\x62igThumbMsgUrl\x18\x1f \x01(\t\x12\x19\n\x11\x62ytes_pb_reserved\x18 \x01(\x0c\x12%\n\x1d\x62ool_story_pic_send_to_recent\x18! \x01(\x08\"\x0f\n\rMarketFaceRec\"\x1b\n\x03Msg\x12\x14\n\x05\x65lems\x18\x01 \x03(\x0b\x32\x05.Elem\"c\n\x04\x45lem\x12\x0f\n\x07textMsg\x18\x01 \x01(\x0c\x12\x0e\n\x06picMsg\x18\x02 \x01(\x0c\x12#\n\x0bmarkfaceMsg\x18\x03 \x01(\x0b\x32\x0e.MarketFaceRec\x12\x15\n\rsourceMsgInfo\x18\x04 \x01(\t\"M\n\x0cSafeMoreInfo\x12\x11\n\tstrMsgTxt\x18\x01 \x01(\t\x12\x15\n\rstrFromMobile\x18\x02 \x01(\t\x12\x13\n\x0bstrFromName\x18\x03 \x01(\t\"\x13\n\x04Test\x12\x0b\n\x03str\x18\x10 \x01(\t\"\xff\x03\n\x06PttRec\x12\x11\n\tlocalPath\x18\x01 \x01(\t\x12\x0c\n\x04size\x18\x02 \x01(\x04\x12\x0c\n\x04type\x18\x03 \x01(\r\x12\x0e\n\x06isRead\x18\x04 \x01(\x08\x12\x0c\n\x04uuid\x18\x05 \x01(\t\x12\x0b\n\x03md5\x18\x06 \x01(\t\x12\x1b\n\x13serverStorageSource\x18\x07 \x01(\t\x12\x0f\n\x07version\x18\x08 \x01(\x05\x12\x10\n\x08isReport\x18\t \x01(\x05\x12\x0f\n\x07pttFlag\x18\n \x01(\x05\x12\x13\n\x0bgroupFileID\x18\x0b \x01(\x04\x12\x0f\n\x07sttText\x18\x0c \x01(\t\x12\x16\n\x0elongPttVipFlag\x18\r \x01(\x05\x12\x11\n\texpandStt\x18\x0e \x01(\x08\x12\x16\n\x0egroup_file_key\x18\x0f \x01(\t\x12\x12\n\nmsgRecTime\x18\x10 \x01(\x04\x12\x0f\n\x07msgTime\x18\x11 \x01(\x04\x12\x11\n\tvoiceType\x18\x12 \x01(\r\x12\x13\n\x0bvoiceLength\x18\x13 \x01(\r\x12\x17\n\x0fvoiceChangeFlag\x18\x14 \x01(\r\x12\x11\n\tdirectUrl\x18\x15 \x01(\t\x12\x10\n\x08\x62usiType\x18\x16 \x01(\r\x12\x15\n\rfullLocalPath\x18\x17 \x01(\t\x12\x0f\n\x07\x65xtFlag\x18\x18 \x01(\x04\x12\x14\n\x0credpack_type\x18\x19 \x01(\r\x12\x18\n\x10\x61utototext_voice\x18\x1a \x01(\rb\x06proto3')
_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals())
_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'RichMsg_pb2', globals())
if _descriptor._USE_C_DESCRIPTORS == False:
DESCRIPTOR._options = None
_FORWARDEXTRA._serialized_start=18
_FORWARDEXTRA._serialized_end=191
_PICREC._serialized_start=194
_PICREC._serialized_end=952
_MARKETFACEREC._serialized_start=954
_MARKETFACEREC._serialized_end=969
_MSG._serialized_start=971
_MSG._serialized_end=998
_ELEM._serialized_start=1000
_ELEM._serialized_end=1099
_SAFEMOREINFO._serialized_start=1101
_SAFEMOREINFO._serialized_end=1178
_TEST._serialized_start=1180
_TEST._serialized_end=1199
_PTTREC._serialized_start=1202
_PTTREC._serialized_end=1713
# @@protoc_insertion_point(module_scope)
================================================
FILE: proto/__init__.py
================================================
# coding=utf-8
================================================
FILE: proto/compile
================================================
protoc RichMsg.proto --python_out=.
================================================
FILE: requirements.txt
================================================
tk
protobuf
av
pilk