async def handle(message: SlackMessage, bot: SlackAdapter): if not bot.addressed_by(message): return if bot.understands(message, with_pattern=re.compile('ping$', re.I)): bot.reply(message, 'pong') return if bot.understands(message, with_pattern=re.compile('bing$', re.I)): bot.reply(message, 'BONG', create_thread=True) return
async def handle(message: SlackMessage, bot: SlackAdapter, db: DB): pattern = "|".join( [".*(?:gibbe|give) money.*", ".*pay me.*", ".*:watermelon:.*"]) trigger = re.compile(pattern, re.IGNORECASE) message_ts = arrow.get(message.ts, 'X') if not is_payable(message_ts) or not bot.understands( message, with_pattern=trigger): return user_id = message.user with db.session_scope() as session: user = User.get_by_slack_id(session, user_id) if not user: return latest_mine = session \ .query(KKredsTransaction) \ .filter(KKredsTransaction.to_user_id == user.id) \ .filter(KKredsTransaction.is_mined) \ .order_by(KKredsTransaction.created_at.desc()) \ .first() if latest_mine and latest_mine.created_at: message_ts_stripped = strip_date(message_ts) latest_mine_time_stripped = strip_date(latest_mine.created_at) if latest_mine_time_stripped >= message_ts_stripped: return amount = 1 if should_2020_04_mega_pay(message_ts): amount = randint(1, 10_000) kaori_user = User.get_by_slack_id(session, bot.id) mined_kkred = KKredsTransaction(from_user=kaori_user, to_user=user, amount=amount, is_mined=True, created_at=message_ts.datetime) session.add(mined_kkred) pluralized = '1 kkred' if amount == 1 else f'{amount} kkreds' bot.reply(message, f'successfully mined {pluralized}')
async def handle(message: SlackMessage, bot: SlackAdapter): if not bot.addressed_by(message): return asking_help = re.compile(r'(?:cards|gacha) ?(?:help|-h|--help)?', re.I) question = re.compile(r'(?:what|why|how|explain).+(?:cards?|gacha)', re.I) if not (bot.understands(message, with_pattern=asking_help) or bot.understands(message, with_pattern=question)): return bot.reply(message, blocks=help_blocks(), create_thread=True, reply_broadcast=True)
async def test_help_command(fake_slack_msg_factory, fake_slack_adapter: SlackAdapter): bogus_message = fake_slack_msg_factory(text=f'@kaori asldfkjslkdjf') fake_slack_adapter.reply = MagicMock(return_value={'ok': True}) await CardHelpCommand.handle(bogus_message, bot=fake_slack_adapter) await CardPriceCommand.handle(bogus_message, bot=fake_slack_adapter) fake_slack_adapter.reply.assert_not_called() await CardHelpCommand.handle(fake_slack_msg_factory( text='@kaori cards help', bot=fake_slack_adapter, ), bot=fake_slack_adapter) ehhhh = ujson.dumps(fake_slack_adapter.reply.call_args[1]) assert 'kaori show cards' in ehhhh assert 'kaori battle NAME vs. NAME' in ehhhh await CardPriceCommand.handle(fake_slack_msg_factory( text='@kaori card prices', bot=fake_slack_adapter, ), bot=fake_slack_adapter) ehhhh = ujson.dumps(fake_slack_adapter.reply.call_args[1]) assert 'price breakdown' in ehhhh
async def handle(message: SlackMessage, bot: SlackAdapter): if message.user == bot.id: return text = message.text.strip() tokens = text.split() if not text: return if bot.mentioned.directly(tokens[0]) and tokens[0].endswith('?'): bot.reply(message, random.choice(im_here_response)) if interrogative_greeting.search(text) and bot.mentioned.anywhere( text): return bot.reply(message, random.choice(interrogative_greeting_response)) if greeting.search(text) and bot.mentioned.anywhere(text): return bot.reply(message, random.choice(greeting_response))
async def handle(message: SlackMessage, bot: SlackAdapter, db: DB): if not bot.addressed_by(message): return match = bot.understands(message, with_pattern=re.compile('refresh users')) if not match: return res = bot.client.api_call('users.list') if not res['ok']: raise RuntimeError('call to users.list failed') slack_members = [ member for member in res['members'] if not member['deleted'] ] with db.session_scope() as session: def maybe_create(slack_id): return User.maybe_create_user_from_slack_id( slack_id, bot.client, session) kaori_members = [ maybe_create(member['id']) for member in slack_members ] for member in kaori_members: el = [x for x in slack_members if x['id'] == member.slack_id] if not el: continue el = el[0] if member.name != el['name']: member.name = el['name'] bot.reply(message, 'Refreshed users. :^)')
async def handle(message: SlackMessage, bot: SlackAdapter): if not bot.addressed_by(message): return if not bot.understands( message, with_pattern=re.compile('card prices?[?]?$', re.I)): return res = bot.reply(message, text='Here are the current prices for creating cards:', blocks=price_blocks()) if not res['ok']: print(res)
async def handle(message: SlackMessage, bot: SlackAdapter, db: DB): pattern = re.compile('balance', re.IGNORECASE) if not bot.addressed_by(message) or not bot.understands( message, with_pattern=pattern): return with db.session_scope() as session: user = User.get_by_slack_id(session, message.user) balance = get_kkred_balance(user, session) pluralized_kkreds = 'kkred' if balance == 1 else 'kkreds' return bot.reply(message, f'your balance is {balance} {pluralized_kkreds}')
async def handle(message: SlackMessage, bot: SlackAdapter, db: DB): if not bot.addressed_by(message): return show_card_pattern = '|'.join([ '(?:get|show|find) card' ]) show_card_pattern = f'(?:{show_card_pattern})' pattern = re.compile(f'{show_card_pattern} (.+)', re.I) search = bot.understands(message, with_pattern=pattern) if not search: return with db.session_scope() as session: card = Card.search_for_one(session, search[1]) if not card: bot.reply(message, 'no card with that name', create_thread=True) return bot.reply(message, **render_card(card))
async def handle(message: SlackMessage, bot: SlackAdapter, db: DB): if not bot.addressed_by(message): return show_card_pattern = '|'.join([ 'cards? (?:stats|statistics)' ]) if not bot.understands(message, with_pattern=re.compile(show_card_pattern, re.I)): return with db.session_scope() as session: game_cards = get_game_cards(session) if not game_cards: bot.reply(message, "No cards", create_thread=True) return bot.reply(message, blocks=card_stats_blocks(card_total=len(game_cards)), create_thread=True) report = generate_report_charts(game_cards) bot.client.api_call( 'files.upload', channels=message.channel, thread_ts=message.ts, filename='rarity.png', file=report['rarity']) bot.client.api_call( 'files.upload', channels=message.channel, thread_ts=message.ts, filename='natures.png', file=report['natures'])
async def handle(message: SlackMessage, bot: SlackAdapter, db: DB): if not bot.addressed_by(message): return show_card_pattern = '|'.join([ '(?:get|gimme|show|find|list) ?(?:my|muh)? cardo?s' ]) if not bot.understands(message, with_pattern=re.compile(show_card_pattern, re.I)): return with db.session_scope() as session: cards = session.query(Card) \ .join(User) \ .filter(User.slack_id == message.user) \ .filter(Card.published == True) \ .limit(10) \ .all() if not cards: bot.reply(message, "You don't have any cards yet.", create_thread=True) return bot.reply(message, create_thread=True, blocks=card_index_blocks(cards))
async def handle(message: SlackMessage, bot: SlackAdapter, db: DB, battler: CardBattler): if not bot.addressed_by(message): return requested_battle = _user_requesting_battle(message=message, bot=bot) if not requested_battle: return attacker_search = requested_battle[1] defender_search = requested_battle[2] with db.session_scope() as session: attacker = Card.search_for_one(session, attacker_search) if not attacker: bot.reply(message, f'no card named "{attacker_search}"', create_thread=True) return defender = Card.search_for_one(session, defender_search) if not defender: bot.reply(message, f'no card named "{defender_search}"', create_thread=True) return battle_url = battler.get_battle_url(attacker.engine, defender.engine) bot.reply(message, create_thread=True, blocks=battle_blocks(attacker=attacker, defender=defender, battle_url=battle_url))
async def handle(message: SlackMessage, bot: SlackAdapter, db: DB): pattern = re.compile(r'(?:pay|tip|give|send)\s+(\S*)\s+(\S*)', re.IGNORECASE) if not bot.addressed_by(message): return matches = bot.understands(message, with_pattern=pattern) if not matches: return message_ts = arrow.get(message.ts, 'X') sending_user_id = message.user with db.session_scope() as session: sending_user = User.get_by_slack_id(session, sending_user_id) if not sending_user: return receiving_user_raw = matches[1] if not is_user_mention(receiving_user_raw): return bot.reply( message, 'User has to be an `@` mention. Like it has to be a real blue `@` mention.' ) receiving_user = User.get_by_slack_id( session, extract_user_id_from_mention(receiving_user_raw)) if not receiving_user: return bot.reply(message, 'Could not find that user') if sending_user.id == receiving_user.id: return bot.reply(message, 'You can’t send money to yourself.') amount_raw = matches[2] try: amount = Decimal(amount_raw) except InvalidOperation: return bot.reply( message, 'That amount is invalid. Try a decimal or integer value') if amount <= 0: return bot.reply(message, 'Amount has to be non-zero') if amount > get_kkred_balance(sending_user, session): return bot.reply(message, 'You don’t have enough kkreds') transaction = KKredsTransaction(from_user=sending_user, to_user=receiving_user, amount=amount, created_at=message_ts.datetime) session.add(transaction) bot.reply(message, f'successfully sent {amount} to {receiving_user.name}')
async def handle(message: SlackMessage, bot: SlackAdapter, db: DB, file_uploader: FileUploader): if not bot.addressed_by(message) or not message.is_thread: return try: session: Session with db.session_scope() as session: card = resume_card(session, thread_ts=message.thread_ts, user=message.user) # this thread is not related to a card creation, ignore if not card: return # lol god this is quickly getting away from me # just let me finish this and I'll refactor later user_input = '' catch_all_pattern = re.compile(r'(.*)', re.IGNORECASE) matches = bot.understands(message, with_pattern=catch_all_pattern) if not matches: return user_input = matches[1].strip() if user_input == 'refresh preview': refresh_card_preview(card, bot) return if card.creation_cursor == 'set_image': if message.files: img = Image.from_slack_message(message=message, session=session, slack_adapter=bot, uploader=file_uploader) card.image = img card.creation_cursor = 'query_description' bot.react(message, 'thumbsup') else: bot.reply(message, 'upload an image to slack') return card, replies = next_card_creation_step( card=card, user_input=user_input, session=session, kaori_user=User.get_by_slack_id(session, bot.id)) refresh_card_preview(card, bot) session.merge(card) session.commit() for reply in replies: if reply == ':+1:': bot.react(message, 'thumbsup') else: if isinstance(reply, dict): bot.reply(message, create_thread=True, **reply) else: bot.reply(message, reply, create_thread=True) except InvalidCardName as e: bot.reply(message, str(e)) except IntegrityError as e: bot.reply( message, f"Something is wrong with that input...try again or ask Austin to fix it. Code {e.code}" ) print(e)
async def handle(message: SlackMessage, bot: SlackAdapter, db: DB, file_uploader: FileUploader): if not bot.addressed_by(message): return # start a conversation if not bot.understands(message, with_pattern=re.compile( r'create\s+card|card\s+create$', re.I)): return if message.is_thread_reply: return try: with db.session_scope() as session: user = User.get_by_slack_id(session, message.user) if not user: raise UserNotFound('cannot find user') # allow creation to recover from errors card = resume_card(session, thread_ts=message.thread_ts, user=message.user) if not card: card = initialize_card(message, user) session.add(card) session.commit() draft_message = bot.reply(message, **render_card(card=card, preview_header=True), create_thread=True, reply_broadcast=True) bot.reply( message, blocks=instructions_blocks(bot_name=bot.mention_string), create_thread=True) if not draft_message.get('ok'): print(draft_message) return card.draft_message_ts = draft_message.get('ts') session.merge(card) except UserNotFound as e: bot.reply( message, "Something is wrong...cannot find your user. Try 'kaori refresh users'" ) return # fake thread # todo: this is kinda dumb message = copy.deepcopy(message) message.is_thread = True message.thread_ts = message.ts await UpdateCardCommand.handle(message=message, bot=bot, db=db, file_uploader=file_uploader)