import argparse import getpass import logging import sys import os from weixin import WebWeixin from sqlcipher3 import dbapi2 as sqlite def parse_args(): parser = argparse.ArgumentParser() parser.add_argument("-f", "--db-file", required=True, help="数据库文件") parser.add_argument("-d", "--data-dir",required=True, help="文件存储目录") args = parser.parse_args() return args class WXBot(WebWeixin): def getUserNickName(self, id): if id == self.User['UserName']: return self.User['NickName'] for member in self.ContactList: if member['UserName'] == id: return member['NickName'] return None def handleMsg(self, r): for msg in r['AddMsgList']: msgID = msg['MsgId'] msgType = msg['MsgType'] sql = "INSERT INTO msg (\ msg_id,\ create_time,\ msg_type,\ content,\ from_id,\ from_name,\ from_nickname,\ to_id,\ to_name,\ to_nickname,\ group_id,\ group_name\ ) VALUES (\ :msg_id,\ :create_time,\ :msg_type,\ :content,\ :from_id,\ :from_name,\ :from_nickname,\ :to_id,\ :to_name,\ :to_nickname,\ :group_id,\ :group_name\ )" params = { "msg_id": msgID, "create_time": msg['CreateTime'], "msg_type": msgType, "content": None, "from_id": msg['FromUserName'], "from_name": self.getUserRemarkName(msg['FromUserName']), "from_nickname": self.getUserNickName(msg['FromUserName']), "to_id": msg['ToUserName'], "to_name": self.getUserRemarkName(msg['ToUserName']), "to_nickname": self.getUserNickName(msg['ToUserName']), "group_id": None, "group_name": None } # 过滤特殊帐号消息 if msg['FromUserName'] in self.SpecialUsers or msg['ToUserName'] in self.SpecialUsers: continue if msgType == 1: params['content'] = msg['Content'].replace('<', '<').replace('>', '>') elif msgType == 3: params['content'] = "[图片](%s)" % msgID self.webwxgetmsgimg(msgID) elif msgType == 34: params['content'] = "[语音](%s)" % msgID self.webwxgetvoice(msgID) elif msgType == 43: params['content'] = "[视频](%s)" % msgID self.webwxgetvideo(msgID) elif msgType == 62: params['msg_type'] = 43 params['content'] = "[小视频](%s)" % msgID self.webwxgetvideo(msgID) elif msgType == 42: params['msg_type'] = 0 params['content'] = "[名片](%s)" % msg['RecommendInfo']['NickName'] elif msgType == 47: if msg['HasProductId'] == 1: # 有版权的表情包,无法在Web端查看 params['msg_type'] = 0 params['content'] = "[表情包图片]" else: params['msg_type'] = 3 params['content'] = "[动画表情](%s)" % msgID self.webwxgetmsgimg(msgID) elif msgType == 49: params['msg_type'] = 0 params['content'] = "[链接:%s](%s)" % (msg['FileName'], msg['Url']) elif (50, 51, 52, 53, 9999, 10000, 10002).index(msgType) >= 0: continue else: params['msg_type'] = 0 params['content'] = "" continue # 群消息 if msg['FromUserName'][:2] == '@@': if ":
" in content: [people, content] = msg['Content'].split(':
', 1) params['group_name'] = self.getUserRemarkName(msg['FromUserName']) params['from_id'] = people params['from_name'] = self.getUserRemarkName(people) params['to_id'] = params['to_name'] = params['to_nickname'] = None elif msg['ToUserName'][:2] == '@@': params['group_name'] = self.getUserRemarkName(msg['ToUserName']) params['from_id'] = self.User['UserName'] params['from_name'] = self.User['NickName'] params['to_id'] = params['to_name'] = params['to_nickname'] = None conn.execute(sql, params) conn.commit() args = parse_args() dataDir = args.data_dir if not os.access(os.path.dirname(args.db_file), os.X_OK) and not os.access(args.db_file, os.W_OK): print("无法创建或打开数据库文件") exit() elif not os.access(dataDir, os.X_OK): print("数据目录不存在或权限不足") exit() conn = sqlite.connect(args.db_file) while True: try: passwd = getpass.getpass("输入数据库密码:") if passwd != '': conn.execute("PRAGMA KEY = %s" % passwd) conn.execute("CREATE TABLE IF NOT EXISTS msg (\ msg_id TEXT NOT NULL,\ create_time INTEGER NOT NULL,\ msg_type INTEGER NOT NULL,\ content TEXT,\ from_id TEXT,\ from_name TEXT,\ from_nickname TEXT,\ to_id TEXT,\ to_name TEXT,\ to_nickname TEXT,\ group_id TEXT,\ group_name TEXT\ );") break except sqlite.DatabaseError as e: if 'file is not a database' in e.args: print("密码错误,请重试") else: print("打开数据库失败", e) except KeyboardInterrupt: exit(1) except Exception as e: print("打开数据库失败", e) exit(1) if sys.stdout.encoding == 'cp936': sys.stdout = UnicodeStreamFilter(sys.stdout) if __name__ == '__main__': logger = logging.getLogger(__name__) if not sys.platform.startswith('win'): import coloredlogs coloredlogs.install(level='INFO') wxbot = WXBot() wxbot.saveFolder = dataDir wxbot.start()