Esempio n. 1
0
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
Esempio n. 2
0
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
Esempio n. 3
0
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
Esempio n. 4
0
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
Esempio n. 5
0
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})
Esempio n. 6
0
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
Esempio n. 7
0
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},
        )