def get_weather(): url = 'https://api.thinkpage.cn/v3/weather/daily.json?' data = { "key": "enygxphjelwni53z", "location": "anyang", "language": "zh-Hans", "unit": "c", "start": "0", "days": "2", } url = url + parse.urlencode(data) req = request.Request(url) try: with request.urlopen(req, timeout=5) as req: content = req.read().decode("utf-8") data = json.loads(content) if data and isinstance(data, dict): return data["results"][0]["daily"] else: baidu_voice.Voice.tts("天气获取失败") except Exception as e: log.exp("获取天气 %s" % url, e) baidu_voice.Voice.tts("天气获取失败") return url
def insert(text): try: conn = "" conn = connector.connect(host=mysql_con.HOST, user=mysql_con.USERNAME, password=mysql_con.PASSWORD, port=mysql_con.PORT, database=mysql_con.DATABASE, charset=mysql_con.CHARSET) cursor = conn.cursor() cursor.execute( "INSERT INTO command (`content`,`status`,`posttime`) VALUES (%s,%s,%s)", (text, 0, datetime.timestamp(datetime.now()))) # 提交记录 conn.commit() log.normal("往数据库中插入新命令:" + text) except Exception as e: log.exp("往数据库中插入新命令:" + text, e) finally: if "" != conn: conn.close()
def exec(command_id): try: conn = "" conn = connector.connect(host=mysql_con.HOST, user=mysql_con.USERNAME, password=mysql_con.PASSWORD, port=mysql_con.PORT, database=mysql_con.DATABASE, charset=mysql_con.CHARSET) cursor = conn.cursor() cursor.execute("UPDATE command SET `status`=%s WHERE id=%s", ('1', command_id)) # 提交记录 conn.commit() log.normal("更新命令状态 命令编号:%d" % command_id) except Exception as e: log.exp("更新命令状态 命令编号:%d" % command_id, e) finally: if "" != conn: conn.close()
def get_text(cls, file_name): log.normal("音频转文字: " + file_name) # 请求地址 request_url = "http://vop.baidu.com/server_api" # 参数 p_rate = config.RATE # 采样率,支持 8000 或者 16000 p_cuid = "FC-AA-14-D0-1D-67" # 用户唯一标识,用来区分用户,填写机器 MAC 地址,长度为60以内 p_token = cls.get_access_token() # 开放平台获取到的开发者 access_token fp = wave.open(file_name, 'rb') nf = fp.getnframes() p_len = nf * 2 p_speech = fp.readframes(nf) srv_url = request_url + '?cuid=' + p_cuid + '&token=' + p_token http_header = [ 'Content-Type: audio/pcm; rate=%d' % p_rate, 'Content-Length: %d' % p_len ] c = pycurl.Curl() c.setopt(pycurl.URL, str(srv_url)) # curl doesn't support unicode c.setopt(c.HTTPHEADER, http_header) # must be list, not dict c.setopt(c.POST, 1) c.setopt(c.CONNECTTIMEOUT, 30) c.setopt(c.TIMEOUT, 30) c.setopt(c.WRITEFUNCTION, cls.parse_text_result) c.setopt(c.POSTFIELDS, p_speech) c.setopt(c.POSTFIELDSIZE, p_len) try: c.perform() except Exception as e: log.exp("语音转文字发生异常。", e)
def deal(trans_id, trans_script_name,trans_script_arvg): try: log.normal("执行命令: 命令编号: %d 脚本名称: %s 参数:%s" % (trans_id, trans_script_name, trans_script_arvg)) os.system("python script/%s %s" % (trans_script_name, trans_script_arvg)) except Exception as e: log.exp("执行命令: 命令编号: %d 脚本名称: %s 参数:%s" % (trans_id, trans_script_name, trans_script_arvg), e)
def save_wave_file(file_name, data): try: with wave.open(file_name, 'wb') as wf: wf.setnchannels(1) wf.setsampwidth(2) wf.setframerate(config.RATE) wf.writeframes(b''.join(data)) except IOError as e: log.exp("保存wav文件失败: " + file_name, e)
def get_access_token(): if "" != Voice.access_token_cache: log.normal("从缓存获取baidu_access_token成功") return Voice.access_token_cache # access_token 保存文件 access_token_filename = "cache/token/baidu_access_token" # 计算时间差,21天换一次 modifiedtime = time.localtime(os.stat(access_token_filename).st_mtime) y = time.strftime('%Y', modifiedtime) m = time.strftime('%m', modifiedtime) d = time.strftime('%d', modifiedtime) try: if 21 > (datetime.now() - datetime(int(y), int(m), int(d))).days: with open(access_token_filename, "r") as file: Voice.access_token_cache = file.read() log.normal("从文件获取baidu_access_token成功") return Voice.access_token_cache except BaseException as e: log.exp("获取baidu_access_token发生异常。", e) return False # 请求地址 grant_type = "client_credentials" # 固定值 client_id = "dnHpAdOFm2jxG0rmnfDbxSsT" # api key client_secret = "c5046dee23e31cf9b542953425f7821e" # secret key request_url_token = "https://openapi.baidu.com/oauth/2.0/token?grant_type=" + grant_type\ + "&client_id=" + client_id \ + "&client_secret=" + client_secret try: with request.urlopen(request_url_token) as f: data = f.read() if 200 != f.status: # 获取错误,返回false log.warning("获取baidu_access_token失败,网络错误") return False data = json.loads(data.decode('utf-8')) log.normal("获取baidu_access_token成功") # 保存到文件 with open(access_token_filename, "w") as file: file.write(data["access_token"]) Voice.access_token_cache = data["access_token"] return Voice.access_token_cache except Exception as e: log.exp("获取baidu_access_token发生异常。", e) return False
def deal(filename): try: filename_before = "cache/sound/" + "before_" + filename log.normal("开始处理音频文件:" + filename_before) # 转换文字 baidu_voice.Voice.get_text(filename_before) # 重命名文件,避免表明重复扫描 os.rename(filename_before, "cache/sound/" + "end_" + filename) log.normal("音频文件处理完毕:" + filename_before) except Exception as e: log.exp("处理音频文件发生异常: ", e)
def start(): # 扫描目录 root_dir = "cache/sound" log.normal("开始扫描音频文件...") while True: try: for file in os.listdir(root_dir): # 搜索 before_ 开头的wav文件 re_wav = re.compile(r'^before_(.+)') m = re_wav.match(file) if m: # 开始处理音频文件 VoiceScan.deal(m.group(1)) except Exception as e: log.exp("扫描音频文件发生异常: ", e)
def tts(cls, text): if len(text) > 1024: log.warning("tts文本过长") return False log.normal("TTS: " + text) # 参数 p_token = cls.get_access_token() # 开放平台获取到的开发者 access_token p_cuid = "FC-AA-14-D0-1D-67" # 用户唯一标识,用来区分用户,填写机器 MAC 地址,长度为60以内 request_url = "http://tsn.baidu.com/text2audio?" data = { "tex": text, "lan": "zh", "tok": p_token, "cuid": p_cuid, "ctp": 1, "spd": "4", "pit": "3", "vol": "9", "per": "3", } request_url_tts = request_url + parse.urlencode(data) try: with request.urlopen(request_url_tts) as f: data = f.read() if 200 != f.status: # 获取错误,返回false log.warning("获取baidu_tts失败,网络错误") return False log.normal("获取baidu_tts成功") # 保存到文件 random.seed() filename = "cache/mp3/" + datetime.now().strftime("%Y-%m-%d_%H_%M_%S") + \ str(random.randint(0, 99999)) + ".mp3" with open(filename, "wb") as file: file.write(data) # 播放 cls.play_mp3(filename) return True except Exception as e: log.exp("获取baidu_tts发生异常。", e) return False
def trans(command_id, content): try: log.normal("执行命令: 命令编号: %d 内容: %s" % (command_id, content)) try: conn = "" conn = connector.connect(host=mysql_con.HOST, user=mysql_con.USERNAME, password=mysql_con.PASSWORD, port=mysql_con.PORT, database=mysql_con.DATABASE, charset=mysql_con.CHARSET) cursor = conn.cursor() cursor.execute("""SELECT * FROM translates WHERE (`type`=1 AND command=%s) OR (`type`=0 AND command LIKE %s)""", (content, "%" + content + "%", )) is_exec = False # 获取所有记录 row = cursor.fetchone() if None is not row: # 处理 CommandScan.deal(row[0], row[2], row[3]) is_exec = True cursor.close() if False is is_exec: log.normal("命令未执行: 命令编号: %d 内容: %s" % (command_id, content)) except Exception as e: log.exp("翻译命令: %s" % content, e) finally: command.Command.exec(command_id) if "" != conn: conn.close() except Exception as e: log.exp("翻译命令: 命令编号: %d 内容: %s" % (command_id, content), e)
def play_mp3(filename): log.normal("播放MP3 " + filename) try: if os.path.isfile(filename): if os.path.getsize(filename): path_now = os.path.dirname(os.path.abspath(__file__)) if "nt" == os.name: # windows player = os.path.join(path_now, "player", "mpg123-win32.exe") else: # mac linux player = os.path.join(path_now, "player", "mpg123-mac") os.system("%s %s" % (player, filename)) else: log.warning("播放MP3错误,文件不存在:" + filename) else: log.warning("播放MP3错误,文件不存在:" + filename) except Exception as e: log.exp("播放MP3发生异常。", e)
def start(): # 扫描目录 log.normal("开始扫描数据库中未完成的命令...") try: conn = "" while True: try: conn = connector.connect(host=mysql_con.HOST, user=mysql_con.USERNAME, password=mysql_con.PASSWORD, port=mysql_con.PORT, database=mysql_con.DATABASE, charset=mysql_con.CHARSET) cursor = conn.cursor() cursor.execute("SELECT * FROM command WHERE status=%s ORDER BY posttime", ('0', )) # 获取所有记录 results = cursor.fetchall() for row in results: # 处理 CommandScan.trans(row[0], row[1]) cursor.close() time.sleep(1) except Exception as e: log.exp("扫描音频文件发生异常: ", e) finally: if "" != conn: conn.close() except Exception as e: log.exp("扫描数据库未完成命令", e)