Ejemplo n.º 1
0
def prepare_for_tracknumber(update: Update, context: CallbackContext) -> None:
    if len(context.user_data) == 0:
        message_text = translate_key_to(lp.DEFAULT_MESSAGE, context.user_data['language'])
    else:
        context.user_data['tag_editor']['current_tag'] = 'tracknumber'
        message_text = translate_key_to(lp.ASK_FOR_TRACK_NUMBER, context.user_data['language'])

    update.message.reply_text(message_text)
Ejemplo n.º 2
0
def prepare_for_album_art(update: Update, context: CallbackContext) -> None:
    if len(context.user_data) == 0:
        message_text = translate_key_to(lp.DEFAULT_MESSAGE, context.user_data['language'])
    else:
        context.user_data['tag_editor']['current_tag'] = 'album_art'
        message_text = translate_key_to(lp.ASK_FOR_ALBUM_ART, context.user_data['language'])

    update.message.reply_text(message_text)
Ejemplo n.º 3
0
def finish_editing_tags(update: Update, context: CallbackContext) -> None:
    message = update.message
    user_data = context.user_data

    context.bot.send_chat_action(
        chat_id=update.message.chat_id,
        action=ChatAction.UPLOAD_AUDIO
    )

    music_path = user_data['music_path']
    new_art_path = user_data['new_art_path']
    music_tags = user_data['tag_editor']
    lang = user_data['language']

    start_over_button_keyboard = generate_start_over_keyboard(lang)

    try:
        save_tags_to_file(
            file=music_path,
            tags=music_tags,
            new_art_path=new_art_path
        )
    except (OSError, BaseException):
        message.reply_text(
            translate_key_to(lp.ERR_ON_UPDATING_TAGS, lang),
            reply_markup=start_over_button_keyboard
        )
        logger.error("Error on updating tags for file %s's file.", music_path, exc_info=True)
        return

    try:
        with open(music_path, 'rb') as music_file:
            context.bot.send_audio(
                audio=music_file,
                duration=user_data['music_duration'],
                chat_id=update.message.chat_id,
                caption=f"🆔 {BOT_USERNAME}",
                reply_markup=start_over_button_keyboard,
                reply_to_message_id=user_data['music_message_id']
            )
    except (TelegramError, BaseException) as error:
        message.reply_text(
            translate_key_to(lp.ERR_ON_UPLOADING, lang),
            reply_markup=start_over_button_keyboard
        )
        logger.exception("Telegram error: %s", error)

    reset_user_data_context(context)
Ejemplo n.º 4
0
def start_over(update: Update, context: CallbackContext) -> None:
    reset_user_data_context(context)

    update.message.reply_text(
        translate_key_to(lp.START_OVER_MESSAGE, context.user_data['language']),
        reply_to_message_id=update.effective_message.message_id,
        reply_markup=ReplyKeyboardRemove()
    )
Ejemplo n.º 5
0
def throw_not_implemented(update: Update, context: CallbackContext) -> None:
    lang = context.user_data['language']

    back_button_keyboard = generate_back_button_keyboard(lang)

    update.message.reply_text(
        translate_key_to(lp.ERR_NOT_IMPLEMENTED, lang),
        reply_markup=back_button_keyboard
    )
Ejemplo n.º 6
0
def set_language(update: Update, context: CallbackContext) -> None:
    lang = update.message.text.lower()
    user_data = context.user_data
    user_id = update.effective_user.id

    if "english" in lang:
        user_data['language'] = 'en'
    elif "فارسی" in lang:
        user_data['language'] = 'fa'

    update.message.reply_text(translate_key_to(lp.LANGUAGE_CHANGED, user_data['language']))
    update.message.reply_text(
        translate_key_to(lp.START_OVER_MESSAGE, user_data['language']),
        reply_markup=ReplyKeyboardRemove()
    )

    user = User.where('user_id', '=', user_id).first()
    user.language = user_data['language']
    user.push()
