From a1fd932a774a2af5bb621460efed8a42d6cb38f5 Mon Sep 17 00:00:00 2001 From: Yuxin Wu Date: Wed, 29 Nov 2017 03:55:09 -0800 Subject: [PATCH] use emoji cover for failures --- wechat/avatar.py | 4 ++-- wechat/libchathelper.py | 16 +++++++++++----- wechat/render.py | 29 +++++++++++++++++------------ wechat/res.py | 35 +++++++++++++++++++++++------------ 4 files changed, 53 insertions(+), 31 deletions(-) diff --git a/wechat/avatar.py b/wechat/avatar.py index b4b33dd..a34ff35 100644 --- a/wechat/avatar.py +++ b/wechat/avatar.py @@ -1,7 +1,7 @@ #!/usr/bin/env python2 # -*- coding: UTF-8 -*- # File: avatar.py -# Date: Wed Nov 29 03:26:10 2017 -0800 +# Date: Wed Nov 29 03:27:16 2017 -0800 # Author: Yuxin Wu from PIL import Image @@ -32,7 +32,7 @@ class AvatarReader(object): self.avt_use_db = True else: logger.warn( - "Avatar database {} not found. Will not use avatar!".format(avt_db)) + "Cannot find avatar files. Will not use avatar!") self._use_avt = False def get_avatar(self, username): diff --git a/wechat/libchathelper.py b/wechat/libchathelper.py index 993fa44..9919203 100644 --- a/wechat/libchathelper.py +++ b/wechat/libchathelper.py @@ -1,7 +1,7 @@ #!/usr/bin/env python2 # -*- coding: UTF-8 -*- # File: libchathelper.py -# Date: Thu Jun 18 00:02:35 2015 +0800 +# Date: Wed Nov 29 03:44:54 2017 -0800 # Author: Yuxin Wu import base64 @@ -46,13 +46,19 @@ class LibChatHelper(object): return img, 'jpeg' elif msg.type == TYPE_EMOJI: md5 = msg.imgPath - emoji_img, format = self.res.get_emoji_by_md5(md5) - return emoji_img, format + if md5: + emoji_img, format = self.res.get_emoji_by_md5(md5) + return emoji_img, format + else: + return '', '' elif msg.type == TYPE_CUSTOM_EMOJI: pq = PyQuery(msg.content) md5 = pq('emoticonmd5').text() - img, format = self.res.get_emoji(md5, None) - return img, format + if md5: + img, format = self.res.get_emoji(md5, None) + return img, format + else: + return '', '' else: return '', '' diff --git a/wechat/render.py b/wechat/render.py index 94722af..571afa1 100644 --- a/wechat/render.py +++ b/wechat/render.py @@ -1,7 +1,7 @@ #!/usr/bin/env python2 # -*- coding: UTF-8 -*- # File: render.py -# Date: Thu Jun 18 00:03:10 2015 +0800 +# Date: Wed Nov 29 03:53:55 2017 -0800 # Author: Yuxin Wu import os @@ -33,7 +33,7 @@ TEMPLATES_FILES = {TYPE_MSG: "TP_MSG", TYPE_IMG: "TP_IMG", TYPE_SPEAK: "TP_SPEAK", TYPE_EMOJI: "TP_EMOJI", - TYPE_CUSTOM_EMOJI: "TP_IMG", + TYPE_CUSTOM_EMOJI: "TP_EMOJI", TYPE_LINK: "TP_MSG"} TEMPLATES = {k: ensure_unicode(open(os.path.join(STATIC_PATH, '{}.html'.format(v))).read()) for k, v in TEMPLATES_FILES.iteritems()} @@ -126,16 +126,21 @@ class HTMLRender(object): # TODO do not show fancybox when no bigimg found format_dict['img'] = (img, 'jpeg') return template.format(**format_dict) - elif msg.type == TYPE_EMOJI: - md5 = msg.imgPath - emoji_img, format = self.res.get_emoji_by_md5(md5) - format_dict['emoji_format'] = format - format_dict['emoji_img'] = emoji_img - return template.format(**format_dict) - elif msg.type == TYPE_CUSTOM_EMOJI: - pq = PyQuery(msg.content) - md5 = pq('emoticonmd5').text() - format_dict['img'] = self.res.get_emoji_by_md5(md5) + elif msg.type == TYPE_EMOJI or msg.type == TYPE_CUSTOM_EMOJI: + if 'emoticonmd5' in msg.content: + pq = PyQuery(msg.content) + md5 = pq('emoticonmd5').text() + else: + md5 = msg.imgPath + # TODO md5 could exist in both. + # first is emoji md5, second is image2/ md5 + # can use fallback here. + if md5: + emoji_img, format = self.res.get_emoji_by_md5(md5) + format_dict['emoji_format'] = format + format_dict['emoji_img'] = emoji_img + else: + import IPython as IP; IP.embed() return template.format(**format_dict) elif msg.type == TYPE_LINK: content = msg.msg_str() diff --git a/wechat/res.py b/wechat/res.py index f1c8c3a..74b96df 100644 --- a/wechat/res.py +++ b/wechat/res.py @@ -1,7 +1,7 @@ #!/usr/bin/env python2 # -*- coding: UTF-8 -*- # File: res.py -# Date: Wed Nov 29 03:24:17 2017 -0800 +# Date: Wed Nov 29 03:43:50 2017 -0800 # Author: Yuxin Wu import glob @@ -196,10 +196,12 @@ class Resource(object): return big_file return get_jpg_b64(small_file) - def _get_res_emoji(self, md5, pack_id): - path = self.emoji_dir - if pack_id: - path = os.path.join(path, pack_id) + def _get_res_emoji(self, md5, pack_id, allow_cover=False): + """ + pack_id: can be None + allow_cover: Cover is non-animated. Can be used as a fallback. + """ + path = os.path.join(self.emoji_dir, pack_id or '') candidates = glob.glob(os.path.join(path, '{}*'.format(md5))) candidates = [k for k in candidates if not k.endswith('_thumb') \ and not re.match('.*_[0-9]+$', k)] @@ -210,14 +212,11 @@ class Resource(object): return None return f[0] - f = try_use([k for k in candidates if not k.endswith('_cover')]) - if f: - return get_file_b64(f), imghdr.what(f) + candidates = [k for k in candidates if (allow_cover or not k.endswith('_cover'))] - # don't try do use cover anymore. cover is not animated - #f = try_use([k for k in candidates if k.endswith('_cover')]) - #if f: - #return get_file_b64(f), imghdr.what(f) + for cand in candidates: + if imghdr.what(cand): + return get_file_b64(cand), imghdr.what(cand) return None, None def _get_internal_emoji(self, fname): @@ -226,24 +225,36 @@ class Resource(object): def get_emoji_by_md5(self, md5): """ :returns: (b64 img, format)""" + assert md5, md5 if md5 in self.parser.internal_emojis: # TODO this seems broken emoji_img, format = self._get_internal_emoji(self.parser.internal_emojis[md5]) logger.warn("Cannot get emoji {}".format(md5)) return None, None else: + # check cache img, format = self.emoji_cache.query(md5) if format: return img, format + + # check resource/emoji/ dir group = self.parser.emoji_groups.get(md5, None) emoji_img, format = self._get_res_emoji(md5, group) if format: return emoji_img, format + + # check url url = self.parser.emoji_url.get(md5, None) if url: emoji_img, format = self.emoji_cache.fetch(md5, url) if format: return emoji_img, format + # check resource/emoji dir again, for cover + emoji_img, format = self._get_res_emoji(md5, group, allow_cover=True) + if format: + return emoji_img, format + + # first 1k in emoji is encrypted logger.warn("Cannot get emoji {} in {}".format(md5, group)) return None, None