Ejemplo n.º 1
0
def add_original_emojis(session, sticker, raw_emojis):
    """Add the original emojis to the sticker's tags and to the original_emoji relationship."""
    for raw_emoji in raw_emojis:
        emoji = Tag.get_or_create(session, raw_emoji, True, True)

        if emoji not in sticker.tags:
            sticker.tags.append(emoji)

        if emoji not in sticker.original_emojis:
            sticker.original_emojis.append(emoji)
Ejemplo n.º 2
0
def sticker_factory(session, file_id, tag_names=None, default_language=True):
    """Create a sticker and eventually add tags."""
    sticker = Sticker(file_id)
    if tag_names:
        for tag_name in tag_names:
            tag = Tag.get_or_create(session, tag_name, default_language, False)
            sticker.tags.append(tag)

    session.add(sticker)
    session.commit()
    return sticker
Ejemplo n.º 3
0
def sticker_factory(session, file_id, tag_names=None, international=False):
    """Create a sticker and eventually add tags."""
    sticker = Sticker(file_id, file_id + "unique")
    if tag_names:
        for tag_name in tag_names:
            tag = Tag.get_or_create(session, tag_name, international, False)
            sticker.tags.append(tag)

    session.add(sticker)
    session.commit()
    return sticker
Ejemplo n.º 4
0
 def add_emojis(self, session, emojis):
     """Add tags for every emoji in the incoming string."""
     from stickerfinder.models import Tag
     self.original_emojis = emojis
     for emoji in emojis:
         tag = Tag.get_or_create(session,
                                 emoji,
                                 emoji=True,
                                 is_default_language=True)
         if tag not in self.tags:
             self.tags.append(tag)
Ejemplo n.º 5
0
def test_original_emoji_stays_on_replace(session, user, sticker_set):
    """Original emojis will remain if tags are added in replace mode."""
    sticker = sticker_set.stickers[0]
    # Add an original emoji tag to the sticker
    tag = Tag('😲', False, True)
    sticker.tags.append(tag)
    sticker.original_emojis.append(tag)
    session.commit()

    # Now tag the sticker in replace mode
    tag_sticker(session, 'new-tag', sticker, user, replace=True)
    assert_sticker_contains_tags(sticker, ['new-tag', '😲'])
    assert len(sticker.tags) == 2
    assert sticker.original_emojis[0] in sticker.tags
Ejemplo n.º 6
0
def test_nsfw_search(session, strict_inline_search, user):
    """Test nsfw search for stickers."""
    context = Context('nsfw p**n roflcopter', '', user)

    sticker_set = strict_inline_search[0]
    sticker_set.nsfw = True

    # Add specific sticker to tag
    sticker = sticker_set.stickers[0]
    tag = Tag.get_or_create(session, 'p**n', True, False)
    sticker.tags.append(tag)
    session.commit()

    matching_stickers, fuzzy_matching_stickers, duration = get_matching_stickers(session, context)
    assert len(matching_stickers) == 1
    assert matching_stickers[0][0] == sticker.file_id
Ejemplo n.º 7
0
def undo_user_changes_revert(session, user):
    """Undo the revert of all changes of a user."""
    affected_stickers = session.query(Sticker) \
        .options(
            joinedload(Sticker.changes),
        ) \
        .join(Sticker.changes) \
        .join(Change.user) \
        .filter(User.id == user.id) \
        .filter(Change.reverted.is_(True)) \
        .all()

    for sticker in affected_stickers:
        updated_languages = set()
        # Changes are sorted by created_at desc
        # We want to revert all changes until the last valid change
        for change in sticker.changes:
            # No reverted change, this is a valid tag change.
            if change.reverted is False and change.user != user:
                continue

            # Only undo the newest reverted change per language
            if change.is_default_language not in updated_languages:
                new_tags = change.new_tags.split(',')
                tags = [
                    tag for tag in sticker.tags
                    if (tag.is_default_language != change.is_default_language
                        or tag.emoji)
                ]

                for new_tag in new_tags:
                    tag = Tag.get_or_create(session, new_tag, False,
                                            change.is_default_language)
                    if tag not in tags:
                        tags.append(tag)

                sticker.tags = tags
                updated_languages.add(change.is_default_language)

            change.reverted = False

    user.reverted = False

    session.add(user)
    session.commit()
Ejemplo n.º 8
0
def test_convert_tag_to_emoji(session, user, sticker_set):
    """Tags will be converted to emojis, if they appear in the original emojis."""
    sticker = sticker_set.stickers[0]
    # Add an original emoji tag to the sticker
    tag = Tag('😲', False, False)
    sticker.tags.append(tag)
    session.commit()

    assert not tag.emoji
    assert not tag.international

    # Now tag the sticker in replace mode
    add_original_emojis(session, sticker, '😲')
    session.commit()

    assert tag.emoji
    assert not tag.international
    assert len(sticker.tags) == 1
    assert sticker.original_emojis[0] in sticker.tags
Ejemplo n.º 9
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})
Ejemplo n.º 10
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
Ejemplo n.º 11
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},
        )