def process_media_voice(bot, update, media, name):
    chat_id = get_chat_id(update)
    file_size = media.file_size

    if file_size >= 20 * (1024**2):
        message_id = get_message_id(update)
        bot.send_message(chat_id=chat_id,
                         text=R.get_string_resource(
                             "file_too_big", TBDB.get_chat_lang(chat_id)) +
                         "\n",
                         reply_to_message_id=message_id,
                         parse_mode="html",
                         is_group=chat_id < 0)
        return

    file_id = media.file_id
    file_path = os.path.join(
        config.get_config_prop("app")["media_path"], file_id)
    file = bot.get_file(file_id)
    file.download(file_path)

    try:
        transcribe_audio_file(bot, update, file_path)
    except Exception as e:
        logger.error("Exception handling %s from %d: %s", name, chat_id,
                     traceback.format_exc())
    finally:
        os.remove(file_path)
def transcribe_audio_file(bot, update, path):
    chat_id = get_chat_id(update)
    lang = TBDB.get_chat_lang(chat_id)
    message_id = get_message_id(update)
    is_group = chat_id < 0

    api_key = config.get_config_prop("wit").get(lang, None)
    if api_key is None:
        logger.error("Language not found in wit.json %s", lang)
        message = bot.send_message(
            chat_id=chat_id,
            text=R.get_string_resource("unknown_api_key",
                                       lang).format(language=lang) + "\n",
            reply_to_message_id=message_id,
            parse_mode="html",
            is_group=is_group).result()
        return
    logger.debug("Using key %s for lang %s", api_key, lang)

    message = bot.send_message(
        chat_id=chat_id,
        text=R.get_string_resource("transcribing", lang) + "\n",
        reply_to_message_id=message_id,
        parse_mode="html",
        is_group=is_group).result()

    TranscriberBot.get().start_thread(message_id)
    logger.debug("Starting thread %d", message_id)

    keyboard = InlineKeyboardMarkup(
        [[InlineKeyboardButton("Stop", callback_data=message_id)]])

    text = ""
    if is_group:
        text = R.get_string_resource("transcription_text", lang) + "\n"
    success = False

    for speech in audiotools.transcribe(path, api_key):
        logger.debug("Thread %d running: %r", message_id,
                     TranscriberBot.get().thread_running(message_id))
        if TranscriberBot.get().thread_running(message_id) is False:
            TranscriberBot.get().del_thread(message_id)
            return

        retry = True
        retry_num = 0

        while retry and TranscriberBot.get().thread_running(message_id):
            try:
                if len(text + " " + speech) >= 4000:
                    text = R.get_string_resource("transcription_continues",
                                                 lang) + "\n"
                    message = bot.send_message(
                        chat_id=chat_id,
                        text=text + " " + speech + " <b>[...]</b>",
                        reply_to_message_id=message.message_id,
                        parse_mode="html",
                        is_group=is_group,
                        reply_markup=keyboard).result()
                else:
                    message = bot.edit_message_text(
                        text=text + " " + speech + " <b>[...]</b>",
                        chat_id=chat_id,
                        message_id=message.message_id,
                        parse_mode="html",
                        is_group=is_group,
                        reply_markup=keyboard).result()

                text += " " + speech
                retry = False
                success = True

            except telegram.error.TimedOut as t:
                logger.error("Timeout error %s", traceback.format_exc())
                retry_num += 1
                if retry_num >= 3:
                    retry = False

            except telegram.error.RetryAfter as r:
                logger.warning("Retrying after %d", r.retry_after)
                time.sleep(r.retry_after)

            except telegram.error.TelegramError as te:
                logger.error("Telegram error %s", traceback.format_exc())
                retry = False

            except Exception as e:
                logger.error("Exception %s", traceback.format_exc())
                retry = False

    retry = True
    retry_num = 0
    while retry and TranscriberBot.get().thread_running(message_id):
        try:
            if success:
                bot.edit_message_text(text=text,
                                      chat_id=chat_id,
                                      message_id=message.message_id,
                                      parse_mode="html",
                                      is_group=is_group)
            else:
                bot.edit_message_text(R.get_string_resource(
                    "transcription_failed", lang),
                                      chat_id=chat_id,
                                      message_id=message.message_id,
                                      parse_mode="html",
                                      is_group=is_group)
            retry = False
        except telegram.error.TimedOut as t:
            logger.error("Timeout error %s", traceback.format_exc())
            retry_num += 1
            if retry_num >= 3:
                retry = False

        except telegram.error.RetryAfter as r:
            logger.warning("Retrying after %d", r.retry_after)
            time.sleep(r.retry_after)

        except telegram.error.TelegramError as te:
            logger.error("Telegram error %s", traceback.format_exc())
            retry = False

        except Exception as e:
            logger.error("Exception %s", traceback.format_exc())
            retry = False

    TranscriberBot.get().del_thread(message_id)
def process_media_photo(bot, update, photo, chat):
    chat_id = get_chat_id(update)
    message_id = get_message_id(update)
    is_group = chat_id < 0

    message = None

    if chat["photos_enabled"] == 1:
        message = bot.send_message(chat_id=chat_id,
                                   text=R.get_string_resource(
                                       "photo_recognizing", chat["lang"]),
                                   reply_to_message_id=message_id,
                                   parse_mode="html",
                                   is_group=is_group).result()

    file_id = photo[-1].file_id
    file_path = os.path.join(
        config.get_config_prop("app")["media_path"], file_id)
    bot.get_file(file_id).download(file_path)

    def process(message):
        if chat["qr_enabled"] == 1:
            qr = phototools.read_qr(file_path, chat["lang"])
            if qr is not None:
                if is_group:
                    qr = R.get_string_resource("qr_result",
                                               chat["lang"]) + "\n" + qr

                if message is not None:
                    bot.edit_message_text(text=qr,
                                          chat_id=chat_id,
                                          message_id=message.message_id,
                                          parse_mode="html",
                                          is_group=is_group)
                    return
                else:
                    message = bot.send_message(chat_id=chat_id,
                                               text=qr,
                                               reply_to_message_id=message_id,
                                               parse_mode="html",
                                               is_group=is_group).result()

        if chat["photos_enabled"] == 1:
            text = phototools.image_ocr(file_path, chat["lang"])
            if text is not None:
                if is_group:
                    text = R.get_string_resource("ocr_result",
                                                 chat["lang"]) + "\n" + text
                bot.edit_message_text(text=text,
                                      chat_id=chat_id,
                                      message_id=message.message_id,
                                      parse_mode="html",
                                      is_group=is_group)
                return

            bot.edit_message_text(text=R.get_string_resource(
                "photo_no_text", chat["lang"]),
                                  chat_id=chat_id,
                                  message_id=message.message_id,
                                  parse_mode="html",
                                  is_group=is_group)

    retry = True
    retry_num = 0
    try:
        while retry:
            process(message)
            retry = False

    except telegram.error.TimedOut as t:
        logger.error("Timeout error %s", traceback.format_exc())
        retry_num += 1
        if retry_num >= 3:
            retry = False

    except telegram.error.RetryAfter as r:
        logger.warning("Retrying after %d", r.retry_after)
        time.sleep(r.retry_after)

    except telegram.error.TelegramError as te:
        logger.error("Telegram error %s", traceback.format_exc())
        retry = False

    except Exception as e:
        logger.error("Exception %s", traceback.format_exc())
        retry = False

    finally:
        os.remove(file_path)