Selaa lähdekoodia

Merge pull request #1446 from 6vision/master

个人订阅号消息存储优化
zhayujie 2 vuotta sitten
vanhempi
säilyke
576526d4ee
2 muutettua tiedostoa jossa 31 lisäystä ja 24 poistoa
  1. 6 4
      channel/wechatmp/passive_reply.py
  2. 25 20
      channel/wechatmp/wechatmp_channel.py

+ 6 - 4
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(

+ 25 - 20
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,24 +83,28 @@ 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
-                    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] = ("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.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))
 
             elif reply.type == ReplyType.IMAGE_URL:  # 从网络下载图片
                 img_url = reply.content
@@ -119,7 +124,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 +139,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