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
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'
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'
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)
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()
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'] = ''
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)))
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