예제 #1
0
    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)
예제 #2
0
 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
예제 #3
0
파일: msg.py 프로젝트: xdcesc/wechat-dump
 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
예제 #4
0
파일: msg.py 프로젝트: ppwwyyxx/wechat-dump
 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
예제 #5
0
    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)))
예제 #6
0
    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)))
예제 #7
0
    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)))
예제 #8
0
    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)))
예제 #9
0
    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
예제 #10
0
 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
예제 #11
0
    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
예제 #12
0
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)
예제 #13
0
    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)
예제 #14
0
    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)
예제 #15
0
    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)
예제 #16
0
파일: msg.py 프로젝트: gnoynait/wechat-dump
 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""
예제 #17
0
 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""
예제 #18
0
    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))
예제 #19
0
    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))
예제 #20
0
    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))
예제 #21
0
    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))
예제 #22
0
                        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
예제 #23
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'))
예제 #24
0
# 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)
예제 #25
0
    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:
예제 #26
0
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)
예제 #27
0
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")
예제 #28
0
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)