From 461612e1663e49b601347ed8a137bfcf5453184b Mon Sep 17 00:00:00 2001 From: Richard Chien Date: Wed, 11 Jan 2017 13:29:40 +0800 Subject: [PATCH] Adjust filter structure --- apiclient.py | 21 +++++++--- app.py | 16 -------- docker-compose.yml | 1 + filters/intercept_some_message_formats_100.py | 16 ++++---- filters/speech_recognition_90.py | 40 ++++++++++++------- filters/split_at_xiaokai_50.py | 11 ++++- filters/unitize_context_message_10000.py | 25 ++++++++++++ 7 files changed, 85 insertions(+), 45 deletions(-) create mode 100644 filters/unitize_context_message_10000.py diff --git a/apiclient.py b/apiclient.py index 2ead4a91..10ecd01c 100644 --- a/apiclient.py +++ b/apiclient.py @@ -7,6 +7,13 @@ class ApiClient: qq_api_url = os.environ.get('QQ_API_URL') wx_api_url = os.environ.get('WX_API_URL') + def _api_url(self, via): + if via == 'qq': + return self.qq_api_url + elif via == 'wx': + return self.wx_api_url + return None + def send_message(self, content: str, ctx_msg: dict): msg_type = ctx_msg.get('type') if msg_type == 'group_message': @@ -67,16 +74,20 @@ class ApiClient: return None def get_group_info(self, via): - url = None - if via == 'qq': - url = self.qq_api_url - elif via == 'wx': - url = self.wx_api_url + url = self._api_url(via) if url: try: return requests.get(url + '/get_group_info') except requests.exceptions.ConnectionError: return None + def get_user_info(self, via): + url = self._api_url(via) + if url: + try: + return requests.get(url + '/get_user_info') + except requests.exceptions.ConnectionError: + return None + client = ApiClient() diff --git a/app.py b/app.py index 5f15d28f..a8128e1f 100644 --- a/app.py +++ b/app.py @@ -24,7 +24,6 @@ def _handle_wx_message(): def _main(ctx_msg: dict): - _preprocess_ctx_msg(ctx_msg) try: if ctx_msg.get('post_type') != 'receive_message': raise SkipException @@ -37,21 +36,6 @@ def _main(ctx_msg: dict): return '', 204 -def _preprocess_ctx_msg(ctx_msg: dict): - if 'group_uid' in ctx_msg: - ctx_msg['group_uid'] = str(ctx_msg['group_uid']) - if 'sender_uid' in ctx_msg: - ctx_msg['sender_uid'] = str(ctx_msg['sender_uid']) - if 'sender_id' in ctx_msg: - ctx_msg['sender_id'] = str(ctx_msg['sender_id']) - if 'discuss_id' in ctx_msg: - ctx_msg['discuss_id'] = str(ctx_msg['discuss_id']) - if 'group_id' in ctx_msg: - ctx_msg['group_id'] = str(ctx_msg['group_id']) - if 'id' in ctx_msg: - ctx_msg['id'] = str(ctx_msg['id']) - - def _load_filters(): filter_mod_files = filter( lambda filename: filename.endswith('.py') and not filename.startswith('_'), diff --git a/docker-compose.yml b/docker-compose.yml index de3dbe65..4ec8b02e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -46,6 +46,7 @@ services: - WX_SUPER_USER=abcdedfh - BAIDU_FANYI_APP_ID=YOUR_APP_ID - BAIDU_FANYI_API_KEY=YOUR_API_KEY + - SPEECH_RECOGNITION_SERVICE=baidu|bing - BAIDU_SPEECH_API_KEY=YOUR_API_KEY - BAIDU_SPEECH_SECRET_KEY=YOUR_SECRET_KEY - BING_SPEECH_API_KEY=YOUR_API_KEY diff --git a/filters/intercept_some_message_formats_100.py b/filters/intercept_some_message_formats_100.py index 0f165644..5e236a59 100644 --- a/filters/intercept_some_message_formats_100.py +++ b/filters/intercept_some_message_formats_100.py @@ -7,14 +7,12 @@ from filter import as_filter @as_filter(priority=100) def _filter(ctx_msg): - if ctx_msg.get('via') == 'wx': - msg_format = ctx_msg.get('format') - if msg_format != 'text' and ctx_msg.get('type') != 'friend_message': - return False - if msg_format not in ('text', 'media'): - return False - if msg_format == 'text': - ctx_msg['text'] = ctx_msg.get('content') - elif ctx_msg.get('via') == 'qq': + msg_format = ctx_msg.get('format') + if msg_format != 'text' and ctx_msg.get('type') != 'friend_message': + return False + if msg_format not in ('text', 'media'): + return False + if msg_format == 'text': + # Directly use the text in content as the 'text' ctx_msg['text'] = ctx_msg.get('content') return True diff --git a/filters/speech_recognition_90.py b/filters/speech_recognition_90.py index be10f952..cc67e018 100644 --- a/filters/speech_recognition_90.py +++ b/filters/speech_recognition_90.py @@ -4,6 +4,7 @@ This filter recognizes speech in voice message and stores it in 'text' field of import re import os +import sys import base64 import requests @@ -57,7 +58,7 @@ def _recognize_bing(wav_path, api_key, language='zh-CN'): @as_filter(priority=90) def _filter(ctx_msg): - if ctx_msg.get('via') == 'wx' and ctx_msg.get('format') == 'media' and ctx_msg.get('media_type') == 'voice': + if ctx_msg.get('format') == 'media' and ctx_msg.get('media_type') == 'voice': m = re.match('\[语音\]\(([/_A-Za-z0-9]+\.mp3)\)', ctx_msg.get('content')) if m: core.echo('正在识别语音内容,请稍等……', ctx_msg) @@ -65,20 +66,31 @@ def _filter(ctx_msg): wav_path = os.path.splitext(mp3_path)[0] + '.wav' voice = AudioSegment.from_mp3(mp3_path) voice.export(wav_path, format='wav') - text = _recognize_baidu( - wav_path, - ctx_msg.get('sender_id')[-60:], - os.environ.get('BAIDU_SPEECH_API_KEY'), - os.environ.get('BAIDU_SPEECH_SECRET_KEY'), - language='zh' - ) - # text = _recognize_bing( - # wav_path, - # os.environ.get('BING_SPEECH_API_KEY'), - # language='zh-CN' - # ) + + service = os.environ.get('SPEECH_RECOGNITION_SERVICE', '').lower() + text = None + service_full_name = None + if service == 'baidu': + service_full_name = '百度语音识别' + text = _recognize_baidu( + wav_path, + ctx_msg.get('sender_id')[-60:], + os.environ.get('BAIDU_SPEECH_API_KEY'), + os.environ.get('BAIDU_SPEECH_SECRET_KEY'), + language='zh' + ) + elif service == 'bing': + service_full_name = '必应语音识别' + text = _recognize_bing( + wav_path, + os.environ.get('BING_SPEECH_API_KEY'), + language='zh-CN' + ) + else: + print('Unknown speech recognition service name.', file=sys.stderr) + if text: - reply = '识别结果(百度语音识别):\n%s\n\n下面将把识别到的内容作为文字消息处理……' % text + reply = '识别结果(' + service_full_name + '):\n%s\n\n下面将把识别到的内容作为文字消息处理……' % text ctx_msg['text'] = text ctx_msg['from_voice'] = True else: diff --git a/filters/split_at_xiaokai_50.py b/filters/split_at_xiaokai_50.py index 395af040..6e5e83fc 100644 --- a/filters/split_at_xiaokai_50.py +++ b/filters/split_at_xiaokai_50.py @@ -3,6 +3,7 @@ This filter intercepts messages not intended to the bot and removes the beginnin """ from filter import as_filter +from apiclient import client as api @as_filter(priority=50) @@ -15,7 +16,15 @@ def _split_at_xiaokai(ctx_msg): return False at_me = '@' + my_group_nick if not text.startswith(at_me): - return False + user_info = api.get_user_info().json() + if not user_info: + return False + my_nick = user_info.get('nick') + if not my_nick: + return False + at_me = '@' + my_nick + if not text.startswith(at_me): + return False text = text[len(at_me):] else: # Not starts with '@' diff --git a/filters/unitize_context_message_10000.py b/filters/unitize_context_message_10000.py new file mode 100644 index 00000000..4936f3eb --- /dev/null +++ b/filters/unitize_context_message_10000.py @@ -0,0 +1,25 @@ +""" +This filter unitize context messages from different platform. +""" + +from filter import as_filter + + +@as_filter(priority=10000) +def _unitize(ctx_msg): + if 'group_uid' in ctx_msg: + ctx_msg['group_uid'] = str(ctx_msg['group_uid']) + if 'sender_uid' in ctx_msg: + ctx_msg['sender_uid'] = str(ctx_msg['sender_uid']) + if 'sender_id' in ctx_msg: + ctx_msg['sender_id'] = str(ctx_msg['sender_id']) + if 'discuss_id' in ctx_msg: + ctx_msg['discuss_id'] = str(ctx_msg['discuss_id']) + if 'group_id' in ctx_msg: + ctx_msg['group_id'] = str(ctx_msg['group_id']) + if 'id' in ctx_msg: + ctx_msg['id'] = str(ctx_msg['id']) + + if ctx_msg.get('via') == 'qq' and not ctx_msg.get('format'): + # All QQ messages that can be received are text + ctx_msg['format'] = 'text'