Ejemplo n.º 1
0
def start(bot, update, session, chat, user):
    """Send the start text."""
    if chat.is_maintenance or chat.is_newsfeed:
        call_tg_func(update.message.chat, 'send_message', ['Hello there'],
                     {'reply_markup': get_main_keyboard(admin=True)})
    else:
        call_tg_func(update.message.chat, 'send_message', [start_text],
                     {'reply_markup': get_main_keyboard(user), 'parse_mode': 'Markdown'})
Ejemplo n.º 2
0
def cancel(bot, update, session, chat, user):
    """Send a help text."""
    if not send_tagged_count_message(session, bot, user, chat):
        keyboard = get_main_keyboard(
            admin=True) if chat.is_maintenance else get_main_keyboard(user)
        call_tg_func(update.message.chat, 'send_message',
                     ['All running commands are canceled'],
                     {'reply_markup': keyboard})

    chat.cancel(bot)
Ejemplo n.º 3
0
def handle_next(session, bot, chat, tg_chat, user):
    """Handle the /next call or the 'next' button click."""
    # We are tagging a whole sticker set. Skip the current sticker
    if chat.tag_mode == TagMode.STICKER_SET:
        # Check there is a next sticker
        stickers = chat.current_sticker.sticker_set.stickers
        for index, sticker in enumerate(stickers):
            if sticker == chat.current_sticker and index + 1 < len(stickers):
                # We found the next sticker. Send the messages and return
                chat.current_sticker = stickers[index + 1]
                send_tag_messages(chat, tg_chat, user)

                return

        # There are no stickers left, reset the chat and send success message.
        chat.current_sticker.sticker_set.completely_tagged = True
        call_tg_func(tg_chat, 'send_message',
                     ['The full sticker set is now tagged.'],
                     {'reply_markup': get_main_keyboard(user)})
        send_tagged_count_message(session, bot, user, chat)
        chat.cancel(bot)

    # Find a random sticker with no changes
    elif chat.tag_mode == TagMode.RANDOM:
        base_query = session.query(Sticker) \
            .outerjoin(Sticker.changes) \
            .join(Sticker.sticker_set) \
            .filter(Change.id.is_(None)) \
            .filter(StickerSet.is_default_language.is_(True)) \
            .filter(StickerSet.banned.is_(False)) \
            .filter(StickerSet.nsfw.is_(False)) \
            .filter(StickerSet.furry.is_(False)) \

        # Let the users tag the deluxe sticker set first.
        # If there are no more deluxe sets, just tag another random sticker.
        sticker = base_query.filter(StickerSet.deluxe.is_(True)) \
            .order_by(func.random()) \
            .limit(1) \
            .one_or_none()
        if sticker is None:
            sticker = base_query \
                .order_by(func.random()) \
                .limit(1) \
                .one_or_none()

        # No stickers for tagging left :)
        if not sticker:
            call_tg_func(tg_chat, 'send_message',
                         ['It looks like all stickers are already tagged :).'],
                         {'reply_markup': get_main_keyboard(user)})
            chat.cancel(bot)

        # Found a sticker. Send the messages
        chat.current_sticker = sticker
        send_tag_messages(chat, tg_chat, user, send_set_info=True)
Ejemplo n.º 4
0
def cleanup(bot, update, session, chat, user):
    """Triggering a one time conversion from text changes to tags."""
    threshold = datetime.strptime('Jan 1 2000', '%b %d %Y')
    full_cleanup(session, threshold, update=update)

    call_tg_func(update.message.chat, 'send_message', ['Cleanup finished.'],
                 {'reply_markup': get_main_keyboard(admin=True)})
Ejemplo n.º 5
0
def set_is_default_language(bot, update, session, chat, user):
    """Change the language of the user to the default langage."""
    user.is_default_language = True

    keyboard = get_main_keyboard(user)
    text = "Your tags will now be marked as english and you won't see any sticker sets with non-english content."
    call_tg_func(update.message.chat, 'send_message', [text], {'reply_markup': keyboard})