Ejemplo n.º 7
0
def handle_photo_message(update: Update, context: CallbackContext) -> None:
    user_data = context.user_data
    message = update.message
    user_id = update.effective_user.id
    music_path = user_data['music_path']
    current_active_module = user_data['current_active_module']
    current_tag = user_data['tag_editor']['current_tag']
    lang = user_data['language']

    tag_editor_keyboard = generate_tag_editor_keyboard(lang)

    if music_path:
        if current_active_module == 'tag_editor':
            if not current_tag or current_tag != 'album_art':
                reply_message = translate_key_to(lp.ASK_WHICH_TAG, lang)
                message.reply_text(reply_message, reply_markup=tag_editor_keyboard)
            else:
                try:
                    file_download_path = download_file(
                        user_id=user_id,
                        file_to_download=message.photo[len(message.photo) - 1],
                        file_type='photo',
                        context=context
                    )
                    reply_message = f"{translate_key_to(lp.ALBUM_ART_CHANGED, lang)} " \
                                    f"{translate_key_to(lp.CLICK_PREVIEW_MESSAGE, lang)} " \
                                    f"{translate_key_to(lp.OR, lang).upper()} " \
                                    f"{translate_key_to(lp.CLICK_DONE_MESSAGE, lang).lower()}"
                    user_data['new_art_path'] = file_download_path
                    message.reply_text(reply_message, reply_markup=tag_editor_keyboard)
                except (ValueError, BaseException):
                    message.reply_text(translate_key_to(lp.ERR_ON_DOWNLOAD_AUDIO_MESSAGE, lang))
                    logger.error(
                        "Error on downloading %s's file. File type: Photo",
                        user_id,
                        exc_info=True
                    )
                    return
    else:
        reply_message = translate_key_to(lp.DEFAULT_MESSAGE, lang)
        message.reply_text(reply_message, reply_markup=ReplyKeyboardRemove())
Ejemplo n.º 8
0
def show_module_selector(update: Update, context: CallbackContext) -> None:
    user_data = context.user_data
    context.user_data['current_active_module'] = ''
    lang = user_data['language']

    module_selector_keyboard = generate_module_selector_keyboard(lang)

    update.message.reply_text(
        translate_key_to(lp.ASK_WHICH_MODULE, lang),
        reply_to_message_id=update.effective_message.message_id,
        reply_markup=module_selector_keyboard
    )
Ejemplo n.º 9
0
def handle_music_to_voice_converter(update: Update, context: CallbackContext) -> None:
    message = update.message
    context.bot.send_chat_action(
        chat_id=update.message.chat_id,
        action=ChatAction.RECORD_AUDIO
    )

    user_data = context.user_data
    input_music_path = user_data['music_path']
    voice_path = f"{user_data['music_path']}.ogg"
    lang = user_data['language']
    user_data['current_active_module'] = 'mp3_to_voice_converter'  # TODO: Make modules a dict

    os.system(
        f"ffmpeg -i -y {input_music_path} -ac 1 -map 0:a -codec:a opus -b:a 128k -vbr off \
         {input_music_path}"
    )
    os.system(f"ffmpeg -i {input_music_path} -c:a libvorbis -q:a 4 {voice_path}")

    start_over_button_keyboard = generate_start_over_keyboard(lang)

    context.bot.send_chat_action(
        chat_id=update.message.chat_id,
        action=ChatAction.UPLOAD_AUDIO
    )

    try:
        with open(voice_path, 'rb') as voice_file:
            context.bot.send_voice(
                voice=voice_file,
                duration=user_data['music_duration'],
                chat_id=message.chat_id,
                caption=f"🆔 {BOT_USERNAME}",
                reply_markup=start_over_button_keyboard,
                reply_to_message_id=user_data['music_message_id']
            )
    except TelegramError as error:
        message.reply_text(
            translate_key_to(lp.ERR_ON_UPLOADING, lang),
            reply_markup=start_over_button_keyboard
        )
        logger.exception("Telegram error: %s", error)

    delete_file(voice_path)

    reset_user_data_context(context)
Ejemplo n.º 10
0
def command_start(update: Update, context: CallbackContext) -> None:
    user_id = update.effective_user.id
    username = update.effective_user.username

    reset_user_data_context(context)

    user = User.where('user_id', '=', user_id).first()

    update.message.reply_text(
        translate_key_to(lp.START_MESSAGE, context.user_data['language']),
        reply_markup=ReplyKeyboardRemove()
    )

    show_language_keyboard(update, context)

    if not user:
        new_user = User()
        new_user.user_id = user_id
        new_user.username = username
        new_user.number_of_files_sent = 0

        new_user.save()

        logger.info("A user with id %s has been started to use the bot.", user_id)
