刘威 6 月之前
父節點
當前提交
9df10ad1d0
共有 4 個文件被更改,包括 150 次插入50 次删除
  1. 9 7
      src/core/callcenter/agent.py
  2. 1 1
      src/core/callcenter/esl/client.py
  3. 119 29
      src/core/datasource.py
  4. 21 13
      src/core/voip/bot.py

+ 9 - 7
src/core/callcenter/agent.py

@@ -1,5 +1,6 @@
 #!/usr/bin/env python3
 # encoding:utf-8
+# from src.core.datasource import MysqlHandler
 from src.core.callcenter.model import AgentActionRequest, AgentInfo, AgentQueryRequest, AgentRequest
 
 
@@ -8,13 +9,8 @@ class AgentService:
     def __init__(self, client, logger):
         self.inbound_client = client
         self.logger = logger
-
-    def enable(self, request: AgentActionRequest):
-        pass
-
-    def disable(self, request: AgentActionRequest):
-        pass
-
+        # self.mysql_handler = MysqlHandler()
+    #
     def checkin(self, request: AgentActionRequest):
         pass
 
@@ -52,6 +48,7 @@ class AgentService:
         pass
 
     def detail(self, saas_id, agent_number):
+        self.mysql_handler.select_one('select * from c_agent where agent_num = %s', (agent_number, ))
         pass
 
     def count(self, request: AgentQueryRequest):
@@ -63,3 +60,8 @@ class AgentService:
     def delete(self, sass_id, agent_number):
         pass
 
+    def enable(self, request: AgentActionRequest):
+        pass
+
+    def disable(self, request: AgentActionRequest):
+        pass

+ 1 - 1
src/core/callcenter/esl/client.py

@@ -31,7 +31,7 @@ class InboundClient:
         self.bot_agent = BotAgent(logger)
         self.handler_table = self.scan_esl_event_handlers()
         self.default_event_handler = DefaultEslEventHandler(self, self.bot_agent, self.logger)
-        self.host, self.port, self.password = '192.168.100.159', '8021', '4918257983818884358'
+        self.host, self.port, self.password = '172.16.12.16', '8021', '4918257983818884358'
         self.executors = {x: concurrent.futures.ThreadPoolExecutor(max_workers=1) for x in range(self.thread_num)}
 
         threading.Thread(target=self.start, args=()).start()

+ 119 - 29
src/core/datasource.py

@@ -10,6 +10,7 @@ import decimal
 import traceback
 import pymysql
 import os
+from typing import List, Tuple
 from src.core import singleton
 from redis import StrictRedis, ConnectionPool
 
