def __init__(self, parser, res=None): self.html = ensure_unicode(open(HTML_FILE).read()) self.time_html = open(TIME_HTML_FILE).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))) css = ensure_unicode((open(css).read())) self.css_string.append(css) 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))) js = ensure_unicode(open(js).read()) self.js_string.append(js)
def __repr__(self): ret = "{}|{}:{}:{}".format( self.type, self.talker_nickname if not self.isSend else 'me', self.createTime, ensure_unicode(self.msg_str())) if self.imgPath: ret = "{}|img:{}".format(ensure_unicode(ret.strip()), self.imgPath) return ret else: return ret
def __repr__(self): ret = u"{}|{}:{}:{}".format( self.type, self.talker if not self.isSend else 'me', self.createTime, ensure_unicode(self.msg_str())).encode('utf-8') if self.imgPath: ret = u"{}|img:{}".format(ensure_unicode(ret.strip()), self.imgPath) return ret.encode('utf-8') else: return ret
def __repr__(self): ret = u"{}|{}:{}:{}".format( self.type, self.talker_nickname if not self.isSend else 'me', self.createTime, ensure_unicode(self.msg_str())).encode('utf-8') if self.imgPath: ret = u"{}|img:{}".format(ensure_unicode(ret.strip()), self.imgPath) return ret.encode('utf-8') else: return ret
def _parse_contact(self): contacts = self.cc.execute(""" SELECT username,conRemark,nickname FROM rcontact """) for row in contacts: username, remark, nickname = row if remark: self.contacts[username] = ensure_unicode(remark) else: self.contacts[username] = ensure_unicode(nickname) logger.info("Found {} contacts.".format(len(self.contacts)))
def _parse_contact(self): contacts = self.cc.execute( """ SELECT username,conRemark,nickname FROM rcontact """) for row in contacts: username, remark, nickname = row if remark: self.contacts[username] = ensure_unicode(remark) else: self.contacts[username] = ensure_unicode(nickname) logger.info("Found {} contacts.".format(len(self.contacts)))
def _parse_contact(self): contacts = self.cc.execute(""" SELECT username,conRemark,nickname FROM rcontact """) for row in contacts: username, remark, nickname = row if remark: self.contacts[username] = ensure_unicode(remark) else: self.contacts[username] = ensure_unicode(nickname) self.contacts_rev = {v: k for k, v in self.contacts.iteritems()} logger.info("Found {} names in `contact` table.".format( len(self.contacts)))
def _parse_contact(self): contacts = self.cc.execute( """ SELECT username,conRemark,nickname FROM rcontact """) for row in contacts: username, remark, nickname = row if remark: self.contacts[username] = ensure_unicode(remark) else: self.contacts[username] = ensure_unicode(nickname) for k, v in self.contacts.iteritems(): self.contacts_rev[v].append(k) logger.info("Found {} names in `contact` table.".format(len(self.contacts)))
def _parse_msg_row(self, row): """ parse a record of message into my format""" values = dict(zip(WeChatDBParser.FIELDS, row)) if values['content']: values['content'] = ensure_unicode(values['content']) else: values['content'] = u'' values['createTime'] = datetime.fromtimestamp(values['createTime'] / 1000) values['chat'] = values['talker'] try: if values['chat'].endswith('@chatroom'): values['chat'] = self.contacts[values['chat']] content = values['content'] if values['isSend'] == 1: values['talker'] = self.username elif values['type'] == TYPE_SYSTEM: values['talker'] = u'SYSTEM' else: talker = content[:content.find(':')] values['talker'] = self.contacts.get(talker, talker) values['content'] = content[content.find('\n') + 1:] else: tk_id = values['talker'] values['chat'] = self.contacts[tk_id] values['talker'] = self.contacts[tk_id] except KeyError: # It's possible that messages are kept in database after contacts been deleted logger.warn("Unknown contact: {}".format(values.get('talker', ''))) return None return values
def _parse_msg_row(self, row): """ parse a record of message into my format""" values = dict(zip(WeChatDBParser.FIELDS, row)) if values['content']: values['content'] = ensure_unicode(values['content']) else: values['content'] = u'' values['createTime'] = datetime.fromtimestamp(values['createTime']/ 1000) values['chat'] = values['talker'] try: if values['chat'].endswith('@chatroom'): values['chat'] = self.contacts[values['chat']] content = values['content'] talker = content[:content.find(':')] try: values['talker'] = self.contacts[talker] values['content'] = content[content.find('\n') + 1:] except KeyError: # system messages have no talker values['talker'] = u'' else: tk_id = values['talker'] values['chat'] = self.contacts[tk_id] values['talker'] = self.contacts[tk_id] except KeyError: # It's possible that messages are kept in database after contacts been deleted logger.warn("Unknown contact, probably deleted: {}".format(tk_id)) return None return values
def _parse_msg_row(self, row): """ parse a record of message into my format""" values = dict(zip(WeChatDBParser.FIELDS, row)) if values['content']: values['content'] = ensure_unicode(values['content']) else: values['content'] = u'' values['createTime'] = datetime.fromtimestamp(values['createTime']/ 1000) values['chat'] = values['talker'] try: if values['chat'].endswith('@chatroom'): values['chat_nickname'] = self.contacts[values['chat']] content = values['content'] if values['isSend'] == 1: values['talker'] = self.username elif values['type'] == TYPE_SYSTEM: values['talker'] = u'SYSTEM' else: talker = content[:content.find(':')] values['talker'] = talker values['talker_nickname'] = self.contacts.get(talker, talker) values['content'] = content[content.find('\n') + 1:] else: tk_id = values['talker'] values['chat'] = tk_id values['chat_nickname'] = self.contacts[tk_id] values['talker'] = tk_id values['talker_nickname'] = self.contacts[tk_id] except KeyError: # It's possible that messages are kept in database after contacts been deleted logger.warn("Unknown contact: {}".format(values.get('talker', ''))) return None return values
def main(): for _,_,files in os.walk(filepath): for f in files: if str(f)[-4:] == "html": wechatname = textutil.ensure_unicode(str(f)[:-5]) print wechatname print len(wechatname) mordifyCover(coverpath, wechatname) convert(f)
def prepare_avatar_css(self, talkers): avatar_tpl= ensure_unicode(open(FRIEND_AVATAR_CSS_FILE).read()) my_avatar = self.res.get_avatar(self.parser.username) css = avatar_tpl.format(name='me', avatar=my_avatar) for talker in talkers: avatar = self.res.get_contact_avatar(talker) css += avatar_tpl.format(name=talker, avatar=avatar) self.css_string.append(css)
def prepare_avatar_css(self, talkers): avatar_tpl = ensure_unicode(open(FRIEND_AVATAR_CSS_FILE).read()) my_avatar = self.res.get_avatar(self.parser.username) css = avatar_tpl.format(name='me', avatar=my_avatar) for talker in talkers: avatar = self.res.get_avatar(talker) css += avatar_tpl.format(name=talker, avatar=avatar) self.css_string.append(css)
def __init__(self, row): """ row: a tuple corresponding to FIELDS""" assert len(row) == len(WeChatMsg.FIELDS) for f, v in zip(WeChatMsg.FIELDS, row): setattr(self, f, v) if self.type not in _KNOWN_TYPES: logger.warn("Unhandled message type: {}".format(self.type)) # only to supress repeated warning: _KNOWN_TYPES.append(self.type) self.createTime = datetime.fromtimestamp(self.createTime / 1000) self.talker_name = None if self.content: self.content = ensure_unicode(self.content) else: self.content = u""
def _parse_msg(self): msgs_tot_cnt = 0 db_msgs = self.cc.execute(""" SELECT {} FROM message """.format(','.join(WeChatMsg.FIELDS))) for row in db_msgs: msg = WeChatMsg(row) if not WeChatMsg.filter_type(msg.type): self.msgs_by_talker[msg.talker].append(msg) #if msg.type > 10000 or msg.type < 0: #print repr(msg).split('|')[0] self.msgs_by_talker = { self.contacts[k]: sorted(v, key=lambda x: x.createTime) for k, v in self.msgs_by_talker.iteritems() } for k, v in self.msgs_by_talker.iteritems(): for msg in v: msg.talker_name = ensure_unicode(k) msgs_tot_cnt += len(v) logger.info("Found {} message records.".format(msgs_tot_cnt))
def _parse_msg(self): msgs_tot_cnt = 0 db_msgs = self.cc.execute( """ SELECT {} FROM message """.format(','.join(WeChatMsg.FIELDS))) for row in db_msgs: msg = WeChatMsg(row) if not WeChatMsg.filter_type(msg.type): self.msgs_by_talker[msg.talker].append(msg) # It's possible that messages are kept in database after contacts been deleted # TODO handle this with a random contact name self.msgs_by_talker = {self.contacts[k]: sorted(v, key=lambda x: x.createTime) for k, v in self.msgs_by_talker.iteritems() if k in self.contacts} for k, v in self.msgs_by_talker.iteritems(): for msg in v: msg.talker_name = ensure_unicode(k) msgs_tot_cnt += len(v) logger.info("Found {} message records.".format(msgs_tot_cnt))
def _parse_msg(self): msgs_tot_cnt = 0 db_msgs = self.cc.execute(""" SELECT {} FROM message """.format(','.join(WeChatMsg.FIELDS))) for row in db_msgs: msg = WeChatMsg(row) if not WeChatMsg.filter_type(msg.type): self.msgs_by_talker[msg.talker].append(msg) # It's possible that messages are kept in database after contacts been deleted # TODO handle this with a random contact name self.msgs_by_talker = { self.contacts[k]: sorted(v, key=lambda x: x.createTime) for k, v in self.msgs_by_talker.iteritems() if k in self.contacts } for k, v in self.msgs_by_talker.iteritems(): for msg in v: msg.talker_name = ensure_unicode(k) msgs_tot_cnt += len(v) logger.info("Found {} message records.".format(msgs_tot_cnt))
def get_avatar(self, username): """ username: `username` field in db.rcontact""" if not self._use_avt: return None username = ensure_unicode(username) avtid = md5(username.encode('utf-8')) dir1, dir2 = avtid[:2], avtid[2:4] candidates = glob.glob( os.path.join(self.avt_dir, dir1, dir2, f"*{avtid}*")) default_candidate = os.path.join(self.avt_dir, dir1, dir2, f"user_{avtid}.png") candidates.append(default_candidate) def priority(s): if "_hd" in s and s.endswith(".png"): return 10 else: return 1 candidates = sorted(set(candidates), key=priority, reverse=True) for cand in candidates: try: if self.avt_use_db: pos, size = self.query_index(cand) return self.read_img(pos, size) else: if os.path.exists(cand): if cand.endswith(".bm"): return self.read_bm_file(cand) else: return Image.open(cand) except Exception: logger.exception("HHH") pass logger.warning( "Avatar for {} not found in avatar database.".format(username))
default='decrypted.db', help='path to decrypted database') parser.add_argument('--avt', default='avatar.index', help='path to avatar.index file') parser.add_argument('--res', default='resource', help='reseource directory') args = parser.parse_args() return args if __name__ == '__main__': args = get_args() name = ensure_unicode(args.name) output_file = args.output parser = WeChatDBParser(args.db) try: chatid = parser.get_id_by_nickname(name) except KeyError: sys.stderr.write(u"Valid Contacts: {}\n".format(u'\n'.join( parser.all_chat_nicknames))) sys.stderr.write(u"Couldn't find the chat {}.".format(name)) sys.exit(1) res = Resource(parser, args.res, args.avt) msgs = parser.msgs_by_chat[chatid] print "Number of Messages: ", len(msgs) assert len(msgs) > 0
from common.textutil import ensure_unicode 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" } TEMPLATES = { k: ensure_unicode( open(os.path.join(STATIC_PATH, '{}.html'.format(v))).read()) for k, v in TEMPLATES_FILES.iteritems() } class HTMLRender(object): def __init__(self, parser, res=None): self.html = ensure_unicode(open(HTML_FILE).read()) self.time_html = open(TIME_HTML_FILE).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'))
# File: dump-html.py # Date: Wed Mar 25 17:44:20 2015 +0800 # Author: Yuxin Wu <*****@*****.**> import sys if len(sys.argv) != 5: sys.exit("Usage: {0} <path to decrypted_database.db> <path to resource> <name> <output html>".format(sys.argv[0])) from common.textutil import ensure_unicode from wechat.parser import WeChatDBParser from wechat.res import Resource from wechat.render import HTMLRender db_file = sys.argv[1] resource_dir = sys.argv[2] name = ensure_unicode(sys.argv[3]) output_file = sys.argv[4] parser = WeChatDBParser(db_file) res = Resource(resource_dir) try: msgs = parser.msgs_by_talker[name] except: sys.stderr.write(u"Valid Contacts: {}\n".format(u'\n'.join(parser.msgs_by_talker.keys()))) sys.stderr.write(u"Couldn't find that contact {}.".format(name)); sys.exit(1) render = HTMLRender(parser, res) htmls = render.render_msgs(msgs)
css_compress = lambda x: x from .msg import * from common.textutil import ensure_unicode 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_IMG", 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()} class HTMLRender(object): def __init__(self, parser, res=None): self.html = ensure_unicode(open(HTML_FILE).read()) self.time_html = open(TIME_HTML_FILE).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:
import sys if len(sys.argv) != 6: sys.exit( "Usage: {0} <path to decrypted_database.db> <path to avatar.index> <path to resource> <name> <output html>" .format(sys.argv[0])) from common.textutil import ensure_unicode from wechat.parser import WeChatDBParser from wechat.res import Resource from wechat.render import HTMLRender db_file = sys.argv[1] avt_db = sys.argv[2] resource_dir = sys.argv[3] name = ensure_unicode(sys.argv[4]) output_file = sys.argv[5] parser = WeChatDBParser(db_file) res = Resource(resource_dir, avt_db) try: msgs = parser.msgs_by_talker[name] except: sys.stderr.write(u"Valid Contacts: {}\n".format(u'\n'.join( parser.msgs_by_talker.keys()))) sys.stderr.write(u"Couldn't find that contact {}.".format(name)) sys.exit(1) render = HTMLRender(parser, res) htmls = render.render_msgs(msgs)
db_file = sys.argv[1] output_dir = sys.argv[2] res_dir = sys.argv[3] avt = sys.argv[4] group = sys.argv[5] try: os.mkdir(output_dir) except: pass if not os.path.isdir(output_dir): sys.exit("Error creating directory {}".format(output_dir)) parser = WeChatDBParser(db_file) res = Resource(res_dir, avt) ten_nhom = ensure_unicode(group) msgs = parser.msgs_by_chat[ten_nhom] import xlsxwriter from io import BytesIO from PIL import Image # Create a workbook and add a worksheet. workbook = xlsxwriter.Workbook('%s.xlsx' % group) worksheet = workbook.add_worksheet() worksheet.protect() worksheet.write(0, 0, "Day") worksheet.write(0, 1, "Time") worksheet.write(0, 2, "From") worksheet.write(0, 3, "Message")
from wechat.render import HTMLRender from wechat.libchathelper import LibChatHelper def get_args(): parser = argparse.ArgumentParser() parser.add_argument('name', help='name of contact') parser.add_argument('--output', help='output mp3 dir', default='/tmp') parser.add_argument('--db', default='decrypted.db', help='path to decrypted database') parser.add_argument('--res', default='resource', help='reseource directory') args = parser.parse_args() return args if __name__ == '__main__': args = get_args() name = ensure_unicode(args.name) output_file = args.output parser = WeChatDBParser(args.db) res = Resource(parser, args.res, '') if name and name in parser.msgs_by_chat: msgs = parser.msgs_by_chat[name] else: sys.stderr.write(u"Valid Contacts: {}\n".format(u'\n'.join(parser.msgs_by_chat.keys()))) sys.stderr.write(u"Couldn't find that contact {}.".format(name)); sys.exit(1) print "Number of Messages: ", len(msgs) assert len(msgs) > 0 libchat = LibChatHelper(parser, res)