Ejemplo n.º 11
0
def ignore_file(update: Update, context: CallbackContext) -> None:
    reset_user_data_context(context)
    update.message.reply_text(
        translate_key_to(lp.START_OVER_MESSAGE, context.user_data['language']),
        reply_markup=ReplyKeyboardRemove()
    )
Ejemplo n.º 12
0
def command_about(update: Update, context: CallbackContext) -> None:
    update.message.reply_text(translate_key_to(lp.ABOUT_MESSAGE, context.user_data['language']))
Ejemplo n.º 13
0
def handle_responses(update: Update, context: CallbackContext) -> None:
    message = update.message
    message_text = digits.ar_to_fa(digits.fa_to_en(message.text))
    user_data = context.user_data
    music_path = user_data['music_path']
    art_path = user_data['art_path']
    music_tags = user_data['tag_editor']
    current_tag = music_tags.get('current_tag')
    lang = user_data['language']

    logging.info(
        "%s:%s:%s",
        update.effective_user.id,
        update.effective_user.username,
        update.message.text
    )

    current_active_module = user_data['current_active_module']

    tag_editor_keyboard = generate_tag_editor_keyboard(lang)

    module_selector_keyboard = generate_module_selector_keyboard(lang)

    back_button_keyboard = generate_back_button_keyboard(lang)
    start_over_button_keyboard = generate_start_over_keyboard(lang)

    if current_active_module == 'tag_editor':
        if not current_tag:
            reply_message = translate_key_to(lp.ASK_WHICH_TAG, lang)
            message.reply_text(reply_message, reply_markup=tag_editor_keyboard)
        elif current_tag == 'album_art':
            reply_message = translate_key_to(lp.ASK_FOR_ALBUM_ART, lang)
            message.reply_text(reply_message, reply_markup=tag_editor_keyboard)
        else:
            save_text_into_tag(
                value=message_text,
                current_tag=current_tag,
                context=context,
                is_number=current_tag in ('year', 'disknumber', 'tracknumber')
            )
            reply_message = f"{translate_key_to(lp.DONE, lang)} " \
                            f"{translate_key_to(lp.CLICK_PREVIEW_MESSAGE, lang)} " \
                            f"{translate_key_to(lp.OR, lang).upper()}" \
                            f" {translate_key_to(lp.CLICK_DONE_MESSAGE, lang).lower()}"
            message.reply_text(reply_message, reply_markup=tag_editor_keyboard)
    elif current_active_module == 'music_cutter':
        try:
            beginning_sec, ending_sec = parse_cutting_range(message_text)
        except (ValueError, BaseException):
            reply_message = translate_key_to(lp.ERR_MALFORMED_RANGE, lang).format(
                translate_key_to(lp.MUSIC_CUTTER_HELP, lang),
            )
            message.reply_text(reply_message, reply_markup=back_button_keyboard)
            return
        music_path_cut = f"{music_path}_cut.mp3"
        music_duration = user_data['music_duration']

        if beginning_sec > music_duration or ending_sec > music_duration:
            reply_message = translate_key_to(lp.ERR_OUT_OF_RANGE, lang).format(
                convert_seconds_to_human_readable_form(music_duration))
            message.reply_text(reply_message)
            message.reply_text(
                translate_key_to(lp.MUSIC_CUTTER_HELP, lang),
                reply_markup=back_button_keyboard
            )
        elif beginning_sec >= ending_sec:
            reply_message = translate_key_to(lp.ERR_BEGINNING_POINT_IS_GREATER, lang)
            message.reply_text(reply_message)
            message.reply_text(
                translate_key_to(lp.MUSIC_CUTTER_HELP, lang),
                reply_markup=back_button_keyboard
            )
        else:
            diff_sec = ending_sec - beginning_sec

            os.system(
                f"ffmpeg -y -ss {beginning_sec} -t {diff_sec} -i {music_path} -acodec copy \
                {music_path_cut}"
            )

            try:
                save_tags_to_file(
                    file=music_path_cut,
                    tags=music_tags,
                    new_art_path=art_path if art_path else ''
                )
            except (OSError, BaseException):
                update.message.reply_text(translate_key_to(lp.ERR_ON_UPDATING_TAGS, lang))
                logger.error(
                    "Error on updating tags for file %s's file.",
                    music_path_cut,
                    exc_info=True
                )

            try:
                with open(music_path_cut, 'rb') as music_file:
                    # FIXME: After sending the file, the album art can't be read back
                    context.bot.send_audio(
                        audio=music_file,
                        chat_id=update.message.chat_id,
                        duration=diff_sec,
                        caption=f"*From*: {convert_seconds_to_human_readable_form(beginning_sec)}\n"
                                f"*To*: {convert_seconds_to_human_readable_form(ending_sec)}\n\n"
                                f"🆔 {BOT_USERNAME}",
                        reply_markup=start_over_button_keyboard,
                        reply_to_message_id=user_data['music_message_id']
                    )
            except (TelegramError, BaseException) as error:
                message.reply_text(
                    translate_key_to(lp.ERR_ON_UPLOADING, lang),
                    reply_markup=start_over_button_keyboard
                )
                logger.exception("Telegram error: %s", error)

            delete_file(music_path_cut)

            reset_user_data_context(context)
    else:
        if music_path:
            if user_data['current_active_module']:
                message.reply_text(
                    translate_key_to(lp.ASK_WHICH_MODULE, lang),
                    reply_markup=module_selector_keyboard
                )
        elif not music_path:
            message.reply_text(translate_key_to(lp.START_OVER_MESSAGE, lang))
        else:
            # Not implemented
            reply_message = translate_key_to(lp.ERR_NOT_IMPLEMENTED, lang)
            message.reply_text(reply_message)
