def language_handler(bot, update, language): chat_id = get_chat_id(update) lang = config.get_config_prop("app")["languages"][language] #ISO 639-1 code for language TBDB.set_chat_lang(chat_id, lang) message = R.get_string_resource("language_set", lang).replace("{lang}", language) reply = update.message or update.channel_post reply.reply_text(message)
def translate(bot, update): chat_id = get_chat_id(update) message = update.message or update.channel_post if not message: return lang = message.text lang = lang.replace("/translate", "").strip() logger.debug("Language %s", lang) if lang not in config.get_config_prop("app")["languages"]: bot.send_message(chat_id=chat_id, text=R.get_string_resource( "translate_language_not_found", TBDB.get_chat_lang(chat_id)).format(lang), is_group=chat_id < 0) return lang = config.get_config_prop("app")["languages"][lang].split('-')[0] if not message.reply_to_message: bot.send_message(chat_id=chat_id, text=R.get_string_resource( "translate_reply_to_message", TBDB.get_chat_lang(chat_id)), is_group=chat_id < 0) return translation = translator.translate(source=TBDB.get_chat_lang(chat_id), target=lang, text=message.reply_to_message.text) message.reply_text(translation)
def enable_qr(bot, update): chat_id = get_chat_id(update) TBDB.set_chat_qr_enabled(chat_id, 1) bot.send_message(chat_id=chat_id, text=R.get_string_resource("qr_enabled", TBDB.get_chat_lang(chat_id)), is_group=chat_id < 0)
def disable_photos(bot, update): chat_id = get_chat_id(update) TBDB.set_chat_photos_enabled(chat_id, 0) bot.send_message(chat_id=chat_id, text=R.get_string_resource("photos_disabled", TBDB.get_chat_lang(chat_id)), is_group=chat_id < 0)
def __pre__hook(self, fn, u, c, **kwargs): b = c.bot m = u.message or u.channel_post if not m: return age = (datetime.utcnow() - m.date.replace(tzinfo=None)).total_seconds() if age > config.get_config_prop("app")["antiflood"]["age_threshold"]: return chat_id = get_chat_id(u) antiflood.on_chat_msg_received(chat_id) if chat_id in self.floods and self.floods[chat_id] is True: return if not TBDB.get_chat_entry(chat_id): # happens when welcome/joined message is not received TBDB.create_default_chat_entry(chat_id, 'en-US') if chat_id in self.mqbot.active_chats_cache and self.mqbot.active_chats_cache[chat_id] == 0: logger.debug("Marking chat {} as active".format(chat_id)) self.mqbot.active_chats_cache[chat_id] = 1 TBDB.set_chat_active(chat_id, self.mqbot.active_chats_cache[chat_id]) return fn(b, u, **kwargs)
def welcome_message(bot, update): chat_id = get_chat_id(update) message_id = get_message_id(update) chat_record = TBDB.get_chat_entry(chat_id) language = None if chat_record is not None: language = chat_record["lang"] elif update.message is not None and update.message.from_user.language_code is not None: # Channel posts do not have a language_code attribute logger.debug("Language_code: %s", update.message.from_user.language_code) language = update.message.from_user.language_code message = R.get_string_resource("message_welcome", language) message = message.replace("{languages}", "/" + "\n/".join(get_language_list())) #Format them to be a list of commands bot.send_message( chat_id=chat_id, text=message, reply_to_message_id = message_id, parse_mode = "html", is_group = chat_id < 0 ) if chat_record is None: if language is None: language = "en-US" if len(language) < 5: language = R.iso639_2_to_639_1(language) logger.debug("No record found for chat {}, creating one with lang {}".format(chat_id, language)) TBDB.create_default_chat_entry(chat_id, language)
def left_chat_member(bot, update): chat_id = get_chat_id(update) message = update.message or update.channel_post if message.left_chat_member.id == bot.get_me().id: logger.info('Marking chat {} as inactive'.format(chat_id)) bot.active_chats_cache[chat_id] = 0 TBDB.set_chat_active(chat_id, bot.active_chats_cache[chat_id])
def users(bot, update): chat_id = get_chat_id(update) tot_chats = TBDB.get_chats_num() active_chats = TBDB.get_active_chats_num() bot.send_message(chat_id=chat_id, text='Total users: {}\nActive users: {}'.format( tot_chats, active_chats), parse_mode='html', is_group=chat_id < 0)
def donate(bot, update): chat_id = get_chat_id(update) bot.send_message(chat_id=chat_id, text=R.get_string_resource("message_donate", TBDB.get_chat_lang(chat_id)), parse_mode="html", is_group=chat_id < 0)
def __init__(self): self.error_handler = None self.message_handlers = {} self.command_handlers = {} self.callback_handlers = {} self.floods = {} self.workers = {} antiflood.register_flood_warning_callback( lambda chat_id: TranscriberBot.get().bot().send_message( chat_id=chat_id, text=R.get_string_resource("flood_warning", TBDB.get_chat_lang(chat_id)), parse_mode = "html", is_group = chat_id < 0 ) ) def flood_started(chat_id): logger.info("Flood detected in %d, ignoring messages", chat_id) self.floods[chat_id] = True def flood_ended(chat_id): logger.info("Flood ended for %d", chat_id) self.floods[chat_id] = False antiflood.register_flood_started_callback(flood_started) antiflood.register_flood_ended_callback(flood_ended)
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 privacy(bot, update): chat_id = get_chat_id(update) bot.send_message(chat_id=chat_id, text=R.get_string_resource("privacy_policy", TBDB.get_chat_lang(chat_id)), parse_mode='html', is_group=chat_id < 0)
def __init__(self, *args, is_queued_def=True, mqueue=None, **kwargs): super().__init__(*args, **kwargs) self._is_messages_queued_default = is_queued_def self._msg_queue = mqueue or mq.MessageQueue() chats = TBDB.get_chats() self.active_chats_cache = dict( zip([c['chat_id'] for c in chats], [c['active'] for c in chats]))
def active_check(self, fn, *args, **kwargs): err = None res = None try: res = fn(*args, **kwargs) except Unauthorized as e: pprint.pprint(e) logger.error(e) err = e if err is not None: chat_id = kwargs['chat_id'] if chat_id not in self.active_chats_cache or self.active_chats_cache[chat_id] == 1: logger.debug("Marking chat {} as inactive".format(chat_id)) self.active_chats_cache[chat_id] = 0 TBDB.set_chat_active(chat_id, self.active_chats_cache[chat_id]) raise err return res
def photo(bot, update): chat_id = get_chat_id(update) chat = TBDB.get_chat_entry(chat_id) if chat["qr_enabled"] == 0 and chat["photos_enabled"] == 0: return message = update.message or update.channel_post if message.photo: TranscriberBot.get().photos_thread_pool.submit(process_media_photo, bot, update, message.photo, chat)
def voice(bot, update): chat_id = get_chat_id(update) voice_enabled = TBDB.get_chat_voice_enabled(chat_id) if voice_enabled == 0: return message = update.message or update.channel_post v = message.voice if voice_enabled == 2: pass else: TranscriberBot.get().voice_thread_pool.submit(process_media_voice, bot, update, v, "voice")
def stop(bot, update): query = update.callback_query TranscriberBot.get().stop_thread(query.data) logger.debug("Stopping thread %s", query.data) logger.debug("Thread %s running: %r", query.data, TranscriberBot.get().thread_running(query.data)) string_stopped = R.get_string_resource( "transcription_stopped", TBDB.get_chat_lang(query.message.chat_id)) bot.edit_message_text(text=query.message.text + " " + string_stopped, chat_id=query.message.chat_id, message_id=query.message.message_id, parse_mode="html", is_group=query.message.chat_id < 0)
def __post(): chats = TBDB.get_chats() sent = 0 for chat in chats: try: bot.send_message(chat_id=chat['chat_id'], text=text, parse_mode='html', is_group=int(chat['chat_id']) < 0) sent += 1 time.sleep(0.1) except Exception as e: logger.error("Exception sending broadcast to %d: (%s) %s", chat['chat_id'], e, traceback.format_exc()) bot.send_message(chat_id=chat_id, text='Broadcast sent to {}/{} chats'.format( sent, len(chats)), is_group=chat_id < 0) TranscriberBot.get().command_handlers['users'](bot, update)
def document(bot, update): chat_id = get_chat_id(update) voice_enabled = TBDB.get_chat_voice_enabled(chat_id) m = update.message or update.channel_post file_name = m.document.file_name _, file_ext = os.path.splitext(file_name) if file_ext[1:] not in config.get_config_prop("app")["audio_ext"]: logger.info('extension %s not recognized', file_ext) return if voice_enabled == 0: return if voice_enabled == 2: pass else: TranscriberBot.get().voice_thread_pool.submit(process_media_voice, bot, update, m.document, 'audio_document')
def rate(bot, update): chat_id = get_chat_id(update) bot.send_message(chat_id=chat_id, text=R.get_string_resource("message_rate", TBDB.get_chat_lang(chat_id)), is_group=chat_id < 0)
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 private_message(bot, update): chat_id = get_chat_id(update) bot.send_message(chat_id=chat_id, text=R.get_string_resource("message_private", TBDB.get_chat_lang(chat_id)))
def lang(bot, update): chat_id = get_chat_id(update) bot.send_message(chat_id=chat_id, text=TBDB.get_chat_lang(chat_id))
def test_db(): id = 1234 TBDB.create_default_chat_entry(id, 'en-US') assert TBDB.get_chat_lang(id) == 'en-US' assert TBDB.get_chat_active(id) == 1 TBDB.set_chat_lang(id, 'lang') TBDB.set_chat_voice_enabled(id, 2) TBDB.set_chat_photos_enabled(id, 1) TBDB.set_chat_qr_enabled(id, 1) TBDB.set_chat_active(id, 0) TBDB.set_chat_ban(id, 1) assert TBDB.get_chat_lang(id) == 'lang' assert TBDB.get_chat_voice_enabled(id) == 2 assert TBDB.get_chat_photos_enabled(id) == 1 assert TBDB.get_chat_qr_enabled(id) == 1 assert TBDB.get_chat_active(id) == 0 assert TBDB.get_chat_ban(id) == 1