class Test_UserImgCache: def setup_method(self,method): self.user_img = UserImgCache() def test_set_user_img(self): group_user_id = "100" img_data = buffer("test") url = self.user_img.set_user_img(group_user_id,img_data) logging.info(("create , url:",url)) # 下载下来确实是test def test_get_user_img_with_user_id(self): group_user_id = "100" url = self.user_img.get_user_img_with_user_id(group_user_id) logging.info(("with user id , url:",url)) def test_get_user_img_with_img_md5(self): img_data = buffer("test") img_md5= hashlib.md5(img_data).hexdigest() url = self.user_img.get_user_img_with_img_md5(img_md5) logging.info(("with img md5 , url:",url)) # None
def forward_message(msg, src_group, target_groups): '''按类型发消息''' msg["UserImg"] = '' if msg["Type"] == 'Text': ''' #print(itchat.get_friends()) # 消息入口 username = msg["ActualUserName"] # 发言用户id 群id:FromUserName user = itchat.search_friends(userName=username) ''' logger.info("forward_message begin") # log for debug logger.info(("forward message : ", msg)) # 多给msg一个属性 at_id message2push = {} message2push["group_name"] = src_group._group_name message2push["content"] = msg["Text"] message2push["group_user_name"] = msg["ActualNickName"] try: # todo 部分用户无法获取头像 chatroomid 错误 # 头像 # user_head_img = itchat.get_head_img(userName=msg["ActualUserName"],chatroomUserName=src_group._group_id,picDir="/tmp/wechat_user/{}".format(img_id)) #存储到本地 # todo:第一层缓存,获取头像之前,先检查本轮对话中 msg["ActualUserName"] # 是否被记录在本地数据库,免去向微信请求 user_img = UserImgCache() group_user_id = msg["ActualUserName"] url_get_with_user_id = user_img.get_user_img_with_user_id( group_user_id) # 第一层缓存 if url_get_with_user_id: message2push["user_img"] = url_get_with_user_id logger.info(("url_get_with_user_id: " + message2push["user_img"])) else: # 重新登录user id 变了,但是img md5还有效 # todo 无法获取头像 可能是这么问题 chatroomUserName logging.debug("ActualUserName :%s, src_group _group_id: %s", msg[ "ActualUserName"], src_group._group_id) img_data = itchat.get_head_img(userName=msg[ "ActualUserName"], chatroomUserName=src_group._group_id) # .getvalue()#前头是str #有时候错误 # logging.debug(img_data) img_md5 = hashlib.md5(buffer(img_data)).hexdigest() url_get_with_img_md5 = user_img.get_user_img_with_img_md5( img_md5) if url_get_with_img_md5: message2push["user_img"] = url_get_with_img_md5 logger.info(("url_get_with_img_md5: " + message2push["user_img"])) else: # 如果两级缓存都没有命中,再上传头像 url_with_uploading_img = user_img.set_user_img( group_user_id, buffer(img_data)) message2push["user_img"] = url_with_uploading_img logger.info(("url_with_uploading_img: " + message2push["user_img"])) msg["UserImg"] = message2push["user_img"] except Exception as e: logger.error("can not get user head img") logger.error('Failed to open file', exc_info=True) try: # 日志系统 if USE_LEANCLOUD: logger.info("ready to push message to cloud") push_message(message2push) logger.info("ready to push message to local file") logger.info(message2push) logger.info("ready to push message to local db(sqlite)") # 有问题 db_store.push_message(message2push) except Exception as e: logger.error("log error") logger.info(str(e)) # todo 有空优化 actual_user_name = msg["ActualNickName"] # for at id localuser_tool = LocalUserTool() # feature : at_id todo:插件化 at_id = localuser_tool.get_at_id(actual_user_name) if not at_id: at_id = localuser_tool.set_at_id(actual_user_name) # 改造消息对象,使其多一个at_id msg["at_id"] = at_id match_at_message = re.match( r'at *(?P<message_at_id>\d+) *(?P<message_text>.*)', msg["Text"]) if match_at_message: # 如果是at意图的消息 groupdict = match_at_message.groupdict() message_at_id = groupdict.get("message_at_id") message_text = groupdict.get("message_text") actual_user_name = localuser_tool.get_actual_user_name( int(message_at_id)) for group in target_groups: now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') logger.info((now, group._group_name, msg[ 'ActualNickName'], msg["Text"])) message = u'@{} \n{}-at_id:{} 发言 :\n{}'.format( actual_user_name, msg['ActualNickName'], msg['at_id'], message_text) #message = u'@{}\u2005\n : {}'.format(actual_user_name,message_text) itchat.send(message, group._group_id) else: # 如果不是at消息:即普通文本消息 # bot回复论坛消息 # handle_text_msg对消息做个分类,只做分析,handle_text_msg不主动发送消息,此处可嵌入插件 response = handle_text_msg(msg).get("response") if response: # 只回复本群 itchat.send(response, src_group._group_id) else: # 推送到其他群 for group in target_groups: now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') logger.info((now, group._group_name, msg[ 'ActualNickName'], msg["Text"])) # if group._group_id: message = '{}-at_id:{} 发言 :\n{}'.format( msg['ActualNickName'], msg['at_id'], msg['Text']) itchat.send(message, group._group_id) # 采用异步 # 之后的消息统一转发 if msg["Type"] == 'Picture': # todo:上传到云端 msg['Text'](msg['FileName']) # 下载 for group in target_groups: itchat.send_image(msg['FileName'], group._group_id) if msg['Type'] == 'Sharing': # 同样作为普通消息存入log share_message = "@{}分享\n{} {}".format( msg['ActualNickName'], msg["Url"].replace("amp;", ""), msg["Text"]) for group in target_groups: itchat.send_msg(share_message, group._group_id)
def setup_method(self, method): self.user_img = UserImgCache()
def forward_message(msg, src_group, target_groups): '''按类型发消息''' if msg["Type"] == 'Text': ''' print(itchat.get_friends()) # 消息入口 logger.info(msg) username = msg["ActualUserName"] # 发言用户id 群id:FromUserName user = itchat.search_friends(userName=username) ''' logger.info("forward_message begin") # log logger.info(("forward message : ", msg)) # log # 跨群@ , 至于私聊 可以截图发微信号 #把用户都存下,多给msg一个属性 at_id # logger.info((now, group._group_name, msg['ActualNickName'], msg["Text"])) # 存入云端 message2push = {} message2push["group_name"] = src_group._group_name message2push["content"] = msg["Text"] message2push["group_user_name"] = msg["ActualNickName"] try: # 头像 #user_head_img = itchat.get_head_img(userName=msg["ActualUserName"],chatroomUserName=src_group._group_id,picDir="/tmp/wechat_user/{}".format(img_id)) #存储到本地 # todo:第一层缓存,获取头像之前,先检查本轮对话中 msg["ActualUserName"] 是否被记录在本地数据库,免去向微信请求 user_img = UserImgCache() group_user_id = msg["ActualUserName"] url_get_with_user_id = user_img.get_user_img_with_user_id( group_user_id) #第一层缓存 if url_get_with_user_id: message2push["user_img"] = url_get_with_user_id logger.info( ("url_get_with_user_id: " + message2push["user_img"])) else: #重新登录user id 变了,但是img md5还有效 img_data = itchat.get_head_img( userName=msg["ActualUserName"], chatroomUserName=src_group._group_id) #.getvalue()#前头是str img_md5 = hashlib.md5(buffer(img_data)).hexdigest() url_get_with_img_md5 = user_img.get_user_img_with_img_md5( img_md5) if url_get_with_img_md5: message2push["user_img"] = url_get_with_img_md5 logger.info( ("url_get_with_img_md5: " + message2push["user_img"])) else: # 如果两级缓存都没有命中 url_with_uploading_img = user_img.set_user_img( group_user_id, buffer(img_data)) message2push["user_img"] = url_with_uploading_img logger.info(("url_with_uploading_img: " + message2push["user_img"])) except Exception as e: logger.info("can not get user head img") logger.info(str(e)) try: logger.info("ready to push message to cloud") if USE_LEANCLOUD: push_message(message2push) logger.info("ready to push message to local db(sqlite)") logger.info(message2push) db_store.push_message(message2push) #except e: except Exception as e: logger.info("can not push message") logger.info(str(e)) # 这样不好 ,有空优化 actual_user_name = msg["ActualNickName"] # for at id localuser_tool = LocalUserTool() at_id = localuser_tool.get_at_id(actual_user_name) if not at_id: at_id = localuser_tool.set_at_id(actual_user_name) # 改造消息属性,使其多一个at_id msg["at_id"] = at_id match_at_message = re.match( r'at *(?P<message_at_id>\d+) *(?P<message_text>.*)', msg["Text"]) if match_at_message: # at 的消息 groupdict = match_at_message.groupdict() message_at_id = groupdict.get("message_at_id") message_text = groupdict.get("message_text") actual_user_name = localuser_tool.get_actual_user_name( int(message_at_id)) for group in target_groups: now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') logger.info((now, group._group_name, msg['ActualNickName'], msg["Text"])) message = u'@{} \n{}-at_id:{} 发言 :\n{}'.format( actual_user_name, msg['ActualNickName'], msg['at_id'], message_text) #message = u'@{}\u2005\n : {}'.format(actual_user_name,message_text) itchat.send(message, group._group_id) else: #普通文本消息 # bot回复论坛消息 response = handle_text_msg(msg).get("response") #来源小组不一样,回复 if response: itchat.send(response, src_group._group_id) # 推送到其他群 else: #如果是网往论坛的则不转发 for group in target_groups: now = datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S') logger.info((now, group._group_name, msg['ActualNickName'], msg["Text"])) #if group._group_id: message = '{}-at_id:{} 发言 :\n{}'.format( msg['ActualNickName'], msg['at_id'], msg['Text']) itchat.send(message, group._group_id) # 采用异步 if msg["Type"] == 'Picture': # todo:上传到云端 msg['Text'](msg['FileName']) #下载 for group in target_groups: itchat.send_image(msg['FileName'], group._group_id) if msg['Type'] == 'Sharing': # 同样作为普通消息存入云端 share_message = "@{}分享\n{} {}".format(msg['ActualNickName'], msg["Url"].replace("amp;", ""), msg["Text"]) for group in target_groups: itchat.send_msg(share_message, group._group_id)
def simple_reply(msg): global groups global other_group_map #头像也用这个思路,groupUserName不需要永久化 print("group message input from wechat(begin)") # 互相转发的群 for group in groups: #logger.info(("local_group", group._group_id, group._group_name)) #logger.info("msg from group:{}".format(msg['FromUserName'])) if msg['FromUserName'] == group._group_id: # 一条消息只能匹配一次 src_group = group # 消息来源群组 target_groups = get_target_groups(src_group, tuple(groups)) # 消息发往的目标群 # 筛选出已激活的 active_target_groups = [group for group in target_groups if group._group_id] forward_message(msg, src_group, active_target_groups) # !!内部逻辑入口 if not group._group_id: # 如果群未被激活,则开始搜索群id # 每条消息都找一下,维护一个全局群id列表 group_instance = itchat.search_chatrooms(name=group._group_name) if group_instance: group.set_id(group_instance[0]['UserName']) print("{}激活,group_id:{}".format(group._group_name, group._group_id)) if DEBUG: itchat.send_msg('机器人已激活: )', group._group_id) # todo 都需要头像 拆分出来 # topic groups 只定期发送到大群 # forward_message(msg, src_group, active_target_groups) # 也是只存储,只是定期看一下数据,然后转让,定时任务 # 定时任务 不影响主线程 https://github.com/mrhwick/schedule/blob/master/schedule/__init__.py 仅仅把schedule.run_pending()改为run_continuously() # 使用本地数据库查询 时间用timestamp arrow # db_store.push_message(message2push) # 然后写查询 每2小时查询一下 pillow生成图片 使用jupyter来做 # 大体上的布局 [xx]:xxx # 需求 摘要+链接(网页) ############################################## # log other groups 记录群消息 # 作为群的一种类型 如果是这种类型的消息则不转发 只存储 # 获取群名,获取头像 独立函数 缓存 is_other_groups_msg = msg['FromUserName'] not in [group._group_id for group in groups] if setting.PUSH_ALL_GROUP_MESSAGE_TO_LEANCLOUD and is_other_groups_msg: # 没有头像 from leancloud_store import push_message other_group_FromUserName = msg['FromUserName'] other_group_NickName = other_group_map.get(other_group_FromUserName) # 建立缓存 维护一个字典即可,不需要永久化 todo 头像也这样做 if not other_group_NickName: other_group = itchat.search_chatrooms(userName=other_group_FromUserName) other_group_NickName = other_group["NickName"] logger.debug("store other_group_NickName to other_group_map") other_group_map[other_group_FromUserName] = other_group_NickName message2push={} message2push["content"] = msg["Text"] message2push["group_user_name"] = msg["ActualNickName"] message2push["CreateTime"] = timestamp2time(int(msg["CreateTime"])) message2push["group_name"] = other_group_NickName user_img_cache = UserImgCache() user_img_url = get_user_img(itchat,msg,user_img_cache,other_group_FromUserName) message2push["user_img"] = user_img_url logger.info("ready to push other group message to cloud") push_message(message2push)