def get_matching_sticker_sets(session, user, query, tags, nsfw, furry, offset): """Get all matching stickers as well as the query duration for given criteria and offset.""" # Measure the db query time start = datetime.now() is_default_language = user.is_default_language # Get strict matching stickers matching_stickers = get_strict_matching_sticker_sets( session, tags, nsfw, furry, offset, is_default_language) end = datetime.now() # If we take more than 10 seconds, the answer will be invalid. # We need to know about this, before it happens. duration = end - start if duration.seconds >= 9: sentry.captureMessage(f'Query took too long.', level='info', extra={ 'query': query, 'duration': duration, 'results': len(matching_stickers), }) return matching_stickers, duration
def get_matching_sticker_sets(session, context): """Get all matching stickers and the query duration.""" # Measure the db query time start = datetime.now() # Get strict matching stickers matching_stickers = get_strict_matching_sticker_sets(session, context) end = datetime.now() # If we take more than 10 seconds, the answer will be invalid. # We need to know about this, before it happens. duration = end - start if duration.seconds >= 9: sentry.captureMessage( f"Query took too long.", level="info", extra={ "query": context.query, "duration": duration, "results": len(matching_stickers), }, ) return matching_stickers, duration
def get_matching_stickers(session, context): """Get all matching stickers and the query duration.""" # Measure the db query time start = datetime.now() # Get exactly matching stickers and fuzzy matching stickers matching_stickers = [] fuzzy_matching_stickers = [] if context.mode == Context.FAVORITE_MODE: matching_stickers = get_favorite_stickers(session, context) else: if context.fuzzy_offset is None: matching_stickers = get_strict_matching_stickers(session, context) # Get the fuzzy matching sticker, if there are no more strictly matching stickers # We also know that we should be using fuzzy search, if the fuzzy offset is defined in the context if context.fuzzy_offset is not None or len(matching_stickers) < 50: # We couldn't find enough strict matching stickers. Get the rest from fuzzy search. # Set the switched_to_fuzzy flag in the context object to signal, that it's ok to have less # than 50 results in the next_offset creation if len(matching_stickers) < 50 and context.fuzzy_offset is None: context.switch_to_fuzzy(50 - len(matching_stickers)) # We have no strict search results in the first search iteration. # Directly jump to fuzzy search fuzzy_matching_stickers = get_fuzzy_matching_stickers( session, context) end = datetime.now() # If we take more than 10 seconds, the answer will be invalid. # We need to know about this, before it happens. duration = end - start if duration.seconds >= 9: sentry.captureMessage( f"Query took too long.", level="info", extra={ "query": context.query, "duration": duration, "results": len(matching_stickers), }, ) return matching_stickers, fuzzy_matching_stickers, duration
def get_matching_stickers(session, user, query, tags, nsfw, furry, offset, fuzzy_offset): """Get all matching stickers and query duration for given criteria and offset.""" # Measure the db query time start = datetime.now() is_default_language = user.is_default_language # Get exactly matching stickers and fuzzy matching stickers matching_stickers = [] fuzzy_matching_stickers = [] if fuzzy_offset is None: matching_stickers = get_strict_matching_stickers( session, tags, nsfw, furry, offset, is_default_language) # Get the fuzzy matching sticker, if there are no more strictly matching stickers # We know that we should be using fuzzy search, if the fuzzy offset is defined in the offset_incoming payload if fuzzy_offset is not None or len(matching_stickers) == 0: # We have no strict search results in the first search iteration. # Directly jump to fuzzy search if fuzzy_offset is None: fuzzy_offset = 0 fuzzy_matching_stickers = get_fuzzy_matching_stickers( session, tags, nsfw, furry, fuzzy_offset, is_default_language) end = datetime.now() # If we take more than 10 seconds, the answer will be invalid. # We need to know about this, before it happens. duration = end - start if duration.seconds >= 9: sentry.captureMessage(f'Query took too long.', level='info', extra={ 'query': query, 'duration': duration, 'results': len(matching_stickers), }) return matching_stickers, fuzzy_matching_stickers, duration
def tag_sticker(session, text, sticker, user, tg_chat=None, chat=None, message_id=None, replace=False, single_sticker=False): """Tag a single sticker.""" text = text.lower() # Remove the /tag command if text.startswith('/tag'): text = text.split(' ')[1:] # Extract all texts from message and clean/filter them raw_tags = get_tags_from_text(text) # No tags, early return if len(raw_tags) == 0: return # Only use the first few tags. This should prevent abuse from tag spammers. raw_tags = raw_tags[:10] # Inform us if the user managed to hit a special count of changes if tg_chat and len(user.changes) in reward_messages: reward = reward_messages[len(user.changes)] call_tg_func(tg_chat, 'send_message', [reward]) sentry.captureMessage( f'User hit {len(user.changes)} changes!', level='info', extra={ 'user': user, 'changes': len(user.changes), }, ) # List of tags that are newly added to this sticker new_tags = [] # List of all new tags (raw_tags, but with resolved entities) # We need this, if we want to replace all tags incoming_tags = [] # Initialize the new tags array with the tags don't have the current language setting. for raw_tag in raw_tags: incoming_tag = Tag.get_or_create(session, raw_tag, user.is_default_language, False) incoming_tags.append(incoming_tag) # Add the tag to the list of new tags, if it doesn't exist on this sticker yet if incoming_tag not in sticker.tags: new_tags.append(incoming_tag) # We got no new tags if len(new_tags) == 0: session.commit() return # List of removed tags. This is only used, if we actually replace the sticker's tags removed_tags = [] # Remove replace old tags if replace: # Merge the original emojis, since they should always be present on a sticker incoming_tags = incoming_tags + sticker.original_emojis # Find out, which stickers have been removed removed_tags = [ tag for tag in sticker.tags if tag not in incoming_tags ] sticker.tags = incoming_tags else: for new_tag in new_tags: sticker.tags.append(new_tag) # Create a change for logging change = Change(user, sticker, user.is_default_language, new_tags, removed_tags, chat=chat, message_id=message_id) session.add(change) session.commit() # Change the inline keyboard to allow fast fixing of the sticker's tags if tg_chat and chat and not single_sticker and chat.last_sticker_message_id: keyboard = get_fix_sticker_tags_keyboard(chat.current_sticker.file_id) call_tg_func(tg_chat.bot, 'edit_message_reply_markup', [tg_chat.id, chat.last_sticker_message_id], {'reply_markup': keyboard})
def tag_sticker(session, text, sticker, user, tg_chat, chat=None, keep_old=False): """Tag a single sticker.""" text = text.lower() # Remove the /tag command if text.startswith('/tag'): text = text.split(' ')[1:] call_tg_func(tg_chat, 'send_message', ["You don't need to add the /tag command ;)"]) incoming_tags = get_tags_from_text(text) is_default_language = user.is_default_language and sticker.sticker_set.is_default_language # Only use the first few tags. This should prevent abuse from tag spammers. incoming_tags = incoming_tags[:15] # Clean the tags from unwanted words incoming_tags = [tag for tag in incoming_tags if tag not in blacklist] if len(user.changes) in reward_messages: reward = reward_messages[len(user.changes)] call_tg_func(tg_chat, 'send_message', [reward]) sentry.captureMessage( f'User hit {len(user.changes)} changes!', level='info', extra={ 'user': user, 'changes': len(user.changes), }, ) if len(incoming_tags) > 0: # Initialize the new tags array with the tags don't have the current language setting. tags = [ tag for tag in sticker.tags if tag.is_default_language is not is_default_language ] for incoming_tag in incoming_tags: tag = session.query(Tag).get(incoming_tag) if tag is None: tag = Tag(incoming_tag, False, is_default_language) if tag not in tags: tags.append(tag) session.add(tag) # Keep old sticker tags if they are emojis and not in the new tags set for tag in sticker.tags: if tag.name in sticker.original_emojis and tag not in tags: tags.append(tag) # Get the old tags for tracking old_tags_as_text = sticker.tags_as_text(is_default_language) if keep_old: for tag in tags: if tag not in sticker.tags: sticker.tags.append(tag) else: # Remove replace old tags sticker.tags = tags # Create a change for logging if old_tags_as_text != sticker.tags_as_text(is_default_language): change = Change(user, sticker, old_tags_as_text, is_default_language) session.add(change) session.commit() if chat and chat.last_sticker_message_id: # Change the inline keyboard to allow fast fixing of the sticker's tags keyboard = get_fix_sticker_tags_keyboard(chat.current_sticker.file_id) call_tg_func(tg_chat.bot, 'edit_message_reply_markup', [tg_chat.id, chat.last_sticker_message_id], {'reply_markup': keyboard}) # Reset last sticker message id chat.last_sticker_message_id = None
def tag_sticker( session, text, sticker, user, tg_chat=None, chat=None, message_id=None, replace=False, single_sticker=False, ): """Tag a single sticker.""" # Extract all texts from message and clean/filter them raw_tags = get_tags_from_text(text) # No tags, early return if len(raw_tags) == 0: return # Only use the first few tags. This should prevent abuse from tag spammers. if len(raw_tags) > 10: raw_tags = raw_tags[:10] call_tg_func( tg_chat, "send_message", [ "Please don't send that many tags. Try to describe everything as brief as possible." ], ) # Inform us if the user managed to hit a special count of changes if tg_chat and len(user.changes) in reward_messages: reward = reward_messages[len(user.changes)] call_tg_func(tg_chat, "send_message", [reward]) sentry.captureMessage( f"User hit {len(user.changes)} changes!", level="info", extra={ "user": user.username, "user_id": user.id, "changes": len(user.changes), }, ) # List of tags that are newly added to this sticker new_tags = [] # List of all new tags (raw_tags, but with resolved entities) # We need this, if we want to replace all tags incoming_tags = [] international = user.international or sticker.sticker_set.international # Initialize the new tags array with the tags don't have the current language setting. for raw_tag in raw_tags: incoming_tag = Tag.get_or_create(session, raw_tag, international, False) incoming_tags.append(incoming_tag) # Add the tag to the list of new tags, if it doesn't exist on this sticker yet if incoming_tag not in sticker.tags: new_tags.append(incoming_tag) # We got no new tags if len(new_tags) == 0 and replace is False: session.commit() return # List of removed tags. This is only used, if we actually replace the sticker's tags removed_tags = [] # Remove replace old tags if replace: # Merge the original emojis, since they should always be present on a sticker incoming_tags = incoming_tags + sticker.original_emojis # Find out, which stickers have been removed removed_tags = [ tag for tag in sticker.tags if tag not in incoming_tags ] sticker.tags = incoming_tags else: for new_tag in new_tags: sticker.tags.append(new_tag) # Create a change for logging change = Change( user, sticker, international, new_tags, removed_tags, chat=chat, message_id=message_id, ) session.add(change) session.commit() # Change the inline keyboard to allow fast fixing of the sticker's tags if tg_chat and chat and not single_sticker and chat.last_sticker_message_id: keyboard = get_fix_sticker_tags_keyboard(chat.current_sticker.file_id) call_tg_func( tg_chat.bot, "edit_message_reply_markup", [tg_chat.id, chat.last_sticker_message_id], {"reply_markup": keyboard}, )