#!/usr/bin/env python3 # -*- coding: UTF-8 -*- import os from collections import Counter from functools import lru_cache import glob from pyquery import PyQuery import logging logger = logging.getLogger(__name__) LIB_PATH = os.path.dirname(os.path.abspath(__file__)) STATIC_PATH = os.path.join(LIB_PATH, 'static') HTML_FILE = os.path.join(STATIC_PATH, 'TP_INDEX.html') TIME_HTML_FILE = os.path.join(STATIC_PATH, 'TP_TIME.html') FRIEND_AVATAR_CSS_FILE = os.path.join(STATIC_PATH, 'avatar.css.tpl') try: from csscompressor import compress as css_compress except ImportError: css_compress = lambda x: x from .msg import * from .common.textutil import get_file_b64 from .common.progress import ProgressReporter from .common.timer import timing from .smiley import SmileyProvider from .msgslice import MessageSlicerByTime, MessageSlicerBySize TEMPLATES_FILES = {TYPE_MSG: "TP_MSG", TYPE_IMG: "TP_IMG", TYPE_SPEAK: "TP_SPEAK", TYPE_EMOJI: "TP_EMOJI", TYPE_CUSTOM_EMOJI: "TP_EMOJI", TYPE_LINK: "TP_MSG", TYPE_VIDEO_FILE: "TP_VIDEO_FILE", TYPE_QQMUSIC: "TP_QQMUSIC", } @lru_cache() def get_template(name: str | int) -> str | None: """Return the html template given a file name or msg type.""" if isinstance(name, int): name = TEMPLATES_FILES.get(name, None) if name is None: return None html_path = os.path.join(STATIC_PATH, f"{name}.html") with open(html_path) as f: return f.read() class HTMLRender(object): def __init__(self, parser, res=None): with open(HTML_FILE) as f: self.html = f.read() with open(TIME_HTML_FILE) as f: self.time_html = f.read() self.parser = parser self.res = res assert self.res is not None, \ "Resource Directory not given. Cannot render HTML." self.smiley = SmileyProvider() css_files = glob.glob(os.path.join(LIB_PATH, 'static/*.css')) self.css_string = [] # css to add for css in css_files: logger.info("Loading {}".format(os.path.basename(css))) with open(css) as f: self.css_string.append(f.read()) js_files = glob.glob(os.path.join(LIB_PATH, 'static/*.js')) # to load jquery before other js js_files = sorted(js_files, key=lambda f: 'jquery-latest' in f, reverse=True) self.js_string = [] for js in js_files: logger.info("Loading {}".format(os.path.basename(js))) with open(js) as f: self.js_string.append(f.read()) self.unknown_type_cnt = Counter() @property def all_css(self): # call after processing all messages, # because smiley css need to be included only when necessary def process(css): css = css_compress(css) return u''.format(css) if hasattr(self, 'final_css'): return self.final_css + process(self.smiley.gen_used_smiley_css()) self.final_css = u"\n".join(map(process, self.css_string)) return self.final_css + process(self.smiley.gen_used_smiley_css()) @property def all_js(self): if hasattr(self, 'final_js'): return self.final_js def process(js): # TODO: add js compress return u''.format(js) self.final_js = u"\n".join(map(process, self.js_string)) return self.final_js #@timing(total=True) def render_msg(self, msg: WeChatMsg): """ render a message, return the html block""" # TODO for chatroom, add nickname on avatar sender = u'you ' + msg.talker if not msg.isSend else 'me' format_dict = {'sender_label': sender, 'time': msg.createTime } if not msg.known_type: self.unknown_type_cnt[msg.type] += 1 if(not msg.isSend and msg.is_chatroom()): format_dict['nickname'] = '>\n
'+msg.talker_nickname+'cnt): {}".format(self.unknown_type_cnt))
        return ret

if __name__ == '__main__':
    r = HTMLRender()
    with open('/tmp/a.html', 'w') as f:
        print >> f, r.html.format(style=r.css, talker='talker',
                                     messages='haha')