def wait_for_this_reply(self, content): result = self.wait_for_reply() retry = 0 content = to_str(content) while to_str(result).find(content) == -1 \ and retry < self.MAX_RETRY_TIMES: result = self.wait_for_reply() retry += 1 if to_str(result).find(content) == -1: self.logging.error( "System welcome does not include welcome words in your configuration!" ) # exit() return result
def process_chat(self, from_name, msg, skip_welcome=True, max_wait=None, login_wait=None): if msg.find('START_ROBOT') > -1: return '你好' # Get reply data = { 'uid': to_str(from_name.encode('utf-8')), 'msg': to_str(msg.encode('utf-8')) } result = self.handler.chat(data) if isinstance(result, dict): result = json.dumps(result) return result.encode('utf-8')
def handle_string(self, result): extra_data = {} result = to_str(result) # extract image data pic_token, result = StringExtractor.extract_type( AnswerTokenType.IMAGE_ATTACH, result) # extract extra data data_token, result = StringExtractor.extract_type( AnswerTokenType.QUERY_ATTACH, result) if data_token: data_url = self.config.get_config('data_url', None) if data_url: r = requests.get(data_url, headers={'key': data_token}, timeout=2) extra_data = r.json() else: test_logger.warning("No data url found") data, result = StringExtractor.extract_json(result) if data: extra_data.update(json.loads(data)) result = StringExtractor.extract_dialogue_stat(result, extra_data) result = StringExtractor.listen_silence(result, extra_data) result = StringExtractor.end_session(result, extra_data) result = StringExtractor.cut_answer(result) business, result = StringExtractor.extract_business_identify(result) if 'slots' in extra_data: extra_data = extra_data['slots'] slots = [] for item in extra_data: if item['name'] == 'chat_key': continue if item['name'] == 'query_text': continue if item['name'] == 'action_name': continue if item['name'] == 'bot_name': continue slots.append('%s=%s' % (item['name'], item['value'])) slots.sort() extra_data = ' '.join(slots) else: extra_data = str(extra_data) return extra_data, result
def process_chat(self, from_name, msg, skip_welcome=True, max_wait=None, login_wait=None): if msg.find('START_ROBOT') > -1: return '你好' # Get reply data = { 'uid': to_str(from_name.encode('utf-8')), 'msg': to_str(msg.encode('utf-8')), 'appkey': 'qiwu-grader', 'nickname': 'tester', 'new_session': 'false', 'max_wait': '20' } result = self.handler.chat(data) if isinstance(result, dict): result = json.dumps(result) return result.encode('utf-8')
def process_chat(self, from_name, msg, max_wait=None, login_wait=None): result = '' skip_first = False # Refresh active time self.active[from_name] = time.time() # If token exist, set chat key. Or login to chat robot if from_name in self.tokens: chat_key = self.tokens[from_name] self.handler.set_chatkey(chat_key) self.logging.debug('Existed user {0} chat with chatkey {1}'.format( from_name, chat_key)) else: chat_key = self.handler.login(self.robot_name) self.tokens[from_name] = chat_key skip_first = True self.logging.debug('New user {0} login with chatkey {1}'.format( from_name, chat_key)) result = self.handler.wait_for_welcome() result_str = to_str(result) self.logging.info( 'Login Res: {0} Length: {1} for chatkey {2}'.format( result_str, str(len(result_str)), chat_key)) if login_wait: time.sleep(login_wait) self.logging.debug('User ask: {0} with chatkey'.format( msg.encode('utf-8'), chat_key)) if skip_first and len(result) != 0: time.sleep(self.handler.wait_duration) # Send question result = self.handler.chat_with_check(msg) # If send action doesn't have reply, wait for a reply if len(result) == 0: result = self.handler.wait_for_reply() # Post process result string ''' result = result.replace('\n', ' ') result = result.replace('\r', ' ') result = result.replace('Marco', str(self.nicknames[from_name])) result = result.strip() ''' # print 'Res: ' + result return result
def process_chat(self, from_name, msg, skip_welcome=True, max_wait=None, login_wait=None): if msg.find('START_ROBOT') > -1: return '你好' uid = from_name if msg == 'reset': del self.session[uid] return 'RESET' msg = allowed_bot_msg_filter(msg) if uid not in self.session: self.session[uid] = str( uid) + ChatRobot.CHAT_KEY_RANDOM_SPLITTER + id_generator(20) # Get reply data = { 'uid': to_str(from_name.encode('utf-8')), 'msg': to_str(msg.encode('utf-8')), 'chat_key': self.session[uid], 'chatKey': '', 'appkey': self.app_key, 'nickname': 'tester', 'new_session': 'false', 'max_wait': '20' } result = self.handler.chat(data) if isinstance(result, dict): result = json.dumps(result) return result.encode('utf-8')
def test_robot(self, name, questions, answers, sessions=None): if sessions is None: sessions = {} if self.test_type == 'api': test_service = SingleDialogueHandler(self.config) else: test_service = pMsgHandler(self.config, test_logger) uid = self.uid_prefix + id_generator(20) last_session = 1 test_service.robot_name = name # items_op = getattr(questions, "iteritems", None) # question_items = callable(items_op) and questions.iteritems() or questions.items() grade = 0 total_time = 0 for i, question in questions.items(): if sessions.get(i, -1) != last_session: uid = self.uid_prefix + id_generator(20) last_session = sessions.get(i, -1) process_time = time.time() # turn question into a string and handle chat if type(question) == int: question_str = str(question) else: question_str = question response = test_service.handle_chat(uid, question_str, login_wait=0) data = None response = to_str(response) if response.find(AnswerTokenType.QUERY_ATTACH.value) != -1 \ or response.find(StringExtractor.DATA_ATTACH_SEPARATOR): try: data, response = self.handle_string(response) except Exception: test_logger.info("Failed to retrive data") chat_key = None if hasattr(test_service, 'tokens') and uid in test_service.tokens: chat_key = test_service.tokens[uid] process_time = time.time() - process_time correct = True if response.find(self.TIMEOUT_REPLY) == 0: correct = False if response == self.REQUEST_TIMEOUT: correct = False if response == self.REQUEST_ERROR_REPLY: correct = False answer_str = 'No answer found for question {0}'.format(i) if correct and answers and i in answers and answers[i]: response = to_str(response) # if data: # temp_res = response # response = data # data = temp_res answer = answers[i] correct = False if isinstance(answer, dict): if 'multi' in answer: answer_str = json.dumps( answer, ensure_ascii=False).encode('utf-8') for j, item in enumerate(answer['multi']): if response.find(item.encode('utf-8')) != -1: correct = True break if 'regex' in answer: answer_str = answer['regex'].encode('utf-8') match_obj = re.match(answer_str, response) if match_obj: correct = True else: answer_str = answer.encode('utf-8') if response.find(to_str(answer_str)) != -1: correct = True if correct: grade += 1 total_time += process_time if self.print_csv: csv_string = str(last_session) csv_string += ",Question {0}".format(i) csv_string += "," + uid csv_string += "," + to_str(question.encode('utf-8')).replace( ",", ",") csv_string += "," + to_str(response).replace(",", ",") csv_string += "," + to_str(answer_str).replace(",", ",") csv_string += "," + (correct and "Passed" or "Wrong") csv_string += "," + "{:.5f}".format(process_time) if data: csv_string += "," + str(len(data)) csv_string += "," + data csv_logger.info(csv_string) if self.print_info: if self.print_conversation: if self.print_details: question_str = to_str(question_str.encode('utf-8')) test_logger.info( "Session {0} Question {1}: {2}".format( last_session, i, question_str)) response = to_str(response) if chat_key: test_logger.info("Chatkey: {0})".format(chat_key)) test_logger.info("Response :" + response) if self.print_correct_answer or not correct: answer_str = to_str(answer_str) test_logger.info("Answer: " + answer_str) test_logger.info((correct and "Passed" or "Wrong") + " for " + uid) test_logger.info( "Processed in {:.5f} seconds".format(process_time)) test_logger.info("=============") else: test_logger.info( "Question {0}: {1} in {2} seconds".format( i, correct and "Passed" or "Wrong", process_time)) if not correct: test_logger.info("Answer: " + to_str(response)) elif not correct: test_logger.warning("Q {0} WA vc: {1}".format( i, to_str(response))) # print ("Q {0} Wrong answer: {1}".format(i, response)) if not correct and self.suspend_on_error: break if not correct and self.pause_on_error: test_logger.info( "Pause thread for 10 seconds due to incorrect response") time.sleep(10) if self.question_interval > 0.1: time.sleep(self.question_interval) # end of question loop if self.print_csv: csv_logger.info("{0},{1} / {2},{3},{4}".format( name, grade, len(questions), total_time, total_time / len(questions))) report_logger.info("{0} grade: {1} / {2}\ntime: {3} avg: {4}".format( name, grade, len(questions), total_time, total_time / len(questions))) return grade == len(questions) and True or False, total_time
def test_robot(self, name, questions, answers): if self.test_type == 'api': test_service = SingleDialogueHandler(self.config) else: test_service = pMsgHandler(self.server, test_logger) uid = "grader_" + id_generator(10) test_service.robot_name = name if self.print_csv: write_utf_bom() # items_op = getattr(questions, "iteritems", None) # question_items = callable(items_op) and questions.iteritems() or questions.items() grade = 0 total_time = 0 for i, question in questions.items(): process_time = time.time() # turn question into a string and handle chat if type(question) == int: question_str = str(question) else: question_str = question response = test_service.handle_chat( uid, question_str, login_wait=self.question_interval) chat_key = None if hasattr(test_service, 'tokens'): chat_key = test_service.tokens[uid] process_time = time.time() - process_time correct = True answer_str = 'No answer found for question {0}'.format(i) if answers and i in answers: answer = answers[i] correct = False if isinstance(answer, dict): if 'multi' in answer: answer_str = json.dumps( answer, ensure_ascii=False).encode('utf-8') for j, item in enumerate(answer['multi']): if response.find(item.encode('utf-8')) != -1: correct = True break if 'regex' in answer: answer_str = answer['regex'].encode('utf-8') match_obj = re.match(answer_str, response) if match_obj: correct = True else: answer_str = answer.encode('utf-8') if response.find(answer_str) != -1: correct = True else: if response == self.ERROR_REPLY: correct = False if correct: grade += 1 total_time += process_time if self.print_csv: csv_string = "Question {0},{1}".format( i, to_str(question.encode('utf-8')).replace(",", ",")) csv_string += "," + to_str(response).replace(",", ",") csv_string += "," + to_str(answer_str).replace(",", ",") csv_string += "," + (correct and "Passed" or "Wrong") csv_string += "," + "Processed in {:.5f} seconds".format( process_time) csv_logger.info(csv_string) if self.print_info: if self.print_conversation: if self.print_details: question_str = to_str(question_str.encode('utf-8')) test_logger.info("Question {0}: {1}".format( i, question_str)) response = to_str(response) if chat_key: test_logger.info( "Chatkey: {1} Response: {0}".format( response, chat_key)) else: test_logger.info("Response :" + response) if self.print_correct_answer or not correct: answer_str = to_str(answer_str) test_logger.info("Answer: " + answer_str) test_logger.info(correct and "Passed" or "Wrong") test_logger.info( "Processed in {:.5f} seconds".format(process_time)) test_logger.info("=============") else: test_logger.info( "Question {0}: {1} in {2} seconds".format( i, correct and "Passed" or "Wrong", process_time)) if not correct: test_logger.info("Answer: " + response) elif not correct: test_logger.warning("Q {0} Wrong answer: {1}".format( i, to_str(response))) # print ("Q {0} Wrong answer: {1}".format(i, response)) if not correct and self.suspend_on_error: break if self.question_interval > 0.1: time.sleep(self.question_interval) # end of question loop if self.print_csv: csv_logger.info("{0},{1} / {2},{3},{4}".format( name, grade, len(questions), total_time, total_time / len(questions))) report_logger.info("{0} grade: {1} / {2}\ntime: {3} avg: {4}".format( name, grade, len(questions), total_time, total_time / len(questions))) return grade == len(questions) and True or False, total_time
def chat(self, data, max_wait=None): if self.threshold and self.threshold > 1: return SingleDialogue.DEFAULT_REPLY payload = to_str(self.payload % data) headers = {} if self.method == "POST": headers['content-type'] = self.type # if self.type.find('urlencoded') != -1: # form = urllib.parse.parse_qs(payload) # form['chat_key'] = [data['uid']] # payload = urllib.parse.urlencode(form) r = None result = None try: if self.method == 'GET': r = self.session.get(self.url, params=payload, headers=headers, timeout=max_wait or self.timeout) else: payload = encode_str(payload) r = self.session.post(self.url, data=payload, headers=headers, timeout=max_wait or self.timeout) result = r.json() except requests.exceptions.Timeout: self.logger.error("request timeout {0} {1}:{2}".format( self.method, self.host, self.port)) return SingleDialogue.REQUEST_TIMEOUT except ValueError as e: if r: self.logger.info("error decoding: " + r.text) self.logger.exception(e) self.logger.error("request value error {0} {1}:{2}".format( self.method, self.host, self.port)) return SingleDialogue.ERROR_REPLY except requests.exceptions.RequestException as e: self.logger.info(e) self.logger.error("request error {0} {1}:{2}".format( self.method, self.host, self.port)) return SingleDialogue.ERROR_REPLY except Exception as e: self.logger.error("request exception {0} {1}:{2}".format( self.method, self.host, self.port)) self.logger.exception(e) return SingleDialogue.ERROR_REPLY if result and self.answer_key in result: if not self.threshold: if self.data_key: attach_data = None if self.data_key == '.': attach_data = result elif self.data_key in result: attach_data = result[self.data_key] if attach_data: return result[self.answer_key] + json.dumps( attach_data, ensure_ascii=False) return result[self.answer_key] else: if 'probability' in result and result[ 'probability'] > self.threshold: cut = result['reply'].find(' ( ') if cut > -1: return result[self.answer_key][:cut] return result[self.answer_key] elif result is None: return SingleDialogue.RESULT_NONE_REPLY return SingleDialogue.DEFAULT_REPLY