def _generating(self): sha1 = hashlib.sha1(self._msg.encode()).hexdigest() ext = 'opus' if self.cfg.yandex_api(self._provider) in (2, 3) else 'mp3' find_part = ''.join(('_', sha1, '.')) rname = find_part + ext use_cache = self.cfg.gt('cache', 'tts_size', 50) > 0 msg_gen = '\'{}\' '.format(self._msg) if self._realtime: self.log('say {}'.format(msg_gen), logger.INFO) msg_gen = '' if use_cache and self._found_in_cache(find_part, ext): self._unlock() work_time = time.time() - self._start_time action = F('{}найдено в кэше', msg_gen) time_diff = '' else: if not use_cache and self._provider in ('rhvoice-rest', 'rhvoice'): ext = 'wav' self._buff_size *= 4 self._file_path = os.path.join(self.cfg.gt('cache', 'path'), self._provider + rname) if use_cache else \ '<{}><{}>'.format(sha1, ext) self._tts_gen(self._file_path if use_cache else None, ext, self._msg) self._unlock() work_time = time.time() - self._start_time action = F('{}сгенерированно {}', msg_gen, self._provider) reply = utils.pretty_time(self._work_time) diff = utils.pretty_time(work_time - self._work_time) time_diff = ' [reply:{}, diff:{}]'.format(reply, diff) return action, utils.pretty_time(work_time), time_diff
def run(self): wtime = time.time() sha1 = hashlib.sha1(self.msg.encode()).hexdigest() provider = self.cfg.get('providertts', 'google') rname = '_'+sha1 + '.mp3' if self.realtime: self.log('say \'{}\''.format(self.msg), logger.INFO) msg_gen = '' else: msg_gen = '\'{}\' '.format(self.msg) use_cache = self.cfg['cache'].get('tts_size', 50) > 0 self.file_path = self._find_in_cache(rname, provider) if use_cache else None if self.file_path: self._unlock() work_time = time.time() - wtime action = '{}найдено в кэше'.format(msg_gen) time_diff = '' else: format_ = 'mp3' if use_cache or provider in ['google', 'yandex'] else 'wav' self.file_path = os.path.join(self.cfg.path['tts_cache'], provider + rname) if use_cache else \ '<{}><{}>'.format(sha1, format_) self._tts_gen(self.file_path if use_cache else None, format_, self.msg) self._unlock() work_time = time.time() - wtime action = '{}сгенерированно {}'.format(msg_gen, provider) reply = utils.pretty_time(self.work_time) if self.work_time is not None else 'NaN' diff = utils.pretty_time(work_time - self.work_time) if self.work_time is not None else 'NaN' time_diff = ' [reply:{}, diff:{}]'.format(reply, diff) self.log( '{} за {}{}: {}'.format(action, utils.pretty_time(work_time), time_diff, self.file_path), logger.DEBUG if self.realtime else logger.INFO )
def config_load(self): wtime = time.time() if not os.path.isfile(self.path['settings']): self._print( 'Файл настроек не найден по пути {}. Для первого запуска это нормально' .format(self.path['settings']), logger.INFO) return config = configparser.ConfigParser() config.read(self.path['settings']) count = 0 for sec in config.sections(): if sec != self.SETTINGS: self._cfg_dict_checker(sec) for key in config[sec]: count += 1 if sec == self.SETTINGS: self[key] = self._cfg_convert(config, sec, key, self.get(key, None)) else: self[sec][key] = self._cfg_convert( config, sec, key, self[sec].get(key, None)) self._print( 'Загружено {} опций за {}'.format( count, utils.pretty_time(time.time() - wtime)), logger.INFO) self._print('Конфигурация загружена!', logger.INFO, mode=2)
def _api_authorization_totp(self, cmd, data): """ Перед хешированием токена добавляет к нему "соль" - Unix time поделенный на 2 и округленный до целого. Хеш будет постоянно меняться, но требует чтобы время на терминале и подключаемом устройстве точно совпадало. Также можно передать timestamp, он не участвует в хешировании но позволит узнать временную разницу: {"method":"authorization.totp","params":{"hash":"3a2af9d519e51c5bff2e283f2a3d384c6ey0721cb1d715ef356508c57bf1544c498328c59f5670e4aeb6bda135497f4e310960a77f88a046d2bb4185498d941f","timestamp":1582885520.931},"id":"8a5559310b336bad7e139550b7f648ad"} """ time_ = time.time() dict_key_checker(data, ('hash', )) remote_hash = data['hash'] if not isinstance(remote_hash, str): raise InternalException( 2, 'hash must be str, not {}'.format(type(remote_hash))) if 'timestamp' in data: timestamp = data['timestamp'] if not isinstance(timestamp, float): raise InternalException( 2, 'timestamp must be float, not {}'.format(type(timestamp))) else: timestamp = None time_diff = '; diff: {}'.format( pretty_time(time_ - timestamp)) if timestamp else '' return self._base_authorization( cmd, lambda token: check_token_with_totp(token, remote_hash, time_), time_diff)
def evaluate_solution_episodes(model: FewShotLearningSolution, validation_sampler: FSLEpisodeSampler, n_iterations=1000, device=torch.device("cuda:0" if torch.cuda.is_available() else "cpu")): val_start_time = time.time() print("Evaluation started...") model = model.to(device) model.eval() res_accuracy = 0 with torch.no_grad(): for i in range(n_iterations): support_set, batch = validation_sampler.sample() query_set, query_labels = batch query_set = query_set.to(device) query_labels = query_labels.to(device) output = model.forward(support_set, query_set) labels_pred = output.argmax(dim=1) labels = query_labels cur_accuracy = accuracy(labels=labels, labels_pred=labels_pred) res_accuracy += cur_accuracy res_accuracy /= n_iterations cur_time = time.time() val_time = cur_time - val_start_time print("Evaluation completed: accuracy = %.3f" % res_accuracy) print("Evaluation time: %s" % pretty_time(val_time)) return res_accuracy
def _lang_init(self): lang = self.gts('lang') deep_check = self.gts('lang_check', 0) err = languages.set_lang(lang, None if not deep_check else self._print) if err: self._print(LNG['err_lng'].format(lang, err), logger.ERROR) self._print(LNG['lng_load_for'].format(lang, utils.pretty_time(languages.load_time())), logger.INFO)
def _listen(self, hello: str, voice) -> tuple: lvl = 5 # Включаем монопольный режим commands = None if self.cfg.gts('alarmkwactivated'): self.own.play(self.cfg.path['ding'], lvl, blocking=2) else: self.own.set_lvl(lvl) self.own.kill_popen() self.log('audio devices: {}'.format(pyaudio.PyAudio().get_device_count() - 1), logger.DEBUG) hello = hello or self.sys_say.hello file_path = self.own.tts(hello) if not voice and hello else None if self.cfg.gts('blocking_listener'): audio, record_time, energy, rms = self._block_listen(hello, lvl, file_path) else: audio, record_time, energy, rms = self._non_block_listen(hello, lvl, file_path) self.log(F('Голос записан за {}', utils.pretty_time(record_time)), logger.INFO) # Выключаем монопольный режим self.own.clear_lvl() if self.cfg.gts('alarmstt'): self.own.play(self.cfg.path['dong']) if audio is not None: commands = self.voice_recognition(audio) if commands: self.log(utils.recognition_msg(commands, energy, rms), logger.INFO) return commands, rms
def test_test(self, providers: list, files: list, *_, **__): files = self._test_fill_file_paths(files) if not files: return providers = self._test_stt_providers(providers) if not providers: return p_offset = max(len(provider) for provider in providers) template = '{:#} [{:>~}]: {}'.replace('#', str(p_offset), 1) for name in files: result = self.own.multiple_recognition( os.path.join(self.cfg.path['test'], name), providers) result.sort(key=lambda x: x.time) result = { k.provider: { 'time': utils.pretty_time(k.time), 'result': str(k) } for k in result } t_offset = max(len(k['time']) for k in result.values()) head = template.replace('~', str(t_offset), 1) self.log('== Multiple recognition for {} =='.format(repr(name)), logger.INFO) for provider, data in result.items(): self.log( head.format(provider, data['time'], repr(data['result'])), logger.INFO) self.log('=' * (p_offset + 1), logger.INFO)
def start(self): upgraded = [] checked = 0 states = ('all', ) if self._settings['all'] else ('deprecated', 'broken') work_time = time.time() for state in states: if self._settings[state]: result = self._upgrade(self.own.plugins_status(state)) upgraded.extend(result[0]) checked += result[1] work_time = time.time() - work_time if checked: self.log('Checked {} plugins in {}'.format(checked, pretty_time(work_time))) if not upgraded: return if self._settings['restart']: msg = 'Restarting...' else: msg = 'Terminal must be restarted.' self.log('Updated plugins: {}. {}'.format(', '.join(upgraded), msg), logger.INFO) if self._settings['restart']: self.own.die_in(wait=8, reload=True)
def join_thread(self, obj): def obj_log(msg_: str, lvl=logger.DEBUG): if log_present: obj.log(msg_, lvl) def diagnostic_msg() -> str: _call = getattr(obj, 'diagnostic_msg', None) return ' {}'.format(_call()) if callable(_call) else '' with self._join_lock: close_signal = getattr(obj, 'close_signal', None) if close_signal: close_signal() if not obj.work: return log_present = callable(getattr(obj, 'log', None)) obj.work = False obj_log('stopping...') stop_time = time.time() obj.join() stop_time = time.time() - stop_time if not obj.is_alive(): obj_log('stop.', logger.INFO) else: obj_log('stopping error.', logger.ERROR) name_ = '.'.join(getattr(obj.log, 'name', [''])) if log_present else None name_ = name_ or str(obj) msg = 'Thread \'{}\' stuck and not stopping in {}!{}'.format( name_, pretty_time(stop_time), diagnostic_msg()) self.log(msg, logger.ERROR)
def _voice_recognition(self, audio, recognizer, quiet=False) -> str or None: prov = self._cfg.get('providerstt', 'google') key = self._cfg.key(prov, 'apikeystt') self.log('Для распознования используем {}'.format(prov), logger.DEBUG) wtime = time.time() try: if prov == 'google': command = recognizer.recognize_google(audio, language='ru-RU') elif prov == 'wit.ai': command = recognizer.recognize_wit(audio, key=key) elif prov == 'microsoft': command = recognizer.recognize_bing(audio, key=key) elif prov == 'pocketsphinx-rest': command = STT.PocketSphinxREST( audio_data=audio, url=self._cfg.get(prov, {}).get('server', 'http://127.0.0.1:8085') ).text() elif prov == 'yandex': command = STT.Yandex(audio_data=audio, key=key).text() else: self.log('Ошибка распознавания - неизвестный провайдер {}'.format(prov), logger.CRIT) return '' except (sr.UnknownValueError, STT.UnknownValueError): return None except (sr.RequestError, RuntimeError) as e: if not quiet: self._play.say('Произошла ошибка распознавания') self.log('Произошла ошибка {}'.format(e), logger.ERROR) return '' else: self.log('Распознано за {}'.format(utils.pretty_time(time.time() - wtime)), logger.DEBUG) return command or ''
def lang_init(self): lang = self.gts('lang') err = languages.set_lang(lang, self.gts('lang_check')) if err: self.log(F('Ошибка инициализации языка {}: {}', repr(lang), err), logger.ERROR) msg = F('Локализация {} загружена за {}', lang, utils.pretty_time(languages.set_lang.load_time)) self.log(msg, logger.INFO)
def _api_pong(self, _, data: str): """Считает пинг""" if data: try: data = time.time() - float(data) except (ValueError, TypeError): pass else: self.log('Ping {}'.format(pretty_time(data)), logger.INFO)
def _kill_overloads(pool: list): for target in pool: target.close_signal() for target in pool: time_ = time.time() target.join() time_ = time.time() - time_ if target.is_alive(): target.log( 'Instance stuck and not stopping in {}!'.format( pretty_time(time_)), logger.ERROR)
def config_load(self): wtime = time.time() if not os.path.isfile(self.path['settings']): self._print(LNG['miss_settings'].format(self.path['settings']), logger.INFO) return False updater = ConfigUpdater(self, self._print) count = updater.from_ini(self.path['settings']) wtime = time.time() - wtime self._lang_init() self._print(LNG['load_for'].format(count, utils.pretty_time(wtime)), logger.INFO) self._print(LNG['load'], logger.INFO, mode=2) return updater.save_me
def config_save(self): wtime = time.time() config = configparser.ConfigParser() for key, val in self.items(): if isinstance(val, dict): config[key] = val with open(self.path['settings'], 'w') as configfile: config.write(configfile) self._print(LNG['save_for'].format(utils.pretty_time(time.time() - wtime)), logger.INFO) self._print(LNG['save'], mode=2)
def _listen(self, hello: str, voice) -> str or None: max_play_time = 120 # максимальное время воспроизведения приветствия max_wait_time = 10 # ожидание после приветствия lvl = 5 # Включаем монопольный режим file_path = self._tts(random.SystemRandom().choice(self.HELLO) if not hello else hello) if not voice else None # self._play.quiet() if self._cfg['alarmkwactivated']: self._play.play(self._cfg.path['ding'], lvl) self.log('audio devices: {}'.format(pyaudio.PyAudio().get_device_count() - 1), logger.DEBUG) r = sr.Recognizer() mic = sr.Microphone(device_index=self.get_mic_index()) with mic as source: # Слушаем шум 1 секунду, потом распознаем, если раздажает задержка можно закомментировать. r.adjust_for_ambient_noise(source) if self._cfg['alarmtts'] and not hello: self._play.play(self._cfg.path['dong'], lvl) start_wait = time.time() if not voice: self._play.play(file_path, lvl) # Начинаем фоновое распознавание голосом после того как запустился плей. listener = NonBlockListener(r=r, source=mic, phrase_time_limit=20) if not voice: while listener.work() and self._play.really_busy() and time.time() - start_wait < max_play_time and self._work: # Ждем пока время не выйдет, голос не распознался и файл играет time.sleep(0.01) self._play.quiet() start_wait2 = time.time() while listener.work() and time.time() - start_wait2 < max_wait_time and self._work: # ждем еще секунд 10 time.sleep(0.01) self.log('Голос записан за {}'.format(utils.pretty_time(time.time() - start_wait)), logger.INFO) listener.stop() # Выключаем монопольный режим self._play.clear_lvl() commands = None if listener.audio is not None: if self._cfg['alarmstt']: self._play.play(self._cfg.path['dong']) commands = self._voice_recognition(listener.audio, listener.recognizer) if commands: self.log('Распознано: {}'.format(commands), logger.INFO) return commands
def run(self): wtime = time.time() sha1 = hashlib.sha1(self.msg.encode()).hexdigest() provider = self.cfg.gts('providertts', 'google') ext = 'mp3' if self.cfg.yandex_api(provider) != 2 else 'opus' find_part = ''.join(('_', sha1, '.')) rname = find_part + ext if self.realtime: self.log('say \'{}\''.format(self.msg), logger.INFO) msg_gen = '' else: msg_gen = '\'{}\' '.format(self.msg) use_cache = self.cfg['cache'].get('tts_size', 50) > 0 self.file_path = self._find_in_cache(provider, find_part, ext) if use_cache else None if self.file_path: self._unlock() work_time = time.time() - wtime action = LNG['action_cache'].format(msg_gen) time_diff = '' else: if not use_cache and provider in ('rhvoice-rest', 'rhvoice'): format_ = 'wav' self._buff_size = 1024 * 4 else: format_ = ext self.file_path = os.path.join(self.cfg.gt('cache', 'path'), provider + rname) if use_cache else \ '<{}><{}>'.format(sha1, format_) self._tts_gen(self.file_path if use_cache else None, format_, self.msg) self._unlock() work_time = time.time() - wtime action = LNG['action_gen'].format(msg_gen, provider) reply = utils.pretty_time(self.work_time) if self.work_time is not None else 'NaN' diff = utils.pretty_time(work_time - self.work_time) if self.work_time is not None else 'NaN' time_diff = ' [reply:{}, diff:{}]'.format(reply, diff) self.log( LNG['for_time'].format(action, utils.pretty_time(work_time), time_diff, self.file_path), logger.DEBUG if self.realtime else logger.INFO )
def _config_save(self): wtime = time.time() config = ConfigParserOnOff() for key, val in self.items(): if isinstance(val, dict): config[key] = val with open(self.path['settings'], 'w', encoding='utf8') as configfile: config.write(configfile) self.log( F('Конфигурация сохранена за {}', utils.pretty_time(time.time() - wtime)), logger.INFO) self.own.say_info(F('Конфигурация сохранена!'))
def _adata_parse(self, adata, model_name: str, phrases: str, vad, callback): if self.cfg.gts('chrome_alarmstt'): self.own.play(self.cfg.path['dong']) msg = self.own.voice_recognition(adata) if not msg: return if isinstance(vad, StreamDetector): model_name, phrase, _ = vad.model_info clear_msg = msg if model_name and phrase else None t_ = vad.recognition_time msg_ = F('Распознано за {}', pretty_time(t_)) if t_ else F( 'Записано за {}', pretty_time(vad.record_time)) self.log(msg_, logger.DEBUG) else: phrase, clear_msg = self.cfg.models.msg_parse(msg, phrases) if clear_msg is not None: # Нашли триггер в сообщении return self._detected_sr(clear_msg, model_name, ': "{}"'.format(phrase), vad, callback) # Не нашли триггер в сообщении - snowboy false positive self._detected_sr(msg, model_name, ': "{}"'.format(phrases), vad)
def config_load(self): wtime = time.time() if not os.path.isfile(self.path['settings']): msg = 'Файл настроек не найден по пути {}. Для первого запуска это нормально' self.log(F(msg, self.path['settings']), logger.INFO) return True updater = ConfigUpdater(self, self.log) count = updater.from_ini(self.path['settings']) wtime = time.time() - wtime self.lang_init() self.log( F('Загружено {} опций за {}', count, utils.pretty_time(wtime)), logger.INFO) self.own.say_info(F('Конфигурация загружена!')) return updater.save_ini
def rsync(local_file, remote_path, port=None, message='Synced'): try: start = datetime.datetime.now() if port: subprocess.check_call(['rsync', '-e ssh -p%s' % (port), '-pq', local_file, remote_path]) else: subprocess.check_call(['rsync', '-pq', local_file, remote_path]) except subprocess.CalledProcessError as e: logging.error('rsync returned %d for %s' % (e.returncode, os.path.basename(local_file))) else: logging.info("%s %s in %s" % (message, os.path.basename(local_file), pretty_time(datetime.datetime.now() - start)))
def _compile_model(self, model, models): phrase, match_count = self._stt.phrase_from_files(models) pmdl_name = ''.join(['model', model, self._cfg.path['model_ext']]) pmdl_path = os.path.join(self._cfg.path['models'], pmdl_name) # Начальные параметры для API сноубоя params = { key: self._cfg.gt('snowboy', key) for key in ('token', 'name', 'age_group', 'gender', 'microphone') } params['language'] = self._cfg.gts('lang', 'ru') if match_count != len(models): msg = LNG['no_consensus'].format(pmdl_name, match_count, len(models)) # Не создаем модель если не все фразы идентичны if self._cfg.gt('snowboy', 'clear_models') or self._cfg.gts('chrome_mode'): self.log(msg, logger.ERROR) self._play.say(LNG['err_no_consensus'].format(model)) return else: self.log(msg, logger.WARN) else: params['name'] = phrase.lower() self.log(LNG['compiling'].format(pmdl_path), logger.INFO) work_time = time.time() try: snowboy = training_service.Training(*models, params=params) except RuntimeError as e: self.log(LNG['err_compile_log'].format(pmdl_path, e), logger.ERROR) self._play.say(LNG['err_compile_say'].format(model)) return work_time = utils.pretty_time(time.time() - work_time) snowboy.save(pmdl_path) msg = ', "{}",'.format(phrase) if phrase else '' self.log(LNG['compile_ok_log'].format(msg, work_time, pmdl_path), logger.INFO) self._play.say(LNG['compile_ok_say'].format(msg, model, work_time)) self._cfg.update_from_dict({'models': {pmdl_name: phrase}}) self._cfg.models_load() self._reload() # Удаляем временные файлы for x in models: os.remove(x)
def config_save(self): wtime = time.time() config = configparser.ConfigParser() config.add_section(self.SETTINGS) for key, val in self.items(): if type(val) == dict: config[key] = val else: config.set(self.SETTINGS, key, str(val)) with open(self.path['settings'], 'w') as configfile: config.write(configfile) self._print( 'Конфигурация сохранена за {}'.format( utils.pretty_time(time.time() - wtime)), logger.INFO) self._print('Конфигурация сохранена!', mode=2)
def __backup(self, manual, remove_old) -> bool: def say(msg_: str): if manual: self.own.say(msg_, lvl=0) timestamp = time.time() if not manual: self._last_backup = timestamp self.cfg.save_state() filename = time.strftime('%Y.%m.%d-%H.%M.%S.zip', time.localtime(timestamp)) file_path = os.path.join(self.cfg.path['backups'], filename) fail_msg = F('Ошибка создания бэкапа') if os.path.exists(file_path): self.log(F('Файл {} уже существует, отмена.', filename), logger.ERROR) say('{} - {}'.format(fail_msg, F('файл уже существует'))) return False to_remove = self._candidates_to_remove() if remove_old else [] work_time = time.time() try: old_size, new_size = self._make_backup(timestamp, file_path) except Exception as e: self.log('{} {}:{}'.format(fail_msg, filename, e), logger.ERROR) say(fail_msg) try: os.remove(file_path) except IOError: pass return False work_time = time.time() - work_time rate = round(new_size / old_size, 2) old_size = utils.pretty_size(old_size) new_size = utils.pretty_size(new_size) work_time = utils.pretty_time(work_time) msg = F('Бэкап {} создан за {} [size: {}, compressed: {}, rate: {}%]', filename, work_time, old_size, new_size, rate) self.log(msg, logger.INFO) say(F('Бэкап успешно создан')) if to_remove: self._remove_candidates([x for x, _ in to_remove]) return True
def _rec_compile(self, param: list): models = [ os.path.join(self._cfg.path['tmp'], param[1] + x + '.wav') for x in ['1', '2', '3'] ] miss = False for x in models: if not os.path.isfile(x): miss = True err = 'Ошибка компиляции - файл {} не найден.' self.log(err.format(x), logger.ERROR) self._play.say(err.format(os.path.basename(x))) if miss: return pmdl_name = 'model' + param[1] + self._cfg.path['model_ext'] pmdl_path = os.path.join(self._cfg.path['models'], pmdl_name) self.log('Компилирую {}'.format(pmdl_path), logger.INFO) work_time = time.time() try: snowboy = training_service.Training(*models) except RuntimeError as e: self.log('Ошибка компиляции модели {}: {}'.format(pmdl_path, e), logger.ERROR) self._play.say('Ошибка компиляции модели номер {}'.format( param[1])) else: work_time = utils.pretty_time(time.time() - work_time) snowboy.save(pmdl_path) phrase = self._stt.phrase_from_files(models) msg = ', "{}",'.format(phrase) if phrase else '' self.log( 'Модель{} скомпилирована успешно за {}: {}'.format( msg, work_time, pmdl_path), logger.INFO) self._play.say( 'Модель{} номер {} скомпилирована успешно за {}'.format( msg, param[1], work_time)) self._cfg.models_load() if not self._api_settings({'models': {pmdl_name: phrase}}): self._terminal.reload() # Удаляем временные файлы for x in models: os.remove(x)
def restore(self, filename: str): self.log(F('Запущено восстановление из бэкапа {}...', filename), logger.INFO) error, path = self._check_file(filename) if not path: self.log(F('Восстановление не возможно: {}', error), logger.CRIT) return fail_msg = F('Восстановление не удалось: {}') if not self._backup(remove_old=False): self.log(fail_msg.format(F('бэкап не создан')), logger.CRIT) return work_time = time.time() try: count = self._restore(path) except Exception as e: self.log(fail_msg.format(e), logger.CRIT) else: work_time = utils.pretty_time(time.time() - work_time) self.log( F('Восстановление завершено за {}, восстановлено {} файлов', work_time, count), logger.INFO)
def _actions_event(self): # log, notify, custom, {stop, reset} msg = 'Thread of terminal stuck: {}'.format( self._terminal_diagnostic_msg()) if 'log' in self._actions: self.log(msg, logger.ERROR) if 'notify' in self._actions and self._send_notify: self._send_notify(msg) if self._custom_cmd: try: w_time = time.time() code = subprocess.call(self._custom_cmd, shell=True) w_time = time.time() - w_time self.log('Call \'{}\'. Code: {}, time: {}'.format( self._custom_cmd, code, pretty_time(w_time))) except OSError as e: self.log('Call \'{}\' failed: {}'.format(self._custom_cmd, e), logger.ERROR) if 'stop' in self._actions: self.own.die_in(5) elif 'reset' in self._actions: self.own.die_in(5, True)
def _voice_recognition(self, audio, quiet: bool = False, fusion=None, provider=None) -> utils.TextBox: def say(text: str): if not quiet: self.own.say(text) quiet = quiet or not self.cfg.gts('say_stt_error') prov = provider or self.cfg.gts('providerstt', 'unset') if not self.own.is_stt_provider(prov): self.log(F('Ошибка распознавания - неизвестный провайдер {}', prov), logger.CRIT) say(F('Ошибка распознавания - неизвестный провайдер {}', '')) return utils.TextBox('', prov) self.log(F('Для распознавания используем {}', prov), logger.DEBUG) wtime = time.time() key = None try: key = self.cfg.key(prov, 'apikeystt') command = STT.GetSTT( prov, audio_data=audio, key=key, lang=self.cfg.stt_lang(prov), url=self.cfg.gt(prov, 'server'), yandex_api=self.cfg.yandex_api(prov), grpc=self.cfg.gt(prov, 'grpc'), ).text() except STT.UnknownValueError: command = '' except Exception as e: say(F('Произошла ошибка распознавания')) msg = 'Ошибка распознавания речи от {}, ключ \'{}\'. ({})' if not isinstance(e, RuntimeError): e = utils.PrettyException(e) self.log(F(msg, prov, utils.mask_off(key), e), logger.ERROR) return utils.TextBox('', prov) if fusion: wtime = fusion() w_time = time.time() - wtime self.log(F('Распознано за {}', utils.pretty_time(w_time)), logger.DEBUG) return utils.TextBox(command or '', prov, w_time)
def voice_recognition(self, audio, quiet: int =0) -> str or None: prov = self._cfg.gts('providerstt', 'google') if quiet < 2: self.log(LNG['recognized_from'].format(prov), logger.DEBUG) wtime = time.time() try: key = self._cfg.key(prov, 'apikeystt') if prov == 'google': command = self._recognizer.recognize_google(audio, language=LNG['stt_lng']) elif prov == 'wit.ai': command = self._recognizer.recognize_wit(audio, key=key) elif prov == 'microsoft': command = self._recognizer.recognize_bing(audio, key=key, language=LNG['stt_lng']) elif prov == 'pocketsphinx-rest': command = STT.PocketSphinxREST( audio_data=audio, url=self._cfg.gt(prov, 'server', 'http://127.0.0.1:8085') ).text() elif prov == 'yandex': if self._cfg.yandex_api(prov) == 2: command = STT.YandexCloud(audio_data=audio, key=key).text() else: command = STT.Yandex(audio_data=audio, key=key).text() else: self.log(LNG['err_unknown_prov'].format(prov), logger.CRIT) return '' except (sr.UnknownValueError, STT.UnknownValueError): return '' except (sr.RequestError, RuntimeError) as e: if not quiet: self._play.say(LNG['err_stt_say']) self.log(LNG['err_stt_log'].format(e), logger.ERROR) return '' else: if quiet >= 2: self.log(LNG['recognized_from'].format(prov), logger.DEBUG) self.log(LNG['recognized_for'].format(utils.pretty_time(time.time() - wtime)), logger.DEBUG) return command or ''
def _listen(self, hello: str, voice) -> str or None: lvl = 5 # Включаем монопольный режим commands = None if self._cfg.gts('alarmkwactivated'): self._play.play(self._cfg.path['ding'], lvl, wait=0.01, blocking=2) else: self._play.set_lvl(lvl) self._play.kill_popen() self.log('audio devices: {}'.format(pyaudio.PyAudio().get_device_count() - 1), logger.DEBUG) hello = hello or self.sys_say.hello file_path = self._tts(hello) if not voice and hello else None if self._cfg.gts('blocking_listener'): audio, record_time, energy_threshold = self._block_listen(hello, lvl, file_path) else: audio, record_time, energy_threshold = self._non_block_listen(hello, lvl, file_path) self.log(LNG['record_for'].format(utils.pretty_time(record_time)), logger.INFO) # Выключаем монопольный режим self._play.clear_lvl() if self._cfg.gts('alarmstt'): self._play.play(self._cfg.path['dong']) if audio is not None: commands = self.voice_recognition(audio) if commands: msg = '' if energy_threshold: self.energy.set(energy_threshold) msg = ', energy_threshold={}'.format(int(energy_threshold)) self.log(LNG['recognized'].format(commands, msg), logger.INFO) else: self.energy.set(None) return commands
parser.add_option('--outputfile', '-o', action='store', dest='outputfile', help="""specify file to which output binary will be writen (by default, we'll overwrite the input binary file)""" ) parser.add_option('--disable-strict', action='store_true', default=False, dest='disablestrict', help="""in case of minor binary/patch compatibility troubles -e.g some patch token are contradictory w.r.t target binary file, etc.-, ignore and move on (option disabled by default)""" ) options, args = parser.parse_args() if len(args) < 2: parser.error('invalid command-line arguments') infile, patchfiles = args[0], args[1:] print __full_version__ print print 'Starting engines at %s (%s)' %pretty_time() for patchfile in patchfiles: try: patch(infile, patchfile, outfile=options.outputfile, revert=options.revert, strict=(not options.disablestrict) ) except: print 'caught excepiton while patching %s with %s (see traceback below); patch will be ignored\n%s' %(infile,patchfile,traceback.format_exc()) pass print 'Done: %s (%s).' %pretty_time()