@@ -36,14 +37,14 @@ class MysqlHandler:
     """
 
     def __init__(self,
-                 # host='10.0.0.28',
-                 # user='root',
-                 # passwd='Hongshan2024@longjiang',
-
-                 host=MYSQL_HOST,
+                 host='172.16.12.16',
                  user='root',
-                 passwd=MYSQL_PASSWORD,
-                 db='big_model',
+                 passwd='12345678',
+
+                 # host=MYSQL_HOST,
+                 # user='root',
+                 # passwd=MYSQL_PASSWORD,
+                 db='libra_bot',
                  port=3306,
                  charset='utf8'
                  ):
@@ -79,18 +80,18 @@ class MysqlHandler:
                 _number += 1
                 time.sleep(stime)  # 连接不成功,休眠3秒钟,继续循环,知道成功或重试次数结束
 
-    def query(self, sql):
+    def select(self, query, params: Tuple = None):
         try:
             self._reConn()
             # 使用 cursor() 方法创建一个游标对象 cursor
             cursor = self.conn.cursor(pymysql.cursors.DictCursor)
             # 执行SQL语句
-            cursor.execute(sql)
+            cursor.execute(query, params)
             # 获取所有记录列表
             results = cursor.fetchall()
             return results
         except:
-            print(sql)
+            print(query, params)
             traceback.print_exc()
         finally:
             # 增/删/改均需要进行commit提交,进行保存
@@ -98,18 +99,81 @@ class MysqlHandler:
             # 关闭游标
             cursor.close()
 
-    def exec(self, sql):
+    def execute(self, sql, values: Tuple = None):
         try:
+            self._reConn()
             # 使用 cursor() 方法创建一个游标对象 cursor
-            cursor = self.db.cursor()
+            cursor = self.conn.cursor()
             # 执行SQL语句
-            cursor.execute(sql)
-            self.db.commit()
-        except Exception as e:
-            print(e)
+            cursor.execute(sql, values)
+            self.conn.commit()
+            return cursor.rowcount, cursor.lastrowid
+        except:
+            print(sql, values)
+            traceback.print_exc()
+            raise e
         finally:
             cursor.close()
 
+    def create_database(self, db_name: str):
+        sql = f"CREATE DATABASE IF NOT EXISTS `{db_name}` CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci;"
+        try:
+            self.execute(sql)
+            print(f"数据库'{db_name}'创建成功")
+        except pymysql.MySQLError as e:
+            print(f"创建数据库时发生错误: {e}")
+
+    def use_database(self, db_name: str):
+        try:
+            self.conn.select_db(db_name)
+        except pymysql.ProgrammingError as e:
+            print(f"切换至数据库'{db_name}'时发生错误: {e}")
+
+    def create_table(self, table_schema: str):
+        try:
+            self.execute(table_schema)
+            print("表创建成功")
+        except pymysql.MySQLError as e:
+            print(f"创建表时发生错误: {e}")
+
+    def insert(self, table_name: str, values: Tuple, columns: Tuple[str, ...] = None):
+        placeholders = ', '.join(['%s'] * len(values))
+        if columns:
+            columns_str = ', '.join(columns)
+            sql = f"INSERT INTO `{table_name}` ({columns_str}) VALUES ({placeholders})"
+        else:
+            sql = f"INSERT INTO `{table_name}` VALUES ({placeholders})"
+
+        try:
+            rowcount, lastrowid = self.execute(sql, values)
+            return lastrowid
+        except pymysql.MySQLError as e:
+            print(f"插入数据时发生错误: {e}")
+
+    def update(self, table_name: str, set_clause: str, where_clause: str, values: Tuple):
+        sql = f"UPDATE `{table_name}` SET {set_clause} WHERE {where_clause}"
+        try:
+            rowcount, lastrowid = self.execute(sql, values)
+            return rowcount
+        except pymysql.MySQLError as e:
+            print(f"更新数据时发生错误: {e}")
+
+    def delete(self, table_name: str, where_clause: str, values: Tuple):
+        sql = f"DELETE FROM `{table_name}` WHERE {where_clause}"
+        try:
+            rowcount, lastrowid = self.execute(sql, values)
+            return rowcount
+        except pymysql.MySQLError as e:
+            print(f"删除数据时发生错误: {e}")
+
+    def select_one(self, query: str, params: Tuple = None):
+        try:
+            result = self.select(query, params)
+            if result and len(result) > 0:
+                return result[0]
+        except pymysql.MySQLError as e:
+            print(f"执行查询时发生错误: {e}")
+
     def __del__(self):
         self.conn.close()
 
@@ -117,7 +181,7 @@ class MysqlHandler:
 @singleton
 class RedisHandler:
 
-    def __init__(self, host='192.168.100.195', port=6379, db=0, password='^YHN&UJM'):
+    def __init__(self, host='172.16.12.16', port=6379, db=0, password='^YHN&UJM'):
         try:
             # host = '10.0.0.24'
             # host = RADIS_HOST
@@ -162,15 +226,41 @@ class RedisHandler:
 #     #             # 在这里可以添加任何自定义的处理逻辑
 #
 #
-# def main1():
-#     mysql = MysqlHandler()
-#     count = mysql.query("select count(0) as totals from t_xinyi_industry where TEST_TIME like '%00'")
-#     print(count)
-#
-#     rows = mysql.query("select * from t_xinyi_industry where TEST_TIME like '%00' limit 10")
-#     for idx, cols in enumerate(rows):
-#         print(cols.get('TEST_TIME'), cols.get('JS_COD'))
-#
-#
-# if __name__ == "__main__":
-#     main()
+def main1():
+    mysql = MysqlHandler()
+    rows = mysql.select_one("select * from c_agent")
+    print(rows)
+
+    # # 创建数据库
+    # ds.create_database('new_database')
+    #
+    # # 切换到新数据库
+    # ds.use_database('new_database')
+    #
+    # # 创建表
+    # table_schema = """
+    # CREATE TABLE IF NOT EXISTS test_table (
+    #     id INT AUTO_INCREMENT PRIMARY KEY,
+    #     name VARCHAR(100),
+    #     email VARCHAR(100),
+    #     created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
+    # );
+    # """
+    # ds.create_table(table_schema)
+    #
+    # # 插入数据
+    # ds.insert('test_table', ('John Doe', 'john.doe@example.com'))
+    #
+    # # 更新数据
+    # set_clause = "name = %s, email = %s"
+    # where_clause = "id = %s"
+    # values = ('Jane Doe', 'jane.doe@example.com', 1)
+    # ds.update('test_table', set_clause, where_clause, values)
+    #
+    # # 删除数据
+    # where_clause = "id = %s"
+    # values = (1,)
+    # ds.delete('test_table', where_clause, values)
+
+if __name__ == "__main__":
+    main1()

+ 21 - 13
src/core/voip/bot.py

@@ -45,7 +45,7 @@ class MyAudioMediaPort(pj.AudioMediaPort):
         # self.wav.setnchannels(1)
         # self.wav.setsampwidth(2)  # 假设每个样本是 16 位(2 字节)
         # self.wav.setframerate(16000)
