import logging, traceback, sys, threading try: import Queue except ImportError: import queue as Queue from ..log import set_logging from ..utils import test_connect from ..storage import templates logger = logging.getLogger('itchat') def load_register(core): core.auto_login = auto_login core.configured_reply = configured_reply core.msg_register = msg_register core.run = run def auto_login(self, hotReload=False, statusStorageDir='itchat.pkl', enableCmdQR=False, picDir=None, qrCallback=None, loginCallback=None, exitCallback=None): if not test_connect(): logger.info("You can't get access to internet or wechat domain, so exit.") sys.exit() self.useHotReload = hotReload self.hotReloadDir = statusStorageDir if hotReload: if rval:=self.load_login_status(statusStorageDir, loginCallback=loginCallback, exitCallback=exitCallback): return logger.error('Hot reload failed, logging in normally, error={}'.format(rval)) self.logout() self.login(enableCmdQR=enableCmdQR, picDir=picDir, qrCallback=qrCallback, loginCallback=loginCallback, exitCallback=exitCallback) self.dump_login_status(statusStorageDir) else: self.login(enableCmdQR=enableCmdQR, picDir=picDir, qrCallback=qrCallback, loginCallback=loginCallback, exitCallback=exitCallback) def configured_reply(self): ''' determine the type of message and reply if its method is defined however, I use a strange way to determine whether a msg is from massive platform I haven't found a better solution here The main problem I'm worrying about is the mismatching of new friends added on phone If you have any good idea, pleeeease report an issue. I will be more than grateful. ''' try: msg = self.msgList.get(timeout=1) except Queue.Empty: pass else: if isinstance(msg['User'], templates.User): replyFn = self.functionDict['FriendChat'].get(msg['Type']) elif isinstance(msg['User'], templates.MassivePlatform): replyFn = self.functionDict['MpChat'].get(msg['Type']) elif isinstance(msg['User'], templates.Chatroom): replyFn = self.functionDict['GroupChat'].get(msg['Type']) if replyFn is None: r = None else: try: r = replyFn(msg) if r is not None: self.send(r, msg.get('FromUserName')) except: logger.warning(traceback.format_exc()) def msg_register(self, msgType, isFriendChat=False, isGroupChat=False, isMpChat=False): ''' a decorator constructor return a specific decorator based on information given ''' if not (isinstance(msgType, list) or isinstance(msgType, tuple)): msgType = [msgType] def _msg_register(fn): for _msgType in msgType: if isFriendChat: self.functionDict['FriendChat'][_msgType] = fn if isGroupChat: self.functionDict['GroupChat'][_msgType] = fn if isMpChat: self.functionDict['MpChat'][_msgType] = fn if not any((isFriendChat, isGroupChat, isMpChat)): self.functionDict['FriendChat'][_msgType] = fn return fn return _msg_register def run(self, debug=False, blockThread=True): logger.info('Start auto replying.') if debug: set_logging(loggingLevel=logging.DEBUG) def reply_fn(): try: while self.alive: self.configured_reply() except KeyboardInterrupt: if self.useHotReload: self.dump_login_status() self.alive = False logger.debug('itchat received an ^C and exit.') logger.info('Bye~') if blockThread: reply_fn() else: replyThread = threading.Thread(target=reply_fn) replyThread.setDaemon(True) replyThread.start()