Beispiel #1
0
def on_first_sticker_receive(bot, update, user_data):
    logger.info('%d: first sticker of the pack received',
                update.effective_user.id)

    title, name = user_data['pack'].get('title', None), user_data['pack'].get(
        'name', None)
    if not title or not name:
        logger.error('pack title or name missing (title: %s, name: %s)', title,
                     name)
        update.message.reply_text(
            s.PACK_CREATION_FIRST_STICKER_PACK_DATA_MISSING)

        user_data.pop('pack', None)  # remove temp info
        user_data['status'] = ''  # reset user status

        return

    full_name = name + '_by_' + bot.username

    sticker = StickerFile(update.message.sticker or update.message.document,
                          caption=update.message.caption)
    sticker.download(prepare_png=True)

    try:
        logger.debug('executing API request...')
        bot.create_new_sticker_set(user_id=update.effective_user.id,
                                   title=title,
                                   name=full_name,
                                   emojis=sticker.emoji,
                                   png_sticker=sticker.png_bytes_object)
    except (BadRequest, TelegramError) as e:
        logger.error('Telegram error while creating stickers pack: %s',
                     e.message)
        error_code = u.get_exception_code(e.message)

        if error_code == 10:  # there's already a pack with that link
            update.message.reply_html(
                s.PACK_CREATION_ERROR_DUPLICATE_NAME.format(
                    u.name2link(full_name)))
            user_data['pack'].pop('name', None)  # remove pack name
            user_data['status'] = 'waiting_pack_name'
        elif error_code == 13:
            update.message.reply_text(s.PACK_CREATION_ERROR_INVALID_NAME)
            user_data['pack'].pop('name', None)  # remove pack name
            user_data['status'] = 'waiting_pack_name'
        else:
            update.message.reply_html(
                s.PACK_CREATION_ERROR_GENERIC.format(e.message))

        return  # do not continue

    db.save_pack(update.effective_user.id, full_name, title)
    pack_link = u.name2link(full_name)
    update.message.reply_html(s.PACK_CREATION_PACK_CREATED.format(pack_link))

    sticker.delete()  # remove sticker files

    user_data['status'] = 'adding_stickers'  # wait for other stickers
    user_data['pack']['name'] = full_name
Beispiel #2
0
def on_pack_title(bot, update, user_data):
    logger.info('%d: user selected the pack title from the keyboard',
                update.effective_user.id)

    selected_title = update.message.text
    pack_info = db.get_packs_by_title(update.effective_user.id,
                                      selected_title,
                                      as_obj=True)

    if pack_info is None:
        logger.error('cannot find any pack with this title: %s',
                     selected_title)
        update.message.reply_text(
            s.ADD_STICKER_SELECTED_TITLE_DOESNT_EXIST.format(
                selected_title[:150]))
        # do not change the user status
        return

    if len(pack_info) > 1:
        logger.info('user has multiple packs with this title: %s',
                    selected_title)

        # build the keyboard with the pack links
        pack_names = [
            pack.name.replace('_by_' + bot.username, '') for pack in pack_info
        ]  # strip the '_by_bot' part
        markup = rm.get_markup_from_list(pack_names, add_back_button=True)

        # list with the links to the involved packs
        pack_links = [
            '<a href="{}">{}</a>'.format(
                u.name2link(pack.name),
                pack.name.replace('_by_' + bot.username, ''))
            for pack in pack_info
        ]
        text = s.ADD_STICKER_SELECTED_TITLE_MULTIPLE.format(
            selected_title, '\n• '.join(pack_links))
        update.message.reply_html(text, reply_markup=markup)

        user_data[
            'status'] = 'adding_waiting_pack_name'  # we now have to wait for the user to tap on a pack name

        return

    logger.info(
        'there is only one pack with the selected title, proceeding...')
    pack = pack_info[0]

    user_data['pack'] = dict(name=pack.name)
    pack_link = u.name2link(pack.name)
    update.message.reply_html(s.ADD_STICKER_PACK_SELECTED.format(pack_link),
                              reply_markup=rm.HIDE)

    user_data['status'] = 'adding_stickers'
