avatar done

This commit is contained in:
ppwwyyxx
2014-11-23 16:38:04 +08:00
parent 5f39a09da3
commit d614eaf454
6 changed files with 117 additions and 17 deletions
+11 -6
View File
@@ -1,24 +1,29 @@
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
# File: dump_html.py
# Date: Sat Nov 22 23:51:45 2014 +0800
# Date: Sun Nov 23 16:37:48 2014 +0800
# Author: Yuxin Wu <[email protected]>
import sys
if len(sys.argv) != 3:
sys.exit("Usage: {0} <path to decoded_database.db> <name>".format(sys.argv[0]))
if len(sys.argv) != 5:
sys.exit("Usage: {0} <path to decoded_database.db> <path to resource> <name> <output html>".format(sys.argv[0]))
from lib.utils import ensure_unicode
from lib.parser import WeChatDBParser
from lib.res import Resource
from lib.render import HTMLRender
db_file = sys.argv[1]
name = ensure_unicode(sys.argv[2])
res = Resource(sys.argv[2])
name = ensure_unicode(sys.argv[3])
output_file = sys.argv[4]
parser = WeChatDBParser(db_file)
parser.parse()
msgs = parser.msgs_by_talker[name]
render = HTMLRender()
render = HTMLRender(parser, res)
html = render.render_msgs(msgs).encode('utf-8')
print html
with open(output_file, 'w') as f:
print >> f, html
+46
View File
@@ -0,0 +1,46 @@
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
# File: avatar.py
# Date: Sun Nov 23 16:28:00 2014 +0800
# Author: Yuxin Wu <[email protected]>
import os
import md5
import numpy as np
from .utils import ensure_bin_str
class AvatarReader(object):
def __init__(self, res_dir):
self.avt_dir = os.path.join(res_dir, 'avatar')
assert os.path.isdir(self.avt_dir), "No such directory {}".format(self.avt_dir)
@staticmethod
def get_filename(username):
m = md5.new()
m.update(username)
return m.hexdigest()
def get_avatar(self, username):
""" username: `username` field in db.rcontact"""
username = ensure_bin_str(username)
filename = AvatarReader.get_filename(username)
dir1, dir2 = filename[:2], filename[2:4]
filename = os.path.join(self.avt_dir, dir1, dir2,
"user_{}.png.bm".format(filename))
if not os.path.isfile(filename):
# avatar not found!
return None
else:
return AvatarReader.read_bm(filename)
@staticmethod
def read_bm(fname):
size = (96, 96, 3)
img = np.zeros(size, dtype='uint8')
with open(fname, 'rb') as f:
for i in range(96):
for j in range(96):
r, g, b, a = map(ord, f.read(4))
img[i,j] = (r, g, b)
return img
+13 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
# File: parser.py
# Date: Sat Nov 22 23:23:44 2014 +0800
# Date: Sun Nov 23 16:33:20 2014 +0800
# Author: Yuxin Wu <[email protected]>
import sqlite3
@@ -18,7 +18,6 @@ addr_upload2
chatroom
message
rcontact
"""
class WeChatDBParser(object):
@@ -42,7 +41,10 @@ SELECT username,conRemark,nickname FROM rcontact
else:
self.contacts[username] = ensure_unicode(nickname)
print "Got {} contacts.".format(len(self.contacts))
def _parse_msg(self):
msgs_tot_cnt = 0
db_msgs = self.cc.execute(
"""
SELECT {} FROM message
@@ -57,6 +59,14 @@ SELECT {} FROM message
for k, v in self.msgs_by_talker.iteritems():
for msg in v:
msg.talker_name = ensure_unicode(k)
msgs_tot_cnt += len(v)
print "Got {} messages in total.".format(msgs_tot_cnt)
def _parse_userinfo(self):
userinfo_q = self.cc.execute(""" SELECT id, value FROM userinfo """)
userinfo = dict(userinfo_q)
self.username = userinfo[2]
print "Your username is: {}".format(self.username)
def _find_msg_by_type(self, msgs=None):
ret = []
@@ -68,5 +78,6 @@ SELECT {} FROM message
return sorted(ret)
def parse(self):
self._parse_userinfo()
self._parse_contact()
self._parse_msg()
+15 -5
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
# File: render.py
# Date: Sat Nov 22 23:24:10 2014 +0800
# Date: Sun Nov 23 16:28:28 2014 +0800
# Author: Yuxin Wu <[email protected]>
import os
@@ -22,14 +22,20 @@ TEMPLATES = dict([(k, open(os.path.join(
LIB_PATH, 'static/{}.html'.format(v))).read())
for k, v in TEMPLATES_FILES.iteritems()])
class HTMLRender(object):
def __init__(self, res=None):
def __init__(self, parser, res=None):
self.css = ensure_unicode(css_compress(open(CSS_FILE).read()))
self.html = ensure_unicode(open(HTML_FILE).read())
self.parser = parser
self.res = res
def get_avatar_pair(self, username):
if self.res is None:
return ("", "")
avt1 = self.res.get_avatar(self.parser.username)
avt2 = self.res.get_avatar(username)
return (avt1, avt2)
def render_msg(self, msg):
""" render a message, return the block"""
# TODO
@@ -42,9 +48,13 @@ class HTMLRender(object):
content=msg.msg_str())
def render_msgs(self, msgs):
talker_name = msgs[0].talker
avatars = self.get_avatar_pair(talker_name)
blocks = [self.render_msg(m) for m in msgs]
return self.html.format(style=self.css, talker=msgs[0].talker_name,
messages=u''.join(blocks))
messages=u''.join(blocks),
avatar_me=avatars[0],
avatar_you=avatars[1])
if __name__ == '__main__':
r = HTMLRender()
+18 -2
View File
@@ -1,11 +1,16 @@
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
# File: Res.py
# Date: Sat Nov 22 20:54:25 2014 +0800
# File: res.py
# Date: Sun Nov 23 15:59:48 2014 +0800
# Author: Yuxin Wu <[email protected]>
import glob
import os
import Image
import cStringIO
import base64
from lib.avatar import AvatarReader
VOICE_DIRNAME = 'voice2'
@@ -14,6 +19,7 @@ class Resource(object):
def __init__(self, res_dir):
assert os.path.isdir(res_dir), "No such directory: {}".format(res_dir)
self.res_dir = res_dir
self.avt_reader = AvatarReader(self.res_dir)
self.init()
def init(self):
@@ -32,6 +38,16 @@ class Resource(object):
"Error interpreting the protocol, this is a bug!"
self.speak_data[key] = full_path
def get_avatar(self, username):
""" return base64 string"""
ret = self.avt_reader.get_avatar(username)
if ret is None:
return ""
im = Image.fromarray(ret)
buf = cStringIO.StringIO()
im.save(buf, 'JPEG', quality=50)
jpeg_str = buf.getvalue()
return base64.b64encode(jpeg_str)
+14 -2
View File
@@ -10,14 +10,14 @@
<body>
<div id="container">
<div id="chat" class="chatPanel normalPanel">
<div class="chatContainer" style="height: 800px;">
<div class="chatContainer" style="height: 600px;">
<div class="chatMainPanel" id="chatMainPanel">
<div class="chatTitle">
<div class="chatNameWrap">
<p class="chatName" id="messagePanelTitle">{talker}</p>
</div>
</div>
<div class="chatScorll" style="height: 770px; overflow-y: scroll; position: relative; font-family:initial;">
<div class="chatScorll" style="height: 550px; overflow-y: scroll; position: relative; font-family:initial;">
<div id="chat_chatmsglist" class="chatContent" style="position: absolute;">
{messages}
</div>
@@ -26,5 +26,17 @@
</div>
</div>
</div>
<script type='text/javascript'>
var chats = document.getElementsByClassName('me');
for (var k = 0; k < chats.length; k ++) {{
var avt = chats[k].getElementsByClassName('avatar')[0];
avt.src = "data:image/jpg;base64,{avatar_me}";
}}
var chats = document.getElementsByClassName('you');
for (var k = 0; k < chats.length; k ++) {{
var avt = chats[k].getElementsByClassName('avatar')[0];
avt.src = "data:image/jpg;base64,{avatar_you}";
}}
</script>
</body>
</html>