Example #1
0
def generate_pretty_roll(roll):

    pretty_roll = None

    victim = dao.get_bakchod_by_id(roll["victim"])

    try:

        if roll["winrar"] is None:

            pretty_roll = "Roll a {} to {} {}!".format(
                roll["roll_number"],
                pretty_roll_rule(roll["rule"]),
                util.extract_pretty_name_from_bakchod(victim),
            )

        else:

            winrar = dao.get_bakchod_by_id(roll["winrar"])

            try:
                roll_expiry = ciso8601.parse_datetime(roll["expiry"])
            except Exception as e:
                roll_expiry = roll["expiry"]

            now = datetime.datetime.now()
            td = roll_expiry - now

            if roll["rule"] == "kick_user":
                pretty_roll = "{} won by rolling a {}! {} has been kicked from this group!".format(
                    util.extract_pretty_name_from_bakchod(winrar),
                    roll["roll_number"],
                    util.extract_pretty_name_from_bakchod(victim),
                )
            else:
                pretty_roll = "{} won by rolling a {}! {} is now {} for {}".format(
                    util.extract_pretty_name_from_bakchod(winrar),
                    roll["roll_number"],
                    util.extract_pretty_name_from_bakchod(victim),
                    pretty_roll_rule(roll["rule"]),
                    util.pretty_time_delta(td.total_seconds()),
                )

    except Exception as e:
        logger.error(
            "Caught Error in roll.generate_pretty_roll - {} \n {}",
            e,
            traceback.format_exc(),
        )

    return pretty_roll
Example #2
0
def all(update, context):

    # Update Bakchod DB
    bakchod = dao.get_bakchod_by_id(update.message.from_user.id)

    if bakchod is None:
        bakchod = Bakchod.fromUpdate(update)
        logger.info("Looks like we have a new Bakchod! - {}", bakchod.__dict__)

    bakchod = update_bakchod(bakchod, update)

    # Update Group DB
    group = dao.get_group_by_id(update.message.chat.id)

    if group is None:
        group = Group.fromUpdate(update)
        logger.info("Looks like we have a new Group! - {}", group.__dict__)

    update_group(group, bakchod, update)

    # Log this
    logger.info(
        "[default.all] b.username='******' b.rokda={} g.title='{}'",
        util.extract_pretty_name_from_bakchod(bakchod),
        bakchod.rokda,
        group.title,
    )

    handle_bakchod_modifiers(update, context, bakchod)

    handle_dice_rolls(update, context)

    handle_message_matching(update, context)
Example #3
0
def ratelimit_user(update, ratelimit_key, fail_message, timeout_mins):

    limited = False

    # Enforce rate limiting on getting random quotes
    bakchod = dao.get_bakchod_by_id(update.message.from_user.id)
    history = bakchod.history

    if history is None:
        history = {}

    timeout_time = datetime.now() - timedelta(minutes=timeout_mins)

    if ratelimit_key in history:
        last_time_get = ciso8601.parse_datetime(history[ratelimit_key])
        if last_time_get > timeout_time:
            logger.info("[ratelimit] blocked for key={}", ratelimit_key)
            update.message.reply_text(fail_message)
            limited = True
            return limited

    history[ratelimit_key] = datetime.now()
    bakchod.history = history
    dao.insert_bakchod(bakchod)

    return limited
Example #4
0
def set_bakchod_rokda(rokda_to_set, bakchod_id):

    bakchod = dao.get_bakchod_by_id(bakchod_id)

    bakchod.rokda = rokda_to_set

    dao.insert_bakchod(bakchod)

    reponse = "✅ Set {}'s ₹okda to {}!".format(bakchod.username, bakchod.rokda)

    return reponse
Example #5
0
def check_if_user_can_riposte(tg_id):

    bakchod = dao.get_bakchod_by_id(tg_id)

    if bakchod is not None:
        if bakchod.rokda <= 50:
            return False
        else:
            bakchod.rokda = bakchod.rokda - 50
            dao.insert_bakchod(bakchod)
            return True
    else:
        return False