Ejemplo n.º 14
0
def handle_music_message(update: Update, context: CallbackContext) -> None:
    message = update.message
    user_id = update.effective_user.id
    user_data = context.user_data
    music_duration = message.audio.duration
    music_file_size = message.audio.file_size
    old_music_path = user_data['music_path']
    old_art_path = user_data['art_path']
    old_new_art_path = user_data['new_art_path']
    language = user_data['language']

    if music_duration >= 3600 and music_file_size > 48000000:
        message.reply_text(
            translate_key_to(lp.ERR_TOO_LARGE_FILE, language),
            reply_markup=generate_start_over_keyboard(language)
        )
        return

    context.bot.send_chat_action(
        chat_id=message.chat_id,
        action=ChatAction.TYPING
    )

    try:
        create_user_directory(user_id)
    except OSError:
        message.reply_text(translate_key_to(lp.ERR_CREATING_USER_FOLDER, language))
        logger.error("Couldn't create directory for user %s", user_id, exc_info=True)
        return

    try:
        file_download_path = download_file(
            user_id=user_id,
            file_to_download=message.audio,
            file_type='audio',
            context=context
        )
    except ValueError:
        message.reply_text(
            translate_key_to(lp.ERR_ON_DOWNLOAD_AUDIO_MESSAGE, language),
            reply_markup=generate_start_over_keyboard(language)
        )
        logger.error("Error on downloading %s's file. File type: Audio", user_id, exc_info=True)
        return

    try:
        music = music_tag.load_file(file_download_path)
    except (OSError, NotImplementedError):
        message.reply_text(
            translate_key_to(lp.ERR_ON_READING_TAGS, language),
            reply_markup=generate_start_over_keyboard(language)
        )
        logger.error(
            "Error on reading the tags %s's file. File path: %s",
            user_id,
            file_download_path,
            exc_info=True
        )
        return

    reset_user_data_context(context)

    user_data['music_path'] = file_download_path
    user_data['art_path'] = ''
    user_data['music_message_id'] = message.message_id
    user_data['music_duration'] = message.audio.duration

    tag_editor_context = user_data['tag_editor']

    artist = music['artist']
    title = music['title']
    album = music['album']
    genre = music['genre']
    art = music['artwork']
    year = music.raw['year']
    disknumber = music.raw['disknumber']
    tracknumber = music.raw['tracknumber']

    if art:
        art_path = user_data['art_path'] = f"{file_download_path}.jpg"
        with open(art_path, 'wb') as art_file:
            art_file.write(art.first.data)

    tag_editor_context['artist'] = str(artist)
    tag_editor_context['title'] = str(title)
    tag_editor_context['album'] = str(album)
    tag_editor_context['genre'] = str(genre)
    tag_editor_context['year'] = str(year)
    tag_editor_context['disknumber'] = str(disknumber)
    tag_editor_context['tracknumber'] = str(tracknumber)

    show_module_selector(update, context)

    increment_usage_counter_for_user(user_id=user_id)

    user = User.where('user_id', '=', user_id).first()
    user.username = update.effective_user.username
    user.push()

    delete_file(old_music_path)
    delete_file(old_art_path)
    delete_file(old_new_art_path)