def __init__(self,msg,type): ''' 初始化消息内容,参数是从itchat接收到的msg内容。 ''' self.createTime = time.strftime("%Y-%m-%d %H:%M:%S",time.localtime(msg.CreateTime)) # 创建时间 self.text = msg.Text # 数据内容 self.remarkName = '' if msg.Type in type_dict: # 根据数据类型做特殊处理 self.text = tdtr(type_dict[msg.Type]) self.text = self.text.replace("\n","\n\033[99999999999999999D") # 将换行替换掉,因为出现换行要重新定位光标到行首 # 根据不同类型做不同判断 if "u" == type: if "NickName" not in msg.User: self.nickName = msg.User.UserName else : self.nickName = msg.User.NickName # 消息发送者昵称 if "RemarkName" not in msg.User: self.remarkName = msg.User.UserName else : self.remarkName = msg.User.RemarkName # 消息发送者备注 self.userName = msg.User.UserName # 用户名,是微信接口中的id,唯一。 elif "r" == type: user = Users.instance().getUserByUserName(msg.ActualUserName) if user is not None: self.remarkName = user.remarkName # 消息发送者备注 self.nickName = msg.ActualNickName # 消息发送者昵称 self.userName = msg.ActualUserName # 用户名,是微信接口中的id,唯一。 else : print(tdtr("消息类型参数错误,请重试"))
def group(self, arg): ''' 群发模式,请指定群发模式: group id1 id2 id3 id... 消息将发送给指定的所有人 ''' user_name_list = [] if len(arg) == 0: print(tdtr("请指定群发对象的id,例如: 'group 3 34 36 23 74'")) return elif arg[0] == '-inverse': # 反选模式,指定的好友不会收到消息。 for uid in [x.id for x in self.parent.getUsers()]: if str(uid) not in arg[1:]: user_name_list.append( self.parent.getUserByID(uid).userName) else: # 正选模式 for uid in arg: if uid == ' ': # 过滤掉空格 continue try: user_id = int(uid) except Exception: continue user_name_list.append( self.parent.getUserByID(user_id).userName) while (True): print(tdtr( "【群发模式】选定的{}位好友将收到此条信息 \n请输入要发送的内容,输入“cd ..”退出\n>>> ").format( len(user_name_list)), end='') msg = td_input() if msg == 'cd ..' or msg == 'cd ../': # 退出聊天,把当前正在沟通的用户置为None self.parent.current_user = None break # 如果输入内容包含疑似cmd字符串,这个len不为0 if len( list( filter(lambda x: True if x in msg else False, cmd_list))) > 0: print(tdtr("您的输入中包含疑似shell终端命令的字符串,确认发送此消息吗?y or n")) res = td_input() if res == 'y' or res == 'yes': pass else: continue # 如果能走到这一步就发送数据 for name in user_name_list: self.parent.sendMsg(msg, name) # 将信息发送给user userName是微信用于识别的用户名
def __init__(self,*args): self.id = args[0] # id self.userName = args[1] # 微信指定的的唯一用户名 self.nickName = args[2] # 昵称 self.remarkName = args[3] # 备注 self.type = tdtr(user_type_dict[args[4]]) # 类型 f | r ---> 好友 | 群聊 self.msgs = []
def handelMsg(self, msg, type): ''' 处理接收到的消息,或打印或存入消息队列 type : 好友信息是 f 群聊消息是 r ''' user = self.getUserByUserName(msg.FromUserName) if msg['ToUserName'] == 'filehelper': # 文件助手发送来的消息,做特殊处理 user = self.getUserByID(0) elif msg['ToUserName'] != self.selfUser.userName: # 忽略掉发送目标不是自己的 return elif msg[ 'FromUserName'] == self.selfUser.userName: # 忽略掉自己发来的消息(否则发送给群聊的消息会被排入队列) return if msg['FromUserName'] == 'newsapp': # 忽略掉腾讯新闻消息 return if msg['FromUserName'] == 'filehelper': return if user is not None: m = Msg(msg, type) if user == self.current_user: # 如果当时正在和这个人聊天 if not has_msg(): # 如果输入区为空的话,直接打印消息 td_print(( "\n\033[99999999999999999D【{}】{} ===> :{}\n\033[99999999999999999D" + tdtr(" 与 {} 聊天中 >>> ")).format( m.createTime, m.getName(), m.text, self.current_user.getName()), end="") td_print("\033[s", end="") # 保存光标位置 else: user.addMsg(m) else: # 如果不是的话,直接排入消息队列 user.addMsg(m)
def outer(func): if cmd not in CmdType: td_print(tdtr("注册类型错误!CmdType中不包含此类型,请在类中添加")) exit(-1) func_dict[cmd] = func def register(*args, **kwargs): return func(*args, **kwargs) return register
def ignore(self, arg): ''' 忽略指定的消息 , 命令示例: - ignore 123 忽略掉id为123的用户发送来的所有消息 - ignore all 忽略掉所有消息 ''' if len(arg) == 0: print(tdtr("参数错误,请重试")) return self.parent.ignore(arg[0])
def find(self, arg): ''' 通过字符串查找对象 , 命令示例: find 张三 李四 三级狗 ''' if len(arg) == 0: print(tdtr("参数错误,请重试")) return result = [] print(tdtr("查找到以下好友|群聊:")) for keywords in arg: # 列表拆分 关键字进行模糊查询 for user in self.parent.getUsers(): if keywords in user: # User的in重写过! if user not in result: # 已经存在的不再添加防止重复 result.append(user) # x 就是每一个user # 注意map是一个惰性序列,必须要list一下才会执行 list( map( lambda x: print(" {:^4}:{:^4} {:^4} {:^4} ".format( x.id, x.type, x.remarkName, x.nickName)), result))
def ignore(self,arg): ''' 忽略掉对应的内容 ''' if arg == 'all': # 忽略掉所有消息 print(tdtr("确认忽略所有未读消息吗?y or n")) res = td_input() if res == 'y' or res == 'yes': # 忽略所有 for user in self.getUsers(): user.msgs.clear() else: return else: try: uid = int(arg) except Exception : print(tdtr("参数错误,请重试")) return if uid not in self.user_dict: print(tdtr("参数错误,请重试")) return self.getUserByID(uid).msgs.clear()
def ls(self, arg): ''' 获取最新消息列表 ''' if len(arg) == 0: # ls 没有参数:获取所有消息列表 if not self.parent.hasNewMsg(): # 没有新消息 print(tdtr("消息列表为空")) else: for user in self.parent.getUsers(): if user.hasNewMsg(): # 消息列表必须不为空 # 如果消息列表不为空,就把这个人的消息都打印出来 print( tdtr("【id:{:^3} 】 {:^10} 发来 {:^3} 条未读消息").format( user.id, user.getName(), len(user.msgs))) elif arg[0] == '-a': # ls -a 获取全部好友 + 群聊 print(tdtr("好友 | 群聊列表:")) for user in self.parent.getUsers(): print(" {:^4}:{:^4} {:^3} ".format(user.id, user.type, user.getName())) elif arg[0] == '-f': # ls -f 好友列表 print(tdtr("好友列表:")) for user in filter(lambda x: x.type == tdtr('【好友】'), self.parent.getUsers()): print(" {:^4}:{:^4} {:^3} ".format(user.id, user.type, user.getName())) elif arg[0] == '-r': # ls -f 群聊列表 print(tdtr("群聊列表:")) for user in filter(lambda x: x.type == tdtr('【群聊】'), self.parent.getUsers()): print(" {:^4}:{:^4} {:^3} ".format(user.id, user.type, user.getName())) else: print(tdtr('参数错误,请重试'))
def exec(self): ''' 用户模块的事件循环 ''' try: while True: print(">>> ",end = '') cmd = minput().strip() # 获取字符去除前后空格 if cmd == '': # 输入无效内容,直接跳过 continue if cmd == 'exit': itchat.logout() break cmd = cmd.split(' ') # 命令去除前后空格后按空格分割 if cmd[0] not in dir(self.cmd): print(tdtr("命令错误,请重试")) continue # 调用cmd所匹配的函数,通过反射的形式调用 即只要用户输入指令与函数名匹配即可调用。 getattr(self.cmd,cmd[0])(cmd[1:]) except Exception as e: print(e) itchat.logout()
def cd(self, arg): ''' 进入聊天室, cd {id} 进入与id进行聊天的界面 ''' if len(arg) == 0: print(tdtr("cd命令需要参数")) return elif arg[0] == '..' or arg[0] == '../': # 返回主页 return else: try: user_id = int(arg[0]) except Exception: print(tdtr("cd后请输入一个数字")) return user = self.parent.getUserByID(user_id) if user is None: # 未找到用户 直接返回 print(tdtr("用户id不存在,请重试")) return self.parent.current_user = user self.cls(None) # 进入与其聊天的死循环 while True: # 进入后先把队列中的消息打印 while user.hasNewMsg(): msg = user.takeMsg() print("【{}】{} ===> :{}".format(msg.createTime, msg.getName(), msg.text)) print(tdtr(" 与 {} 聊天中 >>> ").format(user.getName()), end='') msg = td_input() if msg.strip() == 'cd ..' or msg.strip() == 'cd ../': # 退出聊天,把当前正在沟通的用户置为None self.parent.current_user = None break if msg.strip() == "emoj": print( tdtr( "检测到您的输入为:emoj,如果发送消息内容即为emoj直接回车键发送,如果查看所有emoj表情,请输入1:" )) res = td_input() if res != "1": pass else: print(emoj_list) continue # 如果输入内容包含疑似cmd字符串,这个len不为0 if len( list( filter(lambda x: True if x in msg else False, cmd_list))) > 0: print(tdtr("您的输入中包含疑似shell终端命令的字符串,确认发送此消息吗?y or n")) res = td_input() if res == 'y' or res == 'yes': pass else: continue # 如果能走到这一步就发送数据 if user.id == 0 or user.id == '0': # 处理发送给文件助手的消息 self.parent.sendMsg(msg, 'filehelper') else: self.parent.sendMsg( msg, user.userName) # 将信息发送给user userName是微信用于识别的用户名
def emoj(self, arg): # 显示所有可用的emoj表情 print(tdtr("所有可用表情如下,在消息中直接添加即可发送:")) print(emoj_list)
# Authro : ThreeDog # Data : 2019-06-12 # Function : 共同包,存放一些公共的定义,主要是程序中用到文字转化的地方 from tdinput import td_input from translator import tdtr from time import ctime # 消息类型,转化成对应的消息类型显示 type_dict = { 'Map': tdtr('[定位]'), 'Card': tdtr('[名片推荐]'), 'Note': tdtr('[系统消息]'), 'Sharing': tdtr('[公众号链接]'), 'Picture': tdtr('[图片]'), 'Recording': tdtr('[语音]'), 'Attachment': tdtr('[文件]'), 'Video': tdtr('[视频]') } # 支持的表情: emoj_dict = { "emoj1": "[微笑]", "emoj2": "[撇嘴]", "emoj3": "[色]", "emoj4": "[发呆]", "emoj5": "[得意]", "emoj6": "[流泪]", "emoj7": "[害羞]", "emoj8": "[闭嘴]", "emoj9": "[睡]",