From 2b3e643786a8dfd890ad034e189eaf16d139e9c7 Mon Sep 17 00:00:00 2001 From: 6vision Date: Sat, 23 Sep 2023 11:59:01 +0800 Subject: [PATCH 1/3] =?UTF-8?q?=E9=80=82=E9=85=8D=E4=B8=80=E6=AC=A1?= =?UTF-8?q?=E8=AF=B7=E6=B1=82=E5=A4=9A=E6=9D=A1=E5=9B=9E=E5=A4=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- channel/wechatmp/passive_reply.py | 10 ++++++---- channel/wechatmp/wechatmp_channel.py | 11 ++++++----- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/channel/wechatmp/passive_reply.py b/channel/wechatmp/passive_reply.py index 7f4ee550..d03efc4d 100644 --- a/channel/wechatmp/passive_reply.py +++ b/channel/wechatmp/passive_reply.py @@ -49,7 +49,7 @@ class Query: # New request if ( - from_user not in channel.cache_dict + channel.cache_dict.get(from_user) is None and from_user not in channel.running or content.startswith("#") and message_id not in channel.request_cnt # insert the godcmd @@ -131,8 +131,10 @@ class Query: # Only one request can access to the cached data try: - (reply_type, reply_content) = channel.cache_dict.pop(from_user) - except KeyError: + (reply_type, reply_content) = channel.cache_dict[from_user].pop(0) + if not channel.cache_dict[from_user]: # If popping the message makes the list empty, delete the user entry from cache + del channel.cache_dict[from_user] + except IndexError: return "success" if reply_type == "text": @@ -146,7 +148,7 @@ class Query: max_split=1, ) reply_text = splits[0] + continue_text - channel.cache_dict[from_user] = ("text", splits[1]) + channel.cache_dict[from_user].append(("text", splits[1])) logger.info( "[wechatmp] Request {} do send to {} {}: {}\n{}".format( diff --git a/channel/wechatmp/wechatmp_channel.py b/channel/wechatmp/wechatmp_channel.py index 6f21ce11..d470f1f5 100644 --- a/channel/wechatmp/wechatmp_channel.py +++ b/channel/wechatmp/wechatmp_channel.py @@ -10,6 +10,7 @@ import requests import web from wechatpy.crypto import WeChatCrypto from wechatpy.exceptions import WeChatClientException +from collections import defaultdict from bridge.context import * from bridge.reply import * @@ -46,7 +47,7 @@ class WechatMPChannel(ChatChannel): self.crypto = WeChatCrypto(token, aes_key, appid) if self.passive_reply: # Cache the reply to the user's first message - self.cache_dict = dict() + self.cache_dict = defaultdict(list) # Record whether the current message is being processed self.running = set() # Count the request from wechat official server by message_id @@ -82,7 +83,7 @@ class WechatMPChannel(ChatChannel): if reply.type == ReplyType.TEXT or reply.type == ReplyType.INFO or reply.type == ReplyType.ERROR: reply_text = reply.content logger.info("[wechatmp] text cached, receiver {}\n{}".format(receiver, reply_text)) - self.cache_dict[receiver] = ("text", reply_text) + self.cache_dict[receiver].append(("text", reply_text)) elif reply.type == ReplyType.VOICE: try: voice_file_path = reply.content @@ -99,7 +100,7 @@ class WechatMPChannel(ChatChannel): return media_id = response["media_id"] logger.info("[wechatmp] voice uploaded, receiver {}, media_id {}".format(receiver, media_id)) - self.cache_dict[receiver] = ("voice", media_id) + self.cache_dict[receiver].append(("voice", media_id)) elif reply.type == ReplyType.IMAGE_URL: # 从网络下载图片 img_url = reply.content @@ -119,7 +120,7 @@ class WechatMPChannel(ChatChannel): return media_id = response["media_id"] logger.info("[wechatmp] image uploaded, receiver {}, media_id {}".format(receiver, media_id)) - self.cache_dict[receiver] = ("image", media_id) + self.cache_dict[receiver].append(("image", media_id)) elif reply.type == ReplyType.IMAGE: # 从文件读取图片 image_storage = reply.content image_storage.seek(0) @@ -134,7 +135,7 @@ class WechatMPChannel(ChatChannel): return media_id = response["media_id"] logger.info("[wechatmp] image uploaded, receiver {}, media_id {}".format(receiver, media_id)) - self.cache_dict[receiver] = ("image", media_id) + self.cache_dict[receiver].append(("image", media_id)) else: if reply.type == ReplyType.TEXT or reply.type == ReplyType.INFO or reply.type == ReplyType.ERROR: reply_text = reply.content From 79c7f0c29f0eb58bc615681eeb8a9fbe30e299ee Mon Sep 17 00:00:00 2001 From: 6vision Date: Sat, 23 Sep 2023 13:27:36 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E4=B8=AA=E4=BA=BA=E8=AE=A2=E9=98=85?= =?UTF-8?q?=E5=8F=B7=E9=95=BF=E8=AF=AD=E9=9F=B3=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- channel/wechatmp/wechatmp_channel.py | 36 +++++++++++++++------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/channel/wechatmp/wechatmp_channel.py b/channel/wechatmp/wechatmp_channel.py index d470f1f5..347a8867 100644 --- a/channel/wechatmp/wechatmp_channel.py +++ b/channel/wechatmp/wechatmp_channel.py @@ -85,22 +85,26 @@ class WechatMPChannel(ChatChannel): logger.info("[wechatmp] text cached, receiver {}\n{}".format(receiver, reply_text)) self.cache_dict[receiver].append(("text", reply_text)) elif reply.type == ReplyType.VOICE: - try: - voice_file_path = reply.content - with open(voice_file_path, "rb") as f: - # support: <2M, <60s, mp3/wma/wav/amr - response = self.client.material.add("voice", f) - logger.debug("[wechatmp] upload voice response: {}".format(response)) - # 根据文件大小估计一个微信自动审核的时间,审核结束前返回将会导致语音无法播放,这个估计有待验证 - f_size = os.fstat(f.fileno()).st_size - time.sleep(1.0 + 2 * f_size / 1024 / 1024) - # todo check media_id - except WeChatClientException as e: - logger.error("[wechatmp] upload voice failed: {}".format(e)) - return - media_id = response["media_id"] - logger.info("[wechatmp] voice uploaded, receiver {}, media_id {}".format(receiver, media_id)) - self.cache_dict[receiver].append(("voice", media_id)) + voice_file_path = reply.content + duration, files = split_audio(voice_file_path, 60 * 1000) + if len(files) > 1: + logger.info("[wechatmp] voice too long {}s > 60s , split into {} parts".format(duration / 1000.0, len(files))) + + for path in files: + # support: <2M, <60s, mp3/wma/wav/amr + try: + with open(path, "rb") as f: + response = self.client.media.upload("voice", f) + logger.debug("[wechatmp] upload voice response: {}".format(response)) + f_size = os.fstat(f.fileno()).st_size + time.sleep(1.0 + 2 * f_size / 1024 / 1024) + # todo check media_id + except WeChatClientException as e: + logger.error("[wechatmp] upload voice failed: {}".format(e)) + return + media_id = response["media_id"] + logger.info("[wechatmp] voice uploaded, receiver {}, media_id {}".format(receiver, media_id)) + self.cache_dict[receiver].append(("voice", media_id)) elif reply.type == ReplyType.IMAGE_URL: # 从网络下载图片 img_url = reply.content From 5ba8fdc5e709c2d34317f2381b9aaa22de7e7ce2 Mon Sep 17 00:00:00 2001 From: vision Date: Sat, 23 Sep 2023 14:31:54 +0800 Subject: [PATCH 3/3] fix --- channel/wechatmp/wechatmp_channel.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/channel/wechatmp/wechatmp_channel.py b/channel/wechatmp/wechatmp_channel.py index 347a8867..2ae88228 100644 --- a/channel/wechatmp/wechatmp_channel.py +++ b/channel/wechatmp/wechatmp_channel.py @@ -94,7 +94,7 @@ class WechatMPChannel(ChatChannel): # support: <2M, <60s, mp3/wma/wav/amr try: with open(path, "rb") as f: - response = self.client.media.upload("voice", f) + response = self.client.material.add("voice", f) logger.debug("[wechatmp] upload voice response: {}".format(response)) f_size = os.fstat(f.fileno()).st_size time.sleep(1.0 + 2 * f_size / 1024 / 1024)