Ejemplo n.º 6
0
def handle_check_user(session, bot, context):
    """Handle all actions from the check_user task."""
    task = session.query(Task).get(context.payload)
    # Ban the user
    if CallbackResult(context.action).name == 'ban':
        task.user.banned = True
        call_tg_func(context.query, 'answer', ['User banned'])
    elif CallbackResult(context.action).name == 'unban':
        task.user.banned = False
        call_tg_func(context.query, 'answer', ['User ban reverted'])
        message = f'Your ban has been lifted.'
        call_tg_func(bot, 'send_message', [task.user.id, message], {'reply_markup': get_main_keyboard(task.user)})

    # Revert user changes
    elif CallbackResult(context.action).name == 'revert':
        task.reverted = True
        revert_user_changes(session, task.user)
        call_tg_func(context.query, 'answer', ['All user changes reverted'])
    elif CallbackResult(context.action).name == 'undo_revert':
        task.reverted = False
        undo_user_changes_revert(session, task.user)
        call_tg_func(context.query, 'answer', ['User changes revert undone'])

    # Change the language of all changes of this task.
    elif CallbackResult(context.action).name == 'change_language':
        change_language_of_task_changes(session, task)
        call_tg_func(context.query, 'answer', ['Language changed'])

    elif CallbackResult(context.action).name == 'ok':
        if not task.reviewed:
            task.reviewed = True
            check_maintenance_chat(session, context.tg_chat, context.chat)

    keyboard = check_user_tags_keyboard(task)
    call_tg_func(context.query.message, 'edit_reply_markup', [], {'reply_markup': keyboard})
Ejemplo n.º 7
0
def undeluxe_user(bot, update, session, chat, user):
    """Change the language of the user to the non default langage."""
    if not user.deluxe:
        return "You're already opt out of deluxe sticker packs."

    user.deluxe = False
    call_tg_func(update.message.chat, 'send_message',
                 ["You will now see all sticker sets again."],
                 {'reply_markup': get_main_keyboard(user)})
Ejemplo n.º 8
0
def deluxe_user(bot, update, session, chat, user):
    """Limit the result set of a user's search to deluxe stickers."""
    if user.deluxe:
        return "You're already opt in for deluxe sticker packs."

    user.deluxe = True
    call_tg_func(update.message.chat, 'send_message',
                 ["You will now only see deluxe sticker sets."],
                 {'reply_markup': get_main_keyboard(user)})
Ejemplo n.º 9
0
def send_tagged_count_message(session, bot, user, chat):
    """Send a user a message that displays how many stickers he already tagged."""
    if chat.tag_mode in [TagMode.STICKER_SET, TagMode.RANDOM]:
        count = session.query(Sticker) \
            .join(Sticker.changes) \
            .filter(Change.user == user) \
            .count()

        call_tg_func(
            bot, 'send_message',
            [user.id, f'You already tagged {count} stickers. Thanks!'],
            {'reply_markup': get_main_keyboard(user)})
Ejemplo n.º 10
0
def handle_cancel_tagging(session, bot, context):
    """Cancel tagging for now."""
    # Send a message to the user, which shows how many stickers he already tagged,
    # if the user was just tagging some stickers.
    # Otherwise just send the normal cancel success message.
    if not send_tagged_count_message(session, bot, context.user, context.chat):
        call_tg_func(context.query, 'answer',
                     ['All active commands have been canceled'])

    call_tg_func(context.tg_chat, 'send_message',
                 ['All running commands are canceled'],
                 {'reply_markup': get_main_keyboard(context.user)})

    context.chat.cancel(bot)
Ejemplo n.º 11
0
def start_tasks(bot, update, session, chat, user):
    """Start the handling of tasks."""
    if not chat.is_maintenance and not chat.is_newsfeed:
        call_tg_func(update.message.chat, 'send_message',
                     ['The chat is neither a maintenance nor a newsfeed chat'],
                     {'reply_markup': get_main_keyboard(admin=True)})
        return

    elif chat.current_task:
        return 'There already is a task active for this chat.'

    if chat.is_maintenance:
        check_maintenance_chat(session, update.message.chat, chat)

    if chat.is_newsfeed:
        check_newsfeed_chat(bot, session, chat)
Ejemplo n.º 12
0
def refresh_ocr(bot, update, session, chat, user):
    """Refresh all stickers and rescan for text."""
    sticker_sets = session.query(StickerSet).all()
    call_tg_func(update.message.chat,
                 'send_message',
                 args=[f'Found {len(sticker_sets)} sticker sets.'])

    count = 0
    for sticker_set in sticker_sets:
        refresh_stickers(session, sticker_set, bot, refresh_ocr=True)
        count += 1
        if count % 200 == 0:
            progress = f'Updated {count} sets ({len(sticker_sets) - count} remaining).'
            call_tg_func(update.message.chat, 'send_message', args=[progress])

    call_tg_func(update.message.chat, 'send_message',
                 ['All sticker sets are refreshed.'],
                 {'reply_markup': get_main_keyboard(admin=True)})
Ejemplo n.º 13
0
def refresh_sticker_sets(bot, update, session, chat, user):
    """Refresh all stickers."""
    sticker_sets = session.query(StickerSet) \
        .filter(StickerSet.deleted.is_(False)) \
        .all()

    progress = f'Found {len(sticker_sets)} sets.'
    call_tg_func(update.message.chat, 'send_message', args=[progress])

    count = 0
    for sticker_set in sticker_sets:
        refresh_stickers(session, sticker_set, bot)
        count += 1
        if count % 500 == 0:
            progress = f'Updated {count} sets ({len(sticker_sets) - count} remaining).'
            call_tg_func(update.message.chat, 'send_message', args=[progress])

    call_tg_func(update.message.chat, 'send_message',
                 ['All sticker sets are refreshed.'],
                 {'reply_markup': get_main_keyboard(admin=True)})
Ejemplo n.º 14
0
def random_set(bot, update, session, chat, user):
    """Get random sticker_set."""
    sticker_count = func.count(Sticker.file_id).label("sticker_count")
    sticker_set = session.query(StickerSet)\
        .join(StickerSet.stickers) \
        .filter(StickerSet.is_default_language.is_(True)) \
        .filter(StickerSet.nsfw.is_(False)) \
        .filter(StickerSet.furry.is_(False)) \
        .filter(StickerSet.banned.is_(False)) \
        .group_by(StickerSet) \
        .having(sticker_count > 0) \
        .order_by(func.random()) \
        .limit(1) \
        .one_or_none()

    if sticker_set is not None:
        chat.current_sticker = sticker_set.stickers[0]
        call_tg_func(update.message.chat,
                     'send_sticker',
                     args=[sticker_set.stickers[0].file_id],
                     kwargs={'reply_markup': get_main_keyboard(user)})
Ejemplo n.º 15
0
def broadcast(bot, update, session, chat, user):
    """Broadcast a message to all users."""
    message = update.message.text.split(' ', 1)[1].strip()

    chats = session.query(Chat) \
        .filter(Chat.type == 'private') \
        .all()

    call_tg_func(update.message.chat,
                 'send_message',
                 args=[f'Sending broadcast to {len(chats)} chats.'])
    deleted = 0
    for chat in chats:
        try:
            call_tg_func(bot, 'send_message', [chat.id, message],
                         {'parse_mode': 'Markdown'})

        # The chat doesn't exist any longer, delete it
        except BadRequest as e:
            if e.message == 'Chat not found':  # noqa
                deleted += 1
                session.delete(chat)
                continue

        # We are not allowed to contact this user.
        except Unauthorized:
            deleted += 1
            session.delete(chat)
            continue

        # Sleep one second to not trigger flood prevention
        time.sleep(1)

    call_tg_func(update.message.chat, 'send_message',
                 [f'All messages sent. Deleted {deleted} chats.'],
                 {'reply_markup': get_main_keyboard(user)})
Ejemplo n.º 16
0
def check_maintenance_chat(session, tg_chat, chat, job=False):
    """Get the next task and send it to the maintenance channel."""
    task = session.query(Task) \
        .filter(Task.reviewed.is_(False)) \
        .filter(Task.type.in_([
            Task.CHECK_USER_TAGS,
            Task.REPORT,
        ])) \
        .order_by(Task.created_at.asc()) \
        .limit(1) \
        .one_or_none()

    if task is None:
        chat.current_task = None
        # Don't send messages if we are calling this from a job.
        if job:
            return

        call_tg_func(tg_chat, 'send_message',
                     ['There are no more tasks for processing.'],
                     {'reply_markup': get_main_keyboard(admin=True)})

        return

    chat.current_task = task

    if task.type == Task.CHECK_USER_TAGS:
        changes = task.changes_to_check

        # Compile task text
        text = [
            f'User {task.user.username} ({task.user.id}) tagged {len(changes)} sticker'
        ]
        text.append(f'Detected at {task.created_at}: \n')
        for change in changes:
            if len(change.added_tags) > 0:
                text.append(f'Added: {change.added_tags_as_text()}')
            if len(change.removed_tags) > 0:
                text.append(f'Removed: {change.removed_tags_as_text()}')

        keyboard = check_user_tags_keyboard(task)

    elif task.type == Task.REPORT:
        # Compile task text
        text = ['Ban sticker set? \n']
        for ban in task.sticker_set.reports:
            text.append(ban.reason)

        keyboard = get_report_keyboard(task)

        # Send first sticker of the set
        call_tg_func(tg_chat,
                     'send_sticker',
                     args=[task.sticker_set.stickers[0].file_id])

    text_chunks = split_text(text)
    while len(text_chunks) > 0:
        chunk = text_chunks.pop(0)
        # First chunks, just send the text
        if len(text_chunks) > 0:
            call_tg_func(tg_chat, 'send_message', args=[chunk])

        # Last chunk. Send the text and the inline keyboard
        else:
            call_tg_func(tg_chat,
                         'send_message',
                         args=[chunk],
                         kwargs={'reply_markup': keyboard})

    return True
Ejemplo n.º 17
0
def send_admin_help_text(bot, update, session, chat, user):
    """Send the admin help text."""
    call_tg_func(update.message.chat, 'send_message', [admin_help_text],
                 {'reply_markup': get_main_keyboard(user), 'parse_mode': 'Markdown'})
Ejemplo n.º 18
0
def stats(bot, update, session, chat, user):
    """Send a help text."""
    # Users
    one_month_old = datetime.now() - timedelta(days=30)
    month_user_count = session.query(User) \
        .join(User.inline_queries) \
        .filter(InlineQuery.created_at > one_month_old) \
        .group_by(User) \
        .count()

    one_week_old = datetime.now() - timedelta(days=7)
    week_user_count = session.query(User) \
        .join(User.inline_queries) \
        .filter(InlineQuery.created_at > one_week_old) \
        .group_by(User) \
        .count()
    total_user_count = session.query(User).join(
        User.inline_queries).group_by(User).count()

    # Tags and emojis
    total_tag_count = session.query(sticker_tag.c.sticker_file_id) \
        .join(Tag, sticker_tag.c.tag_name == Tag.name) \
        .filter(Tag.emoji.is_(False)) \
        .count()
    english_tag_count = session.query(Tag) \
        .filter(Tag.is_default_language.is_(True)) \
        .filter(Tag.emoji.is_(False)) \
        .count()
    international_tag_count = session.query(Tag) \
        .filter(Tag.is_default_language.is_(False)) \
        .filter(Tag.emoji.is_(False)) \
        .count()
    emoji_count = session.query(Tag).filter(Tag.emoji.is_(True)).count()

    # Stickers and sticker/text sticker/tag ratio
    sticker_count = session.query(Sticker).count()
    tagged_sticker_count = session.query(distinct(sticker_tag.c.sticker_file_id)) \
        .join(Tag, sticker_tag.c.tag_name == Tag.name) \
        .filter(Tag.emoji.is_(False)) \
        .count()

    text_sticker_count = session.query(Sticker) \
        .filter(Sticker.text.isnot(None)) \
        .count()

    # Sticker set stuff
    sticker_set_count = session.query(StickerSet).count()
    normal_set_count = session.query(StickerSet) \
        .filter(StickerSet.nsfw.is_(False)) \
        .filter(StickerSet.furry.is_(False)) \
        .filter(StickerSet.banned.is_(False)) \
        .filter(StickerSet.is_default_language.is_(True)) \
        .count()
    deluxe_set_count = session.query(StickerSet).filter(
        StickerSet.deluxe.is_(True)).count()
    nsfw_set_count = session.query(StickerSet).filter(
        StickerSet.nsfw.is_(True)).count()
    furry_set_count = session.query(StickerSet).filter(
        StickerSet.furry.is_(True)).count()
    banned_set_count = session.query(StickerSet).filter(
        StickerSet.banned.is_(True)).count()
    not_english_set_count = session.query(StickerSet).filter(
        StickerSet.is_default_language.is_(False)).count()

    # Inline queries
    total_queries_count = session.query(InlineQuery).count()
    last_day_queries_count = session.query(InlineQuery)\
        .filter(InlineQuery.created_at > datetime.now() - timedelta(days=1)) \
        .count()

    stats = f"""Users:
    => last week: {week_user_count}
    => last month: {month_user_count}
    => total: {total_user_count}

Tags:
    => total: {total_tag_count}
    => english: {english_tag_count}
    => international: {international_tag_count}
    => emojis: {emoji_count}

Stickers:
    => total: {sticker_count}
    => with tags: {tagged_sticker_count}
    => with text: {text_sticker_count}

Sticker sets:
    => total: {sticker_set_count}
    => normal: {normal_set_count}
    => deluxe: {deluxe_set_count}
    => nsfw: {nsfw_set_count}
    => furry: {furry_set_count}
    => banned: {banned_set_count}
    => international: {not_english_set_count}

Total queries : {total_queries_count}
    => last day: {last_day_queries_count}
"""
    call_tg_func(update.message.chat, 'send_message', [stats],
                 {'reply_markup': get_main_keyboard(admin=True)})