-
+        print("MyAudioMediaPort::come in, debugger")
         self.call = call
         self.aud_med = aud_med
         self.asr = asr
@@ -58,7 +58,7 @@ class MyAudioMediaPort(pj.AudioMediaPort):
 
     def onFrameReceived(self, frame):
         # self.wav.writeframes(bytes(frame.buf))
-        # print("Received audio frame:", frame.buf, frame.size)
+        print("Received audio frame:", frame.buf, frame.size)
         if self.asr:  # 如果ASR实例存在,则发送音频数据
             self.asr.send_audio(frame.buf)
 
@@ -74,6 +74,7 @@ class MyAudioMediaPort(pj.AudioMediaPort):
                 self.call.chat(user_asr_text)
 
             player_queue_size = self.call.player_queue.qsize()
+            print('onFrameReceived:player_queu_size=',player_queue_size,'play_complete=', play_complete)
             if (player_queue_size > 0 and not self.cur_player_file) or (player_queue_size > 0 and play_complete):
                 self.cur_player_file = self.get_player_file()
                 self.call.send_bot_speaker(self.cur_player_file)
@@ -89,7 +90,7 @@ class MyAudioMediaPort(pj.AudioMediaPort):
     def get_asr_text(self):
         try:
             asr_text = self.call.user_asr_text_queue.get(block=False)
-            print(asr_text)
+            print('get_asr_text:', asr_text)
             return asr_text
         except:
             pass
@@ -97,11 +98,12 @@ class MyAudioMediaPort(pj.AudioMediaPort):
     def get_player_file(self):
         try:
             player_file = self.call.player_queue.get(block=False)
-            print(player_file)
+            print('get_player_file:', player_file)
             return player_file
         except:
             pass
 
+
 class MyAudioMediaPlayer(pj.AudioMediaPlayer):
 
     def __init__(self, player_id, sink, on_complete=None):
@@ -178,9 +180,9 @@ class MyCall(pj.Call):
         # pj.PJSIP_INV_STATE_CONFIRMED
         # pj.PJSIP_INV_STATE_DISCONNECTED
 
-        if call_info.state == pj.PJSIP_INV_STATE_CONFIRMED:
-            # 当呼叫状态为已确认(即接通)
-            self.bot_say_hello()
+        # if call_info.state == pj.PJSIP_INV_STATE_CONFIRMED:
+        #     # 当呼叫状态为已确认(即接通)
+        #     self.bot_say_hello()
 
         if call_info.state == pj.PJSIP_INV_STATE_DISCONNECTED:
             print("通话结束")
@@ -198,6 +200,7 @@ class MyCall(pj.Call):
                 try:
                     # 建立双向通道
                     self.receive_user_speaker()
+                    self.bot_say_hello()
                 except Exception as e:
                     traceback.print_exc()
 
@@ -223,18 +226,23 @@ class MyCall(pj.Call):
         self.player_complete_dict[player_id] = True
 
     def bot_say_hello(self):
-        self.chat()
+        print('bot_say_hello, come in ')
+        self.chat(user_asr_text="SAY_HELLO")
 
     def chat(self, user_asr_text=None):
         # TODO 调用文本机器人接口
         message = {'player_file': self.scripts.get()}
         player = message.get('player_file')
-        self.player_queue.put(player)
+        print('chat::player_file=', player)
+        if "SAY_HELLO" == user_asr_text:
+            self.send_bot_speaker('/code/src/core/voip/test111.wav')
+        else:
+            self.player_queue.put(player)
 
 
 class BotAgent:
 
-    def __init__(self, logger, user_part_range=range(1001, 1011), host="192.168.100.159", port="5060", password="slibra@#123456"):
+    def __init__(self, logger, user_part_range=range(1001, 1011), host="172.16.12.16", port="5060", password="slibra@#123456"):
         self.logger = logger
         self.user_part_range, self.host, self.port, self.password = user_part_range, host, port, password
         self.user_part_pool = queue.Queue(maxsize=len(user_part_range))
@@ -278,9 +286,9 @@ class BotAgent:
             acfg.regConfig.retryIntervalSec = 10  # 重试间隔时间(秒)
             acfg.regConfig.firstRetryIntervalSec = 10  # 首次重试间隔时间(秒)
 
-            acfg.natConfig.iceEnabled = True
-            acfg.natConfig.turnEnabled = True
-            acfg.natConfig.turnServer = "stun:192.168.100.159:3478"
+            # acfg.natConfig.iceEnabled = True
+            # acfg.natConfig.turnEnabled = True
+            # acfg.natConfig.turnServer = "stun:192.168.100.159:3478"
             # acfg.natConfig.turnUsername = "username"
             # acfg.natConfig.turnPassword = "password"