Example #6
0
def get_random_bakchod(group, bakchod_id):

    if group is not None:

        members = group.members

        random_index = random.randint(0, len(members) - 1)
        random_bakchod_id = members[random_index]
        random_bakchod = dao.get_bakchod_by_id(random_bakchod_id)

        if random_bakchod.id == str(bakchod_id):
            return Bakchod(0, "cr", "cr")

    return random_bakchod
Example #7
0
def get_random_bakchod(group_id):

    random_bakchod = None

    group = dao.get_group_by_id(group_id)

    if group is not None:

        members = group.members

        random_index = random.randint(0, len(members) - 1)
        random_bakchod_id = members[random_index]
        random_bakchod = dao.get_bakchod_by_id(random_bakchod_id)

    return random_bakchod
Example #8
0
def paywall_user(tg_id, cost):

    bakchod = dao.get_bakchod_by_id(tg_id)

    if bakchod is not None:
        if bakchod.rokda <= cost:
            logger.info("[paywall] {} doesn't have enough rokda cost={}",
                        bakchod.id, cost)
            return False
        else:
            bakchod.rokda = bakchod.rokda - cost
            dao.insert_bakchod(bakchod)
            return True
    else:
        return False
Example #9
0
def handle(update, context):

    util.log_chat("reset", update)

    try:

        # Extract query...
        query = update.message.text
        query = query.split(" ")

        target = None

        if not util.is_admin(update.message.from_user["id"]):
            return

        # Request includes the username as a mention
        if update.message.entities:
            for entity in update.message.entities:
                if entity.type == "text_mention" and entity.user is not None:
                    target = dao.get_bakchod_by_id(entity.user.id)

        # Last attempt... try to lookup username in DB
        if target is None:

            receiver_username = query[1]

            # Remove the "@" prefix
            if receiver_username.startswith("@"):
                receiver_username = receiver_username[1:]

            target = dao.get_bakchod_by_username(receiver_username)

        if target is not None:
            logger.info("[reset] target={}",
                        util.extract_pretty_name_from_bakchod(target))
            target.modifiers = {}
            dao.insert_bakchod(target)
            update.message.reply_text(
                "Reset - " + util.extract_pretty_name_from_bakchod(target))
            return

    except Exception as e:
        logger.error(
            "Caught Error in reset.handle - {} \n {}",
            e,
            traceback.format_exc(),
        )
Example #10
0
def handle(update, context):

    util.log_chat("about", update)

    if update.message.reply_to_message:
        query_id = update.message.reply_to_message.from_user["id"]
    else:
        query_id = update.message.from_user["id"]

    bakchod = dao.get_bakchod_by_id(query_id)

    if bakchod is None:
        bakchod = Bakchod.fromUpdate(update)
        dao.insert_bakchod(bakchod)

    update.message.reply_text(text=generate_about_response(bakchod),
                              parse_mode=ParseMode.MARKDOWN)
Example #11
0
def get_random_bakchod(group_id):

    random_bakchod = None

    group = dao.get_group_by_id(group_id)

    if group is not None:

        collected_bakchods = []

        # loop through the member ids and store the bakchod objects
        for member_id in group.members:

            bakchod = dao.get_bakchod_by_id(member_id)

            if bakchod is not None:

                if bakchod.lastseen is not None:

                    try:
                        bakchod.lastseen = ciso8601.parse_datetime(bakchod.lastseen)
                        collected_bakchods.append(bakchod)
                    except Exception as e:
                        logger.error(
                            "Caught Error in roll.get_random_bakchod - {} \n {}",
                            e,
                            traceback.format_exc(),
                        )

        # sort the bakchods by lastseen
        collected_bakchods.sort(key=lambda r: r.lastseen, reverse=True)

        # only care about the x% of the lastseen
        relevant_section = math.ceil(0.15 * len(collected_bakchods))

        # pick a random bakchod from the relevant section
        index = random.randint(0, relevant_section)

        random_bakchod = collected_bakchods[index]

    return random_bakchod
Example #12
0
def reset_roll_effects(context: telegram.ext.CallbackContext):

    # Get group_id
    group_id = context.job.context

    # Get relevant roll based on group_id
    roll = dao.get_roll_by_id(group_id)

    # Get victim's Bakchod
    victim = dao.get_bakchod_by_id(roll["victim"])

    logger.info(
        "[roll] Resetting roll effects for {} in group={}",
        util.extract_pretty_name_from_bakchod(victim),
        group_id,
    )

    # Reset victim's modifiers
    if roll["rule"] == "mute_user":
        censored_modifiers = victim.modifiers["censored"]
        if censored_modifiers is not None:
            censored_modifiers["group_ids"].remove(group_id)
            victim.modifiers["censored"] = censored_modifiers

    elif roll["rule"] == "auto_mom":
        auto_mom_modifiers = victim.modifiers["auto_mom"]
        if auto_mom_modifiers is not None:
            auto_mom_modifiers["group_ids"].remove(group_id)
            victim.modifiers["auto_mom"] = auto_mom_modifiers

    dao.insert_bakchod(victim)

    # Post reset message
    response = "Roll Modifiers for {} are now removed!".format(
        util.extract_pretty_name_from_bakchod(victim)
    )
    context.bot.send_message(
        group_id, text=response,
    )

    return
Example #13
0
def gamble(bakchod_id, chat_id, update):

    bakchod = dao.get_bakchod_by_id(bakchod_id)

    if bakchod is None:
        bakchod = Bakchod.fromUpdate(update)
        dao.insert_bakchod(bakchod)

    can_gamble, response = can_bakchod_gamble(bakchod)

    if can_gamble:

        # Get a random_bakchod from the same Group
        group = dao.get_group_by_id(chat_id)
        random_bakchod = get_random_bakchod(group, bakchod_id)

        response, bakchod, random_bakchod = gamble_engine(
            bakchod, random_bakchod)

        # Update History
        try:
            history = bakchod.history
        except:
            history = {}

        history["gamble"] = datetime.datetime.now()
        bakchod.history = history

        # Update gambler bakchod
        dao.insert_bakchod(bakchod)

        # Update random_bakchod
        if random_bakchod.id != 0:
            dao.insert_bakchod(random_bakchod)

    return response
Example #14
0
def handle(update, context):

    util.log_chat("rokda", update)

    if update.message.reply_to_message:
        bakchod_id = update.message.reply_to_message.from_user["id"]
    else:
        bakchod_id = update.message.from_user["id"]

    bakchod = dao.get_bakchod_by_id(bakchod_id)

    if bakchod is not None:

        response = "💰" + util.extract_pretty_name_from_bakchod(
            bakchod) + " has " + str(round(bakchod.rokda, 2)) + " ₹okda!"
        logger.info("[rokda] Sending response " + response)
        update.message.reply_text(response)

    else:

        logger.info("[rokda] Couldn't find user")
        file_id = "CAADAwADrQADnozgCI_qxocBgD_OFgQ"
        sticker_to_send = file_id
        update.message.reply_sticker(sticker=sticker_to_send)
Example #15
0
def handle(update, context):

    try:

        util.log_chat("daan", update)

        # Extract query...
        query = update.message.text
        query = query.split(" ")

        if len(query) < 2:
            update.message.reply_text(
                text="Haat chutiya! Syntax is `/daan @username 786`",
                parse_mode=ParseMode.MARKDOWN,
            )
            return

        # Extract Sender by ID
        sender = dao.get_bakchod_by_id(update.message.from_user["id"])
        if sender is None:
            sender = Bakchod.fromUpdate(update)
            dao.insert_bakchod(sender)

        # Extract Receiver
        receiver = None

        if update.message.reply_to_message:
            # Request is a reply to message... Extract receiver from ID
            receiver = dao.get_bakchod_by_id(
                update.message.reply_to_message.from_user["id"]
            )

            # Donation can be the rest of the message
            donation = query[1:]

        else:
            # Request includes the username as a mention
            if update.message.entities:
                for entity in update.message.entities:
                    if entity.type == "text_mention" and entity.user is not None:
                        receiver = dao.get_bakchod_by_id(entity.user.id)

            # Last attempt... try to lookup username in DB
            if receiver is None:

                receiver_username = query[1]

                # Remove the "@" prefix
                if receiver_username.startswith("@"):
                    receiver_username = receiver_username[1:]

                receiver = dao.get_bakchod_by_username(receiver_username)

            # Donation can be the rest of the message
            donation = query[2:]

        # Handle if receiver could be extracted
        if receiver is None:
            if receiver_username:
                update.message.reply_text(receiver_username + "??? Who dat???")
                return
            else:
                update.message.reply_text("Kisko daan do be????")
                return

        # Parse Daan amount
        try:
            daan = float("".join(donation))
            daan = round(daan, 2)
            daan = abs(daan)
        except Exception as e:
            update.message.reply_text("Kitna ₹okda be???")
            return

        logger.info(
            "[daan] sender={} receiver={} daan={}",
            util.extract_pretty_name_from_bakchod(sender),
            util.extract_pretty_name_from_bakchod(receiver),
            daan,
        )

        if (sender.rokda - daan) < 0:
            update.message.reply_text("Gareeb saale! You don't have enough ₹okda!")
            return

        if sender.id == receiver.id:
            file_id = "CAADAwADrQADnozgCI_qxocBgD_OFgQ"
            sticker_to_send = file_id
            update.message.reply_sticker(sticker=sticker_to_send)
            return

        # Commit Daan transaction to DB
        sender.rokda = sender.rokda - daan
        dao.insert_bakchod(sender)

        receiver.rokda = receiver.rokda + daan
        dao.insert_bakchod(receiver)

        daan_id = shortuuid.uuid()

        dao.insert_daan(
            daan_id, sender.id, receiver.id, daan, str(datetime.datetime.now())
        )

        update.message.reply_text(
            text="{} gave {} 🤲 a daan of {} ₹okda! 🎉 \n Daan ID - <code>{}</code>".format(
                util.extract_pretty_name_from_bakchod(sender),
                util.extract_pretty_name_from_bakchod(receiver),
                daan,
                daan_id,
            ),
            parse_mode=ParseMode.HTML,
        )
        return

    except Exception as e:
        logger.error(
            "Caught Error in daan.handle - {} \n {}", e, traceback.format_exc(),
        )
Example #16
0
def handle(update, context):

    util.log_chat("quotes", update)

    try:

        # Extract query...
        query = update.message.text
        query = query.split(" ")

        command = None

        try:
            command = query[1].lower()
        except:
            command = "random"

        if command == "add":
            if update.message.reply_to_message.text:
                response = add_quote(update)
                update.message.reply_text(text=response, parse_mode=ParseMode.MARKDOWN)

        elif command == "remove":
            if util.is_admin(update.message.from_user["id"]):
                try:
                    id_to_remove = query[2]
                except:
                    update.message.reply_text(
                        text="Please include the Quote ID you want to remove!",
                        parse_mode=ParseMode.MARKDOWN,
                    )
                    return
                response = remove_quote(id_to_remove)
            else:
                response = "Chal kat re bsdk!"

            update.message.reply_text(text=response, parse_mode=ParseMode.MARKDOWN)

        elif command == "get":

            response = ""

            try:
                quote_id = query[2]
            except:
                update.message.reply_text(
                    text="Please include the Quote ID you want to get!",
                    parse_mode=ParseMode.MARKDOWN,
                )
                return

            quote = get_quote_by_id(quote_id)

            if quote is None:

                group_id = util.get_group_id_from_update(update)
                if group_id is None:
                    update.message.reply_text(text="Can't run this command here!")
                    return

                # Return a random quote
                random_quote = get_random_quote(group_id)

                if random_quote is None:
                    logger.info("[quotes] No quotes found! - group_id={}", group_id)
                    update.message.reply_text(
                        text="No quotes found for this Group! You can add quotes with `/quotes add`",
                        parse_mode=ParseMode.MARKDOWN,
                    )
                    return

                response = "Couldn't find quote with ID `{}`... but here's a random one - \n".format(
                    quote_id
                )

            pretty_quote = generate_pretty_quote(quote)
            response = response + pretty_quote
            update.message.reply_text(text=response, parse_mode=ParseMode.MARKDOWN)

        elif command == "join":

            response = ""

            try:
                quote_id = query[2]
            except:
                update.message.reply_text(
                    text="Please include the Quote ID you want to join!",
                    parse_mode=ParseMode.MARKDOWN,
                )
                return

            quote = get_quote_by_id(quote_id)

            if quote is None:
                update.message.reply_text(
                    text="Couldn't find quote with ID `{}`!".format(quote_id),
                    parse_mode=ParseMode.MARKDOWN,
                )
                return

            response = join_quotes(quote, update)

            update.message.reply_text(text=response, parse_mode=ParseMode.MARKDOWN)

        else:

            # Enforce rate limiting on getting random quotes
            bakchod = dao.get_bakchod_by_id(update.message.from_user.id)
            history = bakchod.history

            if history is None:
                history = {}

            two_min_ago = datetime.datetime.now() - datetime.timedelta(minutes=2)

            if "random_quote_get" in history:
                last_time_get = ciso8601.parse_datetime(history["random_quote_get"])
                if last_time_get > two_min_ago:
                    logger.info("[quotes] request random quote too soon... skipping")
                    update.message.reply_text(
                        "Quotes ki dukan band hai... come back later!"
                    )
                    return

            history["random_quote_get"] = datetime.datetime.now()
            bakchod.history = history
            dao.insert_bakchod(bakchod)

            group_id = util.get_group_id_from_update(update)
            if group_id is None:
                update.message.reply_text(text="Can't run this command here!")
                return

            # Return a random quote
            random_quote = get_random_quote(group_id)

            if random_quote is None:
                logger.info("[quotes] No quotes found! - group_id={}", group_id)
                update.message.reply_text(
                    text="No quotes found for this Group! You can add quotes with `/quotes add`",
                    parse_mode=ParseMode.MARKDOWN,
                )
                return

            logger.info("[quotes] Got a random quote '{}", random_quote)
            pretty_quote = generate_pretty_quote(random_quote)
            update.message.reply_text(text=pretty_quote, parse_mode=ParseMode.MARKDOWN)
            return

    except Exception as e:
        logger.error(
            "Caught Error in quotes.handle - {} \n {}", e, traceback.format_exc(),
        )
Example #17
0
def handle_dice_rolls(dice_value, update, context):

    try:

        metrics.rolls_attempted.inc()

        logger.info("[roll] handle_dice_rolls dice_value={}", dice_value)

        # Extract Group ID
        group_id = get_group_id_from_update(update)
        if group_id is None:
            logger.info("[roll] dice roll was not in a group... skipping")
            return

        # Get current roll based on group_id
        current_roll = dao.get_roll_by_id(group_id)
        if current_roll is None:
            logger.info("[roll] current_roll was a None... skipping")
            return

        # Check whether roll already a winrar
        if current_roll["winrar"] is not None:
            logger.info("[roll] current_roll already has a winrar... skipping")
            return

        # Check roll expiry
        roll_expiry = ciso8601.parse_datetime(current_roll["expiry"])
        if roll_expiry <= datetime.datetime.now():
            logger.info("[roll] current_roll has expired... skipping")
            return

        # Check and update roll history
        roller = dao.get_bakchod_by_id(update.message.from_user.id)
        history = roller.history

        if history is None:
            history = {}

        five_min_ago = datetime.datetime.now() - datetime.timedelta(minutes=5)

        if not DEBUG:
            if "roll" in history:
                last_time_rolled = ciso8601.parse_datetime(history["roll"])
                if last_time_rolled > five_min_ago:
                    logger.info("[roll] rolled too soon... skipping")
                    update.message.reply_text(
                        "You can only roll once every 5 mins... Ignoring this roll!"
                    )
                    return
        else:
            logger.debug("[roll] DEBUG is True... ignoring time check")

        history["roll"] = datetime.datetime.now()
        roller.history = history
        dao.insert_bakchod(roller)

        # Check roll outcome
        roll_number = int(current_roll["roll_number"])

        if dice_value == roll_number:

            metrics.rolls_won.inc()

            # Handle roll winrar
            winrar_bakchod = dao.get_bakchod_by_id(update.message.from_user.id)

            logger.info(
                "[roll] We got a winrar! bakchod={} roll_number={} group_id={}",
                util.extract_pretty_name_from_bakchod(winrar_bakchod),
                roll_number,
                group_id,
            )

            current_roll["winrar"] = winrar_bakchod.id
            current_roll["expiry"] = datetime.datetime.now() + datetime.timedelta(
                hours=1
            )

            # Update roll in DB
            dao.insert_roll(
                current_roll["group_id"],
                current_roll["rule"],
                current_roll["roll_number"],
                current_roll["victim"],
                current_roll["winrar"],
                current_roll["expiry"],
            )

            # Add roll effect to victims modifiers
            victim = dao.get_bakchod_by_id(current_roll["victim"])
            modifiers = victim.modifiers

            if current_roll["rule"] == "mute_user":

                if "censored" in modifiers:
                    censored_modifier = modifiers["censored"]
                else:
                    censored_modifier = {}

                if "group_ids" not in censored_modifier:
                    censored_modifier["group_ids"] = []

                censored_modifier["group_ids"].append(group_id)

                modifiers["censored"] = censored_modifier

            elif current_roll["rule"] == "auto_mom":

                if "auto_mom" in modifiers:
                    auto_mom_modifier = modifiers["auto_mom"]
                else:
                    auto_mom_modifier = {}

                if "group_ids" not in auto_mom_modifier:
                    auto_mom_modifier["group_ids"] = []

                auto_mom_modifier["group_ids"].append(group_id)

                modifiers["auto_mom"] = auto_mom_modifier

            elif current_roll["rule"] == "kick_user":

                try:

                    logger.info(
                        "[roll] Kicking User - group_id={} victim.id={}",
                        group_id,
                        victim.id,
                    )
                    context.bot.send_message(
                        chat_id=update.message.chat_id,
                        text="BYEEEEEEEEEEEE "
                        + util.extract_pretty_name_from_bakchod(victim),
                    )

                    # refer to https://python-telegram-bot.readthedocs.io/en/stable/telegram.bot.html#telegram.Bot.kick_chat_member
                    ban_until = datetime.datetime.now() + datetime.timedelta(seconds=31)
                    context.bot.kick_chat_member(
                        chat_id=group_id, user_id=victim.id, until_date=ban_until
                    )

                    # remove the victim from group members list
                    group = dao.get_group_by_id(group_id)
                    group.members.remove(victim.id)
                    dao.insert_group(group)

                except Exception as e:
                    logger.error(
                        "[roll] Caught Error in kick Bakchod - {} \n {}",
                        e,
                        traceback.format_exc(),
                    )
                    context.bot.send_message(
                        chat_id=update.message.chat_id,
                        text="Looks like I'm not able to kick user... Please check the Group permissions!",
                    )
                    return

            victim.modifiers = modifiers
            dao.insert_bakchod(victim)

            response = "<b>WINRAR!!!</b> {}".format(generate_pretty_roll(current_roll))
            update.message.reply_text(text=response, parse_mode=telegram.ParseMode.HTML)

            # Schedule callback for resetting roll effects in 1 hour
            context.job_queue.run_once(
                reset_roll_effects, 3600, context=update.message.chat_id
            )

    except Exception as e:
        logger.error(
            "Caught Error in roll.handle_dice_rolls - {} \n {}",
            e,
            traceback.format_exc(),
        )

    return