emoji -> smiley

This commit is contained in:
ppwwyyxx
2014-12-20 17:55:46 +08:00
parent 5b97d3d95f
commit 0d219538a6
290 changed files with 388 additions and 385 deletions
+1 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
# File: dump_html.py
# Date: Sun Nov 23 16:37:48 2014 +0800
# Date: Sat Dec 20 15:58:35 2014 +0800
# Author: Yuxin Wu <[email protected]>
import sys
@@ -19,7 +19,6 @@ 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(parser, res)
+1 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
# File: dump_msg.py
# Date: Sat Nov 22 22:32:23 2014 +0800
# Date: Sat Dec 20 15:58:29 2014 +0800
# Author: Yuxin Wu <[email protected]>
from lib.parser import WeChatDBParser
@@ -20,7 +20,6 @@ if not os.path.isdir(output_dir):
sys.exit("Error creating directory {}".format(output_dir))
parser = WeChatDBParser(db_file)
parser.parse()
for name, msgs in parser.msgs_by_talker.iteritems():
print u"Writing msgs for {}".format(name)
-81
View File
@@ -1,81 +0,0 @@
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
# File: emoji.py
# Date: Sat Dec 20 15:08:45 2014 +0800
# Author: Yuxin Wu <[email protected]>
import os
import re
import json
LIB_PATH = os.path.dirname(os.path.abspath(__file__))
UNICODE_EMOJI_FILE = os.path.join(LIB_PATH, 'static', 'unicode-emoji.json')
TENCENT_EMOJI_FILE = os.path.join(LIB_PATH, 'static', 'tencent-emoji.json')
TENCENT_EXTRAEMOJI_FILE = os.path.join(LIB_PATH,
'static', 'tencent-emoji-extra.json')
UNICODE_EMOJI_RE = re.compile(u'[\U00010000-\U0010ffff]|[\u2600-\u2764]|\u2122|\u00a9|\u00ae')
class EmojiProvider(object):
def __init__(self, html_replace=True):
""" html_replace: replace emojicode by html.
otherwise, replace by plain text
"""
self.html_replace = html_replace
if not html_replace:
raise NotImplementedError()
# [微笑] -> 0
self.tencent_emoji = json.load(open(TENCENT_EMOJI_FILE))
# some extra emoji from javascript on wx.qq.com
extra_emoji = json.load(open(TENCENT_EXTRAEMOJI_FILE))
extra_emoji = dict([(u'[' + k + u']', v) for k, v in
extra_emoji.iteritems()])
self.tencent_emoji.update(extra_emoji)
# 1f35c -> "\ue340"
#self.unicode_emoji_code = gUnicodeCodeMap
# u'\U0001f35c' -> "e340"
self.unicode_emoji = dict([(unichr(int(k, 16)), hex(ord(v))[2:])
for k, v in
json.load(open(UNICODE_EMOJI_FILE)).iteritems()])
self.used_emoji_id = set()
def gen_replace_elem(self, emoji_id):
return '<span class="emoji emoji{}"></span>'.format(emoji_id)
def _replace_unicode(self, msg):
if not UNICODE_EMOJI_RE.findall(msg):
# didn't find the code
return msg
for k, v in self.unicode_emoji.iteritems():
if k in msg:
self.used_emoji_id.add(v)
msg = msg.replace(k, self.gen_replace_elem(v))
return msg
def _replace_tencent(self, msg):
if (not '[' in msg or not ']' in msg) \
and (not '\:' in msg) and (not '/' in msg):
return msg
for k, v in self.tencent_emoji.iteritems():
if k in msg:
self.used_emoji_id.add(v)
msg = msg.replace(k, self.gen_replace_elem(v))
return msg
def replace_emojicode(self, msg):
""" replace the emoji code in msg
return a html
"""
msg = self._replace_unicode(msg)
msg = self._replace_tencent(msg)
return msg
if __name__ == '__main__':
emoji = EmojiProvider()
msg = u"[挥手]哈哈呵呵hihi\U0001f684\u2728\u0001"
msg = emoji.replace_emojicode(msg)
print msg
+2 -1
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
# File: parser.py
# Date: Wed Dec 17 23:04:54 2014 +0800
# Date: Sat Dec 20 15:58:16 2014 +0800
# Author: Yuxin Wu <[email protected]>
import sqlite3
@@ -30,6 +30,7 @@ class WeChatDBParser(object):
self.cc = self.db_conn.cursor()
self.contacts = {}
self.msgs_by_talker = defaultdict(list)
self.parse()
def _parse_contact(self):
contacts = self.cc.execute(
Executable → Regular
+11 -5
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
# File: render.py
# Date: Sat Dec 20 15:40:19 2014 +0800
# Date: Sat Dec 20 17:48:48 2014 +0800
# Author: Yuxin Wu <[email protected]>
import os
@@ -20,7 +20,7 @@ except:
from .msg import *
from .utils import ensure_unicode
from emoji import EmojiProvider
from smiley import SmileyProvider
TEMPLATES_FILES = {TYPE_MSG: "TP_MSG",
TYPE_IMG: "TP_IMG",
@@ -36,12 +36,12 @@ class HTMLRender(object):
self.res = res
if self.res is None:
logger.warn("Resource Directory not given. Images / Voice Message won't be displayed.")
self.emoji = EmojiProvider()
self.smiley = SmileyProvider()
csss = glob.glob(os.path.join(LIB_PATH, 'static/*.css'))
css_string = []
for css in csss:
logger.info("Loading {}.".format(os.path.basename(css)))
logger.info("Loading {}".format(os.path.basename(css)))
css = ensure_unicode(css_compress(open(css).read()))
css = u'<style type="text/css">{}</style>'.format(css)
css_string.append(css)
@@ -71,7 +71,7 @@ class HTMLRender(object):
def fallback():
template = ensure_unicode(TEMPLATES[1])
content = msg.msg_str()
content = self.emoji.replace_emojicode(content)
content = self.smiley.replace_smileycode(content)
return template.format(sender_label=sender,
content=content)
if msg.type not in TEMPLATES:
@@ -94,6 +94,12 @@ class HTMLRender(object):
return template.format(sender_label=sender,
small_img=smallimg,
big_img=bigimg)
elif msg.type == TYPE_EMOJI:
imgpath = msg.imgPath
print imgpath
return fallback()
# custom emoji
return fallback()
def render_msgs(self, msgs):
+3 -2
View File
@@ -1,7 +1,7 @@
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
# File: res.py
# Date: Sat Dec 20 15:40:33 2014 +0800
# Date: Sat Dec 20 16:26:51 2014 +0800
# Author: Yuxin Wu <[email protected]>
import glob
@@ -16,6 +16,7 @@ logger = logging.getLogger(__name__)
from lib.avatar import AvatarReader
VOICE_DIRNAME = 'voice2'
IMG_DIRNAME = 'image2'
JPEG_QUALITY = 50
class Resource(object):
@@ -23,7 +24,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.img_dir = os.path.join(res_dir, 'image2')
self.img_dir = os.path.join(res_dir, IMG_DIRNAME)
assert os.path.isdir(self.img_dir), \
"No such directory: {}".format(self.img_dir)
self.avt_reader = AvatarReader(self.res_dir)
Executable
+81
View File
@@ -0,0 +1,81 @@
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
# File: smiley.py
# Date: Sat Dec 20 17:49:42 2014 +0800
# Author: Yuxin Wu <[email protected]>
import os
import re
import json
LIB_PATH = os.path.dirname(os.path.abspath(__file__))
UNICODE_SMILEY_FILE = os.path.join(LIB_PATH, 'static', 'unicode-smiley.json')
TENCENT_SMILEY_FILE = os.path.join(LIB_PATH, 'static', 'tencent-smiley.json')
TENCENT_EXTRASMILEY_FILE = os.path.join(LIB_PATH,
'static', 'tencent-smiley-extra.json')
UNICODE_SMILEY_RE = re.compile(u'[\U00010000-\U0010ffff]|[\u2600-\u2764]|\u2122|\u00a9|\u00ae')
class SmileyProvider(object):
def __init__(self, html_replace=True):
""" html_replace: replace smileycode by html.
otherwise, replace by plain text
"""
self.html_replace = html_replace
if not html_replace:
raise NotImplementedError()
# [微笑] -> 0
self.tencent_smiley = json.load(open(TENCENT_SMILEY_FILE))
# some extra smiley from javascript on wx.qq.com
extra_smiley = json.load(open(TENCENT_EXTRASMILEY_FILE))
extra_smiley = dict([(u'[' + k + u']', v) for k, v in
extra_smiley.iteritems()])
self.tencent_smiley.update(extra_smiley)
# 1f35c -> "\ue340"
#self.unicode_smiley_code = gUnicodeCodeMap
# u'\U0001f35c' -> "e340"
self.unicode_smiley = dict([(unichr(int(k, 16)), hex(ord(v))[2:])
for k, v in
json.load(open(UNICODE_SMILEY_FILE)).iteritems()])
self.used_smiley_id = set()
def gen_replace_elem(self, smiley_id):
return '<span class="smiley smiley{}"></span>'.format(smiley_id)
def _replace_unicode(self, msg):
if not UNICODE_SMILEY_RE.findall(msg):
# didn't find the code
return msg
for k, v in self.unicode_smiley.iteritems():
if k in msg:
self.used_smiley_id.add(v)
msg = msg.replace(k, self.gen_replace_elem(v))
return msg
def _replace_tencent(self, msg):
if (not '[' in msg or not ']' in msg) \
and (not '\:' in msg) and (not '/' in msg):
return msg
for k, v in self.tencent_smiley.iteritems():
if k in msg:
self.used_smiley_id.add(v)
msg = msg.replace(k, self.gen_replace_elem(v))
return msg
def replace_smileycode(self, msg):
""" replace the smiley code in msg
return a html
"""
msg = self._replace_unicode(msg)
msg = self._replace_tencent(msg)
return msg
if __name__ == '__main__':
smiley = SmileyProvider()
msg = u"[挥手]哈哈呵呵hihi\U0001f684\u2728\u0001"
msg = smiley.replace_smileycode(msg)
print msg
@@ -1,7 +1,7 @@
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
# File: gen_emoji_css.py
# Date: Mon Dec 15 22:15:54 2014 +0800
# Date: Sat Dec 20 17:50:57 2014 +0800
# Author: Yuxin Wu <[email protected]>
import os
@@ -9,9 +9,9 @@ import glob
import base64
DIR_PATH = os.path.dirname(os.path.abspath(__file__))
OUTPUT_FILE = os.path.join(DIR_PATH, 'emoji.css')
OUTPUT_FILE = os.path.join(DIR_PATH, 'smiley.css')
HEAD = """.emoji {
HEAD = """.smiley {
background-position: -2px -2px;
background-repeat: norepeat;
width: 20px;
@@ -22,7 +22,7 @@ HEAD = """.emoji {
}
"""
TEMPLATE = """.emoji{name} {{
TEMPLATE = """.smiley{name} {{
background-image: url("data:image/png;base64,{b64}");
}}"""
@@ -32,8 +32,8 @@ def get_file_b64(fname):
with open(OUTPUT_FILE, 'w') as f:
print >> f, HEAD
for fname in glob.glob(os.path.join(DIR_PATH, 'emojis', '*.png')):
for fname in glob.glob(os.path.join(DIR_PATH, 'smileys', '*.png')):
b64 = get_file_b64(fname)
basename = os.path.basename(fname)
emojiname = basename[:-4]
print >> f, TEMPLATE.format(name=emojiname, b64=b64);
smileyname = basename[:-4]
print >> f, TEMPLATE.format(name=smileyname, b64=b64);
@@ -1,20 +1,18 @@
#!/usr/bin/env python2
# -*- coding: UTF-8 -*-
# File: parse_tencent_emoji.py
# Date: Tue Dec 16 23:22:50 2014 +0800
# Date: Sat Dec 20 17:52:20 2014 +0800
# Author: Yuxin Wu <[email protected]>
import xml.etree.ElementTree as ET
import os
import json
NUM_EMOJI = 105
tree = ET.parse(os.path.join(
os.path.dirname(os.path.abspath(__file__)), 'emoji.xml'))
os.path.dirname(os.path.abspath(__file__)), 'smiley.xml'))
root = tree.getroot()
emojis = {}
smileys = {}
for child in root:
name = child.attrib['name']
if 'smiley_values' in name:
@@ -25,8 +23,8 @@ for child in root:
for idx, v in enumerate(lst):
if type(v) == str:
v = v.decode('utf-8')
emojis[v] = idx
smileys[v] = idx
with open('tencent-emoji.json', 'w') as f:
json.dump(emojis, f)
with open('tencent-smiley.json', 'w') as f:
json.dump(smileys, f)
File diff suppressed because it is too large Load Diff

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 914 B

After

Width:  |  Height:  |  Size: 914 B

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Before

Width:  |  Height:  |  Size: 891 B

After

Width:  |  Height:  |  Size: 891 B

Before

Width:  |  Height:  |  Size: 898 B

After

Width:  |  Height:  |  Size: 898 B

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 907 B

After

Width:  |  Height:  |  Size: 907 B

Before

Width:  |  Height:  |  Size: 1006 B

After

Width:  |  Height:  |  Size: 1006 B

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 792 B

After

Width:  |  Height:  |  Size: 792 B

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 938 B

After

Width:  |  Height:  |  Size: 938 B

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 572 B

After

Width:  |  Height:  |  Size: 572 B

Before

Width:  |  Height:  |  Size: 608 B

After

Width:  |  Height:  |  Size: 608 B

Before

Width:  |  Height:  |  Size: 823 B

After

Width:  |  Height:  |  Size: 823 B

Before

Width:  |  Height:  |  Size: 935 B

After

Width:  |  Height:  |  Size: 935 B

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Before

Width:  |  Height:  |  Size: 907 B

After

Width:  |  Height:  |  Size: 907 B

Before

Width:  |  Height:  |  Size: 736 B

After

Width:  |  Height:  |  Size: 736 B

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 582 B

After

Width:  |  Height:  |  Size: 582 B

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1022 B

After

Width:  |  Height:  |  Size: 1022 B

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Before

Width:  |  Height:  |  Size: 890 B

After

Width:  |  Height:  |  Size: 890 B

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 1.3 KiB

Before

Width:  |  Height:  |  Size: 922 B

After

Width:  |  Height:  |  Size: 922 B

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Before

Width:  |  Height:  |  Size: 952 B

After

Width:  |  Height:  |  Size: 952 B

Some files were not shown because too many files have changed in this diff Show More