Beispiel #3
0
def on_pack_name(bot, update, user_data):
    logger.info('%d: user selected the pack name from the keyboard', update.effective_user.id)

    if re.search(r'^GO BACK$', update.message.text, re.I):
        pack_titles = db.get_pack_titles(update.effective_user.id)
        markup = rm.get_markup_from_list(pack_titles)
        update.message.reply_text(s.ADD_STICKER_SELECT_PACK, reply_markup=markup)

        user_data['status'] = 'adding_waiting_pack_title'
        return

    selected_name = '{}_by_{}'.format(update.message.text, bot.username)  # the buttons list has the name without "_by_botusername"

    pack = db.get_pack_by_name(update.effective_user.id, selected_name, as_namedtuple=True)
    if not pack:
        logger.error('user %d does not have any pack with name %s', update.effective_user.id, selected_name)
        update.message.reply_text(s.ADD_STICKER_SELECTED_NAME_DOESNT_EXIST)
        # do not reset the user status
        return

    user_data['pack'] = dict(name=pack.name)
    pack_link = u.name2link(pack.name)
    update.message.reply_html(s.ADD_STICKER_PACK_SELECTED.format(pack_link), reply_markup=rm.HIDE)

    user_data['status'] = 'adding_stickers'
Beispiel #4
0
def on_sticker_receive(bot, update, user_data):
    logger.info('%d: user sent the stciker to add', update.effective_user.id)

    sticker = StickerFile(update.message.sticker)

    error = sticker.remove_from_set(bot)
    pack_link = u.name2link(update.message.sticker.set_name)
    if not error:
        update.message.reply_html(s.REMOVE_STICKER_SUCCESS.format(pack_link), quote=True)
    elif error == 11:
        update.message.reply_html(s.REMOVE_STICKER_FOREIGN_PACK.format(u.name2link(update.message.sticker.set_name)),
                                  quote=True)
    elif error == 12:
        update.message.reply_html(s.REMOVE_STICKER_ALREADY_DELETED.format(pack_link), quote=True)
    else:
        update.message.reply_html(s.REMOVE_STICKER_GENERIC_ERROR.format(pack_link, error), quote=True)
Beispiel #5
0
def on_sticker_receive(bot, update, user_data):
    logger.info('%d: user sent a sticker to add', update.effective_user.id)

    name = user_data['pack'].get('name', None)
    if not name:
        logger.error('pack name missing (%s)', name)
        update.message.reply_text(s.ADD_STICKER_PACK_DATA_MISSING)

        user_data.pop('pack', None)  # remove temp info
        user_data['status'] = ''  # reset user status

        return

    sticker = StickerFile(update.message.sticker or update.message.document,
                          caption=update.message.caption)
    sticker.download(prepare_png=True)

    error = sticker.add_to_set(bot, update.effective_user.id, name)
    pack_link = u.name2link(name)
    if not error:
        update.message.reply_html(s.ADD_STICKER_SUCCESS.format(pack_link),
                                  quote=True)
    elif error == 14:
        update.message.reply_html(s.ADD_STICKER_PACK_FULL.format(pack_link),
                                  quote=True)
    elif error == 17:
        logger.error('resized sticker has the wrong size: %s', str(sticker))
        update.message.reply_html(
            s.ADD_STICKER_SIZE_ERROR.format(*sticker.size), quote=True)
    elif error == 11:
        # pack name invalid or that pack has been deleted: delete it from the db
        deleted_rows = db.delete_pack(update.effective_user.id, name)
        logger.debug('rows deleted: %d', deleted_rows or 0)

        # get the remaining packs' titles
        pack_titles = db.get_pack_titles(update.effective_user.id)
        if not pack_titles:
            # user doesn't have any other pack to chose from, reset his status
            update.message.reply_html(
                s.ADD_STICKER_PACK_NOT_VALID_NO_PACKS.format(pack_link))
            user_data['status'] = ''
        else:
            # make the user select another pack from the keyboard
            markup = rm.get_markup_from_list(pack_titles)
            update.message.reply_html(
                s.ADD_STICKER_PACK_NOT_VALID.format(pack_link),
                reply_markup=markup)
            user_data.pop('pack', None)  # remove temporary data
            user_data['status'] = 'adding_waiting_pack_title'
    else:
        update.message.reply_html(s.ADD_STICKER_GENERIC_ERROR.format(
            pack_link, error),
                                  quote=True)

    sticker.delete()
Beispiel #6
0
def on_addpack_name_receive(bot, update, user_data):
    logger.info('%d: received possible addpack name', update.effective_user.id)

    addpack_name = update.message.text
    if "https://t.me/addstickers/" in addpack_name:
        addpack_name = addpack_name.split("https://t.me/addstickers/", 1)[1]
        if "_by_" + bot.username not in addpack_name:
            update.message.reply_text(s.PACK_NAME_NOT_OURS_ERROR)
            user_data['status'] = 'waiting_addpack_name'
            return
    elif addpack_name is not None:
        addpack_name = addpack_name + '_by_' + bot.username
    else:
        update.message.reply_text(s.PACK_NAME_NOT_OURS_ERROR)
        user_data['status'] = 'waiting_addpack_name'
        return

    if len(addpack_name) > 64:
        logger.info('Not a valid pack name too long: %s', addpack_name)
        update.message.reply_text(s.PACK_TITLE_TOO_LONG)
        # do not change the user status and let him send another title
        return

    if '\n' in addpack_name:
        logger.info('pack title contains newline character')
        update.message.reply_text(s.PACK_TITLE_CONTAINS_NEWLINES)
        # do not change the user status and let him send another title
        return

    logger.info('pack title is valid')
    # get sticker set
    try:
        addpack_name_stickerset = bot.getStickerSet(addpack_name)
    except (BadRequest, TelegramError) as e:
        logger.error('Telegram error while trying to get the sticker set: %s',
                     e.message)
        error_code = u.get_exception_code(e.message)

        if error_code == 13:
            update.message.reply_text(s.PACK_CREATION_ERROR_INVALID_NAME)
            user_data['status'] = 'waiting_addpack_name'
        else:
            update.message.reply_html(
                s.PACK_CREATION_ERROR_GENERIC.format(e.message))

        return  # do not continue

    db.save_pack(update.effective_user.id, addpack_name_stickerset.name,
                 addpack_name_stickerset.title)
    pack_link = u.name2link(addpack_name_stickerset.name)
    update.message.reply_html(s.PACK_ADDED.format(pack_link))

    user_data['status'] = ''
Beispiel #7
0
def on_list_command(bot, update):
    logger.info('%d: /list', update.effective_user.id)

    packs = db.get_user_packs(update.effective_user.id, as_namedtuple=True)
    if not packs:
        update.message.reply_text(s.LIST_NO_PACKS)
        return

    packs = packs[:100]  # can't include more than 100 entities
    strings_list = [
        '<a href="{}">{}</a>'.format(u.name2link(pack.name), pack.title)
        for pack in packs
    ]
    update.message.reply_html('• {}'.format('\n• '.join(strings_list)))
Beispiel #8
0
def on_sticker_receive(bot, update, user_data):
    logger.info('%d: user sent a stciker from the pack to export', update.effective_user.id)

    if not update.message.sticker.set_name:
        update.message.reply_text(s.EXPORT_PACK_NO_PACK)
        return

    sticker_set = bot.get_sticker_set(update.message.sticker.set_name)

    # use the message_id to make sure we will not end up with multiple dirs/files with the same name
    dir_name = '{}_{}/'.format(update.message.message_id, sticker_set.title)
    dir_path = 'tmp/{}'.format(dir_name)
    os.mkdir(dir_path)

    base_progress_message = s.EXPORT_PACK_START.format(html_escape(sticker_set.title))
    message_to_edit = update.message.reply_html(base_progress_message, quote=True)

    total = len(sticker_set.stickers)
    progress = 0
    for sticker in sticker_set.stickers:
        sticker_file = StickerFile(sticker)
        try:
            # try to download and convert to png
            sticker_file.download(update, prepare_png=True, subdir=dir_name)
            # delete only the .webp file
            sticker_file.delete(keep_result_png=True)
        except Exception as e:
            logger.info('error while downloading and converting a sticker we need to export: %s', str(e))
            # make sure we delete the downloaded .webp file
            sticker_file.delete(keep_result_png=True)
        progress += 1

        # edit message every 12 exported stickers, or when we're done
        if progress == total or progress % 12 == 0:
            try:
                message_to_edit.edit_text('{} (progress: {}/{})'.format(base_progress_message, progress, total),
                                          parse_mode=ParseMode.HTML)
            except (TelegramError, BadRequest) as e:
                logger.error('error while editing progress message: %s', e.message)

    message_to_edit.reply_text(s.EXPORT_PACK_UPLOADING, quote=True)

    logger.info('creating zip file...')
    zip_path = 'tmp/{}_{}'.format(update.message.message_id, sticker_set.name)
    make_archive(zip_path, 'zip', dir_path)
    zip_path += '.zip'

    logger.debug('sending zip file %s', zip_path)
    with open(zip_path, 'rb') as f:
        update.message.reply_document(f, caption='<a href="{}">{}</a>'.format(
            u.name2link(sticker_set.name),
            html_escape(sticker_set.title)
        ), parse_mode=ParseMode.HTML, quote=True)

    logger.info('cleaning up export files')
    try:
        os.remove(zip_path)  # remove the zip file
        rmtree(dir_path)  # remove the png dir
    except Exception as e:
        logger.error('error while cleaning up the export files: %s', str(e))

    user_data['status'] = ''  # reset the user status, do not implicitly wait for new packs to export