async def cog_before_invoke(self, ctx: Context): ctx.error = False msg = ctx.message # Check paused if await RedisDB.instance().is_paused(): ctx.error = True await Messages.send_error_dm(msg.author, f"Transaction activity is currently suspended. I'll be back online soon!") return if ctx.command.name == 'send_cmd': try: ctx.send_amount = RegexUtil.find_send_amounts(msg.content) if Validators.too_many_decimals(ctx.send_amount): await Messages.send_error_dm(msg.author, f"You are only allowed to use {Env.precision_digits()} digits after the decimal.") ctx.error = True return except AmountMissingException: await Messages.send_usage_dm(msg.author, SEND_INFO) ctx.error = True return except AmountAmbiguousException: await Messages.send_error_dm(msg.author, "You can only specify 1 amount to send") ctx.error = True return if ctx.command.name in ['send_cmd', 'sendmax_cmd']: # See if user exists in DB user = await User.get_user(msg.author) if user is None: await Messages.send_error_dm(msg.author, f"You should create an account with me first, send me `{config.Config.instance().command_prefix}help` to get started.") ctx.error = True return elif user.frozen: ctx.error = True await Messages.send_error_dm(msg.author, f"Your account is frozen. Contact an admin if you need further assistance.") return # Update name, if applicable await user.update_name(msg.author.name) ctx.user = user # See if they are spammin' withdraw_delay = await user.get_next_withdraw_s() if withdraw_delay > 0: await Messages.send_error_dm(msg.author, f"You need to wait {withdraw_delay}s before you can withdraw again") ctx.error = True return try: ctx.destination = RegexUtil.find_address_match(msg.content) except AddressMissingException: await Messages.send_usage_dm(msg.author, SEND_INFO) ctx.error = True return except AddressAmbiguousException: await Messages.send_error_dm(msg.author, "You can only specify 1 destination address") ctx.error = True return if not Validators.is_valid_address(ctx.destination): await Messages.send_error_dm(msg.author, "The destination address you specified is invalid") ctx.error = True return
async def ufw(self, request: web.Request): """Return user info for specified wallet addresses e.g. http://server/wfu/ban_16n5c7qozokx661rneikh6e3mf978mc46qqjen7a51pwzood155bwrha6sfj+ban_37z6omyukgpgttq7bdagweaxdrdm5wjy7tdm97ggtkobdetme3bmhfayjowj""" if 'wallet' not in request.match_info: return web.HTTPBadRequest(reason="wallet is required") try: addresses = RegexUtil.find_address_matches( request.match_info['wallet']) except AddressMissingException: return web.HTTPBadRequest(reason="bad address specified") accounts = await Account.filter(address__in=addresses ).prefetch_related('user').all() if accounts is None: return web.json_response(data={'error': 'user(s) not found'}, dumps=json.dumps) resp = [] for account in accounts: resp.append({ 'user_id': account.user.id, 'user_last_known_name': account.user.name, 'address': account.address, 'created_ts_utc': self.format_js_iso(account.user.created_at) }) return web.json_response(data=resp, dumps=json.dumps)
async def ufw_cmd(self, ctx: Context): msg = ctx.message try: addresses = RegexUtil.find_address_matches(msg.content) except AddressMissingException: await Messages.add_x_reaction(msg) await Messages.send_error_dm(msg.author, "No valid addresses in your ufw command") return address_list = await Account.filter(address__in=addresses).prefetch_related('user').all() if len(address_list) < 1: await Messages.add_x_reaction(msg) await Messages.send_error_dm(msg.author, "No users found with specified addresses.") return for acct in address_list: response = f"Last known name: {acct.user.name}```{acct.user.id}```" response += f"```{acct.address}```" if Env.banano(): response += f"https://creeper.banano.cc/explorer/account/{acct.address}\n" else: response += f"https://nanocrawler.cc/explorer/account/{acct.address}\n" embed = discord.Embed(colour=0xFBDD11 if Env.banano() else discord.Colour.green()) embed.set_author(name="UFW Result", icon_url="https://github.com/bbedward/Graham_Nano_Tip_Bot/raw/master/assets/banano_logo.png" if Env.banano() else "https://i.imgur.com/7QFgoqT.png") embed.description = response await msg.author.send(embed=embed)
async def register_cmd(self, ctx: Context): if ctx.error: return msg = ctx.message try: amount = RegexUtil.find_float(msg.content) except AmountMissingException: amount = 0.0 # Get/create user try: user = await User.create_or_fetch_user(msg.author) user_address = await user.get_address() except Exception: self.logger.exception('Exception creating user') await Messages.send_error_dm(msg.author, "I failed at retrieving your address, try again later and contact my master if the issue persists.") return # Build URI uri_scheme = "ban:" if Env.banano() else "watermelonano:" if amount == 0: uri = user_address else: uri = "{0}{1}?amount={2}".format(uri_scheme, user_address, Env.amount_to_raw(amount)) # Build and send response embed = discord.Embed(colour=0xFBDD11 if Env.banano() else discord.Colour.green()) embed.set_author(name=user_address, icon_url="https://github.com/bbedward/Graham_Nano_Tip_Bot/raw/master/assets/banano_logo.png" if Env.banano() else "https://i.imgur.com/7QFgoqT.png") embed.set_image(url=f"https://chart.googleapis.com/chart?cht=qr&chl={uri}&chs=180x180&choe=UTF-8&chld=L|2") await msg.author.send(embed=embed) await msg.author.send(user_address)
async def cog_before_invoke(self, ctx: Context): ctx.error = False msg = ctx.message # See if user exists in DB user = await User.get_user(msg.author) if user is None: ctx.error = True await Messages.send_error_dm( msg.author, f"You should create an account with me first, send me `{config.Config.instance().command_prefix}help` to get started." ) return elif user.frozen: ctx.error = True await Messages.send_error_dm( msg.author, f"Your account is frozen. Contact an admin if you need further assistance." ) return ctx.user = user # Update name if applicable await user.update_name(msg.author.name) # Special checks for tipfavorites if ctx.command.name == 'tipfavorites_cmd': # Check admins ctx.god = msg.author.id in config.Config.instance().get_admin_ids() ctx.admin = False author: discord.Member = msg.author for role in author.roles: if role.id in config.Config.instance().get_admin_roles(): ctx.admin = True break # Check paused if await RedisDB.instance().is_paused(): ctx.error = True await Messages.send_error_dm( msg.author, f"Transaction activity is currently suspended. I'll be back online soon!" ) return # See if amount meets tip_minimum requirement try: send_amount = RegexUtil.find_float(msg.content) if send_amount < Constants.TIP_MINIMUM: raise AmountMissingException( f"Tip amount is too low, minimum is {Constants.TIP_MINIMUM}" ) elif Validators.too_many_decimals(send_amount): await Messages.send_error_dm( ctx.message.author, f"You are only allowed to use {Env.precision_digits()} digits after the decimal." ) ctx.error = True return except AmountMissingException: ctx.error = True await Messages.send_usage_dm(msg.author, TIPFAVORITES_INFO) ctx.send_amount = send_amount
async def increasetips_cmd(self, ctx: Context): if ctx.error: return msg = ctx.message increasetip_ids = [] # Get mentioned users for m in msg.mentions: increasetip_ids.append(m.id) # remove duplicates and avoid admins increasetip_ids = set(increasetip_ids) increasetip_ids = [x for x in increasetip_ids if x not in config.Config.instance().get_admin_ids()] if msg.author.id not in config.Config.instance().get_admin_ids(): for d in increasetip_ids: memba = msg.guild.get_member(d) if memba is not None: for r in memba.roles: if r.id in [config.Config.instance().get_admin_roles()]: d.remove(r.id) if len(increasetip_ids) < 1: await Messages.add_x_reaction(msg) await msg.author.send("Your message has no users to increasetips for") return try: amount = RegexUtil.find_float(msg.content) except AmountMissingException: await Messages.send_usage_dm(msg.author, INCREASETIPS_INFO) return # TODO - tortoise doesnt give us any feedback on update counts atm # https://github.com/tortoise/tortoise-orm/issues/126 # TODO - we also don't have atomic updates :/ increase_tip_count = 0 for u in await Stats.filter(user_id__in=increasetip_ids, server_id=msg.guild.id).all(): async with in_transaction() as conn: u.total_tipped_amount = float(u.total_tipped_amount) + amount u.legacy_total_tipped_amount = float(u.legacy_total_tipped_amount) + amount await u.save(using_db=conn, update_fields=['total_tipped_amount', 'legacy_total_tipped_amount']) increase_tip_count += 1 await msg.author.send(f"Increased stats of {increase_tip_count} by {amount} {Env.currency_name()}") await msg.add_reaction("\u2795")
async def cog_before_invoke(self, ctx: Context): ctx.error = False msg = ctx.message if ChannelUtil.is_private(ctx.message.channel): ctx.error = True return else: # Check admins ctx.god = msg.author.id in config.Config.instance().get_admin_ids() ctx.admin = False author: discord.Member = msg.author for role in author.roles: if role.id in config.Config.instance().get_admin_roles(): ctx.admin = True break # Check paused if await RedisDB.instance().is_paused(): ctx.error = True await Messages.send_error_dm( msg.author, f"Transaction activity is currently suspended. I'll be back online soon!" ) return # Check anti-spam if not ctx.god and await RedisDB.instance().exists( f"rainspam{msg.author.id}"): ctx.error = True await Messages.add_timer_reaction(msg) await Messages.send_basic_dm( msg.author, "You can only rain once every 5 minutes") return # Parse some info try: ctx.send_amount = RegexUtil.find_send_amounts(msg.content) if Validators.too_many_decimals(ctx.send_amount): await Messages.add_x_reaction(msg) await Messages.send_error_dm( msg.author, f"You are only allowed to use {Env.precision_digits()} digits after the decimal." ) ctx.error = True return elif ctx.send_amount < config.Config.instance().get_rain_minimum(): ctx.error = True await Messages.add_x_reaction(msg) await Messages.send_usage_dm(msg.author, RAIN_INFO) return # See if user exists in DB user = await User.get_user(msg.author) if user is None: await Messages.add_x_reaction(msg) await Messages.send_error_dm( msg.author, f"You should create an account with me first, send me `{config.Config.instance().command_prefix}help` to get started." ) ctx.error = True return elif user.frozen: ctx.error = True await Messages.add_x_reaction(msg) await Messages.send_error_dm( msg.author, f"Your account is frozen. Contact an admin if you need further assistance." ) return # Update name, if applicable await user.update_name(msg.author.name) ctx.user = user except AmountMissingException: await Messages.add_x_reaction(msg) await Messages.send_usage_dm(msg.author, RAIN_INFO) ctx.error = True return except AmountAmbiguousException: await Messages.add_x_reaction(msg) await Messages.send_error_dm( msg.author, "You can only specify 1 amount to send") ctx.error = True return
async def tipgiveaway_cmd(self, ctx: Context): if ctx.error: return msg = ctx.message user = ctx.user # Check roles if not await self.role_check(msg): return # Punish them for trying to do this command in a no spam channel if msg.channel.id in config.Config.instance().get_no_spam_channels(): redis_key = f"ticketspam:{msg.author.id}" if not ctx.god: spam = await RedisDB.instance().get(redis_key) if spam is not None: spam = int(spam) else: spam = 0 await Messages.add_x_reaction(msg) await Messages.send_error_dm(msg.author, "You can't view donate to the giveaway in this channel") await RedisDB.instance().set(f"ticketspam:{msg.author.id}", str(spam + 1), expires=3600) await Messages.delete_message_if_ok(msg) return # Get their tip amount try: tip_amount = RegexUtil.find_float(msg.content) if tip_amount < Constants.TIP_MINIMUM: await Messages.send_error_dm(msg.author, f"Minimum tip amount if {Constants.TIP_MINIMUM}") await Messages.delete_message_if_ok(msg) return except AmountMissingException: await Messages.send_usage_dm(msg.author, TIPGIVEAWAY_INFO) await Messages.delete_message_if_ok(msg) return # Get active giveaway gw = await Giveaway.get_active_giveaway(server_id=msg.guild.id) if gw is None: # get bot-pending giveaway or create one gw = await Giveaway.get_pending_bot_giveaway(server_id=msg.guild.id) if gw is None: try: # Initiate the bot giveaway with a lock to avoid race condition # Lock this so concurrent giveaways can't be started/avoid race condition async with RedisLock( await RedisDB.instance().get_redis(), key=f"{Env.currency_symbol().lower()}giveawaylock:{msg.guild.id}", timeout=30, wait_timeout=30 ) as lock: # See if giveaway already in progress should_create = False active_giveaway = await Giveaway.get_active_giveaway(server_id=msg.guild.id) if active_giveaway is None: bot_giveaway = await Giveaway.get_pending_bot_giveaway(server_id=msg.guild.id) if bot_giveaway is None: should_create = True if should_create: # Start giveaway async with in_transaction() as conn: gw = await Giveaway.start_giveaway_bot( server_id=msg.guild.id, entry_fee=config.Config.instance().get_giveaway_auto_fee(), started_in_channel=msg.channel.id, conn=conn ) except LockTimeoutError: gw = await Giveaway.get_pending_bot_giveaway(server_id=msg.guild.id) if gw is None: await Messages.send_error_dm(msg.author, "I was unable to process your donation, try again alter!") await Messages.delete_message_if_ok(msg) return # Check balance available_balance = Env.raw_to_amount(await user.get_available_balance()) if tip_amount > available_balance: if not ctx.god: redis_key = f"ticketspam:{msg.author.id}" spam = await RedisDB.instance().get(redis_key) if spam is not None: spam = int(spam) else: spam = 0 await RedisDB.instance().set(f"ticketspam:{msg.author.id}", str(spam + 1), expires=3600) await Messages.add_x_reaction(msg) await Messages.send_error_dm(msg.author, "Your balance isn't high enough to complete this tip.") await Messages.delete_message_if_ok(msg) return # See if they already contributed user_tx = await Transaction.filter(giveaway__id=gw.id, sending_user__id=user.id).first() already_entered = False async with in_transaction() as conn: if user_tx is not None: if int(user_tx.amount) >= int(gw.entry_fee): already_entered=True user_tx.amount = str(int(user_tx.amount) + Env.amount_to_raw(tip_amount)) await user_tx.save(update_fields=['amount'], using_db=conn) else: user_tx = await Transaction.create_transaction_giveaway( user, tip_amount, gw, conn=conn ) if gw.end_at is None: if not already_entered and int(user_tx.amount) >= int(gw.entry_fee): await Messages.send_success_dm(msg.author, f"With your generous donation of {Env.raw_to_amount(int(user_tx.amount))} {Env.currency_symbol()} I have reserved your spot for giveaway #{gw.id}!") else: await Messages.send_success_dm(msg.author, f"Your generous donation of {Env.raw_to_amount(int(user_tx.amount))} {Env.currency_symbol()} will help support giveaway #{gw.id}!") # See if we should start this giveaway, and start it if so # TODO - We should use the DB SUM() function but,we store it as a VarChar and tortoise-orm currently doesn't support casting giveaway_sum_raw = 0 for tx in await Transaction.filter(giveaway=gw): giveaway_sum_raw += int(tx.amount) giveaway_sum = Env.raw_to_amount(giveaway_sum_raw) if giveaway_sum >= config.Config.instance().get_giveaway_auto_minimum(): # start giveaway # re-fetch latest version gw = await Giveaway.get_pending_bot_giveaway(server_id=msg.guild.id) if gw is not None: gw.end_at = datetime.datetime.utcnow() + datetime.timedelta(minutes=config.Config.instance().get_giveaway_auto_duration()) gw.started_in_channel = msg.channel.id async with in_transaction() as conn: await gw.save(update_fields=['end_at', 'started_in_channel'], using_db=conn) # Announce giveaway embed = self.format_giveaway_announcement(gw, amount=giveaway_sum_raw) await msg.channel.send(embed=embed) for ch in config.Config.instance().get_giveaway_announce_channels(): if ch != msg.channel.id: channel = msg.guild.get_channel(ch) if channel is not None: try: await channel.send(embed=embed) except Exception: pass # Start the timer asyncio.create_task(self.start_giveaway_timer(gw)) else: if not already_entered and int(user_tx.amount) >= int(gw.entry_fee): await Messages.send_success_dm(msg.author, f"With your generous donation of {tip_amount} {Env.currency_symbol()} I have entered you into giveaway #{gw.id}!") else: await Messages.send_success_dm(msg.author, f"Your generous donation of {tip_amount} {Env.currency_symbol()} will help support giveaway #{gw.id}!") if msg.channel.id in config.Config.instance().get_giveaway_no_delete_channels(): await Messages.add_tip_reaction(msg, tip_amount) await Messages.delete_message_if_ok(msg) # Update stats stats: Stats = await user.get_stats(server_id=msg.guild.id) if msg.channel.id not in config.Config.instance().get_no_stats_channels(): await stats.update_tip_stats(tip_amount)
async def ticket_cmd(self, ctx: Context): if ctx.error: return msg = ctx.message user = ctx.user author = msg.author content = msg.content is_private = ChannelUtil.is_private(msg.channel) id=None if is_private: if 'id=' not in msg.content: await Messages.send_usage_dm(msg.author, TICKET_INFO) await Messages.add_x_reaction(msg) return # Parse message split_content = msg.content.split(' ') cleaned_content = msg.content for split in split_content: if split.startswith('id='): cleaned_content.replace(split, "") split = split.replace('id=','').strip() if not split: continue try: id = int(split) except ValueError as e: await Messages.add_x_reaction(msg) await Messages.send_usage_dm(msg.author, TICKET_INFO) return # See if they've been spamming redis_key = f"ticketspam:{msg.author.id}" if not ctx.god: spam = await RedisDB.instance().get(redis_key) if spam is not None: spam = int(spam) if spam >= 3: await Messages.send_error_dm(msg.author, "You're temporarily banned from entering giveaways") await Messages.delete_message_if_ok(msg) return else: spam = 0 else: spam = 0 # Get active giveaway if id is None: gw = await Giveaway.get_active_giveaway(server_id=msg.guild.id) else: gw = await Giveaway.get_active_giveaway_by_id(id=id) if gw is None: await Messages.send_error_dm(msg.author, "There aren't any active giveaways to enter.") await Messages.delete_message_if_ok(msg) # Block ticket spam await RedisDB.instance().set(f"ticketspam:{msg.author.id}", str(spam + 1), expires=3600) return # Check roles if is_private: guild = self.bot.get_guild(gw.server_id) if guild is None: await Messages.send_error_dm(msg.author, "Something went wrong, ask my master for help") return member = guild.get_member(msg.author.id) if member is None: await "You're not a member of that server" return msg.author = member if not await self.role_check(msg): return # There is an active giveaway, enter em if not already entered. active_tx = await Transaction.filter(giveaway__id=gw.id, sending_user__id=user.id).first() if active_tx is not None and int(gw.entry_fee) == 0: await Messages.send_error_dm(msg.author, "You've already entered this giveaway.") await Messages.delete_message_if_ok(msg) return elif active_tx is None: paid_already = 0 else: paid_already = int(active_tx.amount) if paid_already >= int(gw.entry_fee) and int(gw.entry_fee) > 0: await Messages.send_error_dm(msg.author, "You've already entered this giveaway.") await Messages.delete_message_if_ok(msg) return # Enter em fee_raw = int(gw.entry_fee) - paid_already fee = Env.raw_to_amount(fee_raw) # Check balance if fee is > 0 if fee > 0: try: amount = RegexUtil.find_float(msg.content) if amount < fee: await Messages.send_error_dm(msg.author, f"This giveaway has a fee of {fee} {Env.currency_symbol()}. The amount you specified isn't enough to cover the entry fee") await Messages.delete_message_if_ok(msg) return except AmountMissingException: await Messages.send_error_dm(msg.author, f"This giveaway has a fee, you need to specify the amount to enter. `{config.Config.instance().command_prefix}ticket {fee}`") await Messages.delete_message_if_ok(msg) return available_balance = Env.raw_to_amount(await user.get_available_balance()) if fee > available_balance: await Messages.add_x_reaction(ctx.message) await Messages.send_error_dm(msg.author, f"Your balance isn't high enough to complete this tip. You have **{available_balance} {Env.currency_symbol()}**, but this entry would cost you **{fee} {Env.currency_symbol()}**") await Messages.delete_message_if_ok(msg) await RedisDB.instance().set(f"ticketspam:{msg.author.id}", str(spam + 1), expires=3600) return await Transaction.create_transaction_giveaway( user, fee, gw ) await Messages.send_success_dm(msg.author, f"You've successfully been entered into giveaway #{gw.id}") await Messages.delete_message_if_ok(msg) return
async def giveaway_cmd(self, ctx: Context): if ctx.error: return msg = ctx.message user = ctx.user # Check paused if await RedisDB.instance().is_paused(): await Messages.send_error_dm(msg.author, f"Transaction activity is currently suspended. I'll be back online soon!") return # Check roles if not await self.role_check(msg): return elif msg.channel.id in config.Config.instance().get_no_spam_channels(): await Messages.send_error_dm(msg.author, f"You can't start giveaways in this channel") return if 'fee=' not in msg.content or 'duration=' not in msg.content: await Messages.send_usage_dm(msg.author, START_GIVEAWAY_INFO) await Messages.add_x_reaction(msg) return # Parse message split_content = msg.content.split(' ') cleaned_content = msg.content for split in split_content: if split.startswith('fee='): cleaned_content.replace(split, "") split = split.replace('fee=','').strip() if not split: continue try: fee = abs(float(split)) except ValueError as e: await Messages.add_x_reaction(msg) await Messages.send_usage_dm(msg.author, START_GIVEAWAY_INFO) return elif split.startswith('duration='): cleaned_content.replace(split, "") split=split.replace('duration=','').strip() if not split: continue try: duration = abs(int(split)) if not ctx.god and (duration < config.Config.instance().get_giveaway_min_duration() or duration > config.Config.instance().get_giveaway_max_duration()): raise ValueError("Bad duration specified") except ValueError as e: await Messages.add_x_reaction(msg) await Messages.send_usage_dm(msg.author, START_GIVEAWAY_INFO) return # Find giveaway amount try: giveaway_amount = RegexUtil.find_float(cleaned_content) if Validators.too_many_decimals(giveaway_amount): await Messages.send_error_dm(ctx.message.author, f"You are only allowed to use {Env.precision_digits()} digits after the decimal for giveaway amount.") ctx.error = True return elif fee > giveaway_amount * config.Config.instance().get_giveaway_max_fee_multiplier(): await Messages.add_x_reaction(msg) await Messages.send_usage_dm(msg.author, START_GIVEAWAY_INFO) return elif giveaway_amount < config.Config.instance().get_giveaway_minimum(): await Messages.add_x_reaction(msg) await Messages.send_usage_dm(msg.author, START_GIVEAWAY_INFO) return except AmountMissingException: await Messages.add_x_reaction(msg) await Messages.send_usage_dm(msg.author, START_GIVEAWAY_INFO) return # See how much they need to make this tip. available_balance = Env.raw_to_amount(await user.get_available_balance()) if giveaway_amount > available_balance: await Messages.add_x_reaction(ctx.message) await Messages.send_error_dm(msg.author, f"Your balance isn't high enough to start this giveaway. You have **{available_balance} {Env.currency_symbol()}**, but this tip would cost you **{giveaway_amount} {Env.currency_symbol()}**") return try: # Lock this so concurrent giveaways can't be started/avoid race condition async with RedisLock( await RedisDB.instance().get_redis(), key=f"{Env.currency_symbol().lower()}giveawaylock:{msg.guild.id}", timeout=30, wait_timeout=30 ) as lock: # See if giveaway already in progress active_giveaway = await Giveaway.get_active_giveaway(server_id=msg.guild.id) if active_giveaway is not None: await Messages.add_x_reaction(msg) await Messages.send_error_dm(msg.author, "There's already a giveaway in progress on this server") return # Start giveaway async with in_transaction() as conn: gw = await Giveaway.start_giveaway_user( server_id=msg.guild.id, started_by=user, amount=giveaway_amount, entry_fee=fee, duration=duration, started_in_channel=msg.channel.id, conn=conn ) # Create pending TX for this user await Transaction.create_transaction_giveaway( sending_user=user, amount=giveaway_amount, giveaway=gw, conn=conn ) # Announce giveaway embed = self.format_giveaway_announcement(gw) await msg.channel.send(embed=embed) for ch in config.Config.instance().get_giveaway_announce_channels(): if ch != msg.channel.id: channel = msg.guild.get_channel(ch) if channel is not None: try: await channel.send(embed=embed) except Exception: pass # Start the timer asyncio.create_task(self.start_giveaway_timer(gw)) except LockTimeoutError: await Messages.add_x_reaction(msg) await Messages.send_error_dm(msg.author, "I couldn't start a giveaway, maybe someone else beat you to it as there can only be 1 active at a time.")
def test_find_address(self): os.environ['BANANO'] = 'true' self.assertEqual( RegexUtil.find_address_match( 'sdasdasban_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48oksesdadasd' ), 'ban_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48okse') with self.assertRaises(AddressAmbiguousException): RegexUtil.find_address_match( 'sdasdban_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48oksesdasd ban_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48okse sban_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48okse' ) with self.assertRaises(AddressMissingException): RegexUtil.find_address_match('sdadsd') del os.environ['BANANO'] self.assertEqual( RegexUtil.find_address_match( 'sdasdasnano_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48oksesdadasd' ), 'nano_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48okse' ) with self.assertRaises(AddressAmbiguousException): RegexUtil.find_address_match( 'sdasdnano_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48oksesdasd nano_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48okse snano_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48okse' ) with self.assertRaises(AddressMissingException): RegexUtil.find_address_match('sdadsd') # XRB self.assertEqual( RegexUtil.find_address_match( 'sdasdasxrb_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48oksesdadasd' ), 'xrb_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48okse') with self.assertRaises(AddressAmbiguousException): RegexUtil.find_address_match( 'sdasdxrb_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48oksesdasd xrb_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48okse sxrb_3jb1fp4diu79wggp7e171jdpxp95auji4moste6gmc55pptwerfjqu48okse' ) with self.assertRaises(AddressMissingException): RegexUtil.find_address_match('sdadsd')
def test_find_send_amounts(self): self.assertEqual(RegexUtil.find_send_amounts('Hello 1.23 World'), 1.23) with self.assertRaises(AmountMissingException): RegexUtil.find_send_amounts('Hello World') with self.assertRaises(AmountAmbiguousException): RegexUtil.find_send_amounts('Hello 1.23 4.56 World')
def test_find_float(self): self.assertEqual(RegexUtil.find_float('Hello 1.23 World'), 1.23) self.assertEqual(RegexUtil.find_float('Hello 1.23 4.56 World'), 1.23) with self.assertRaises(AmountMissingException) as exc: RegexUtil.find_float('Hello World')
async def cog_before_invoke(self, ctx: Context): ctx.error = False # Remove duplicate mentions ctx.message.mentions = set(ctx.message.mentions) # Only allow tip commands in public channels msg = ctx.message if ChannelUtil.is_private(msg.channel): ctx.error = True return else: # Check admins ctx.god = msg.author.id in config.Config.instance().get_admin_ids() ctx.admin = False author: discord.Member = msg.author for role in author.roles: if role.id in config.Config.instance().get_admin_roles(): ctx.admin = True break # Check paused if await RedisDB.instance().is_paused(): ctx.error = True await Messages.send_error_dm( msg.author, f"Transaction activity is currently suspended. I'll be back online soon!" ) return # See if user exists in DB user = await User.get_user(msg.author) if user is None: ctx.error = True await Messages.send_error_dm( msg.author, f"You should create an account with me first, send me `{config.Config.instance().command_prefix}help` to get started." ) return elif user.frozen: ctx.error = True await Messages.send_error_dm( msg.author, f"Your account is frozen. Contact an admin if you need further assistance." ) return # Update name, if applicable await user.update_name(msg.author.name) ctx.user = user # See if amount meets tip_minimum requirement try: send_amount = RegexUtil.find_float(msg.content) if ctx.command.name == 'tiprandom_cmd' and send_amount < Constants.TIPRANDOM_MINIMUM: raise AmountMissingException( f"Tip random amount is too low, minimum is {Constants.TIPRANDOM_MINIMUM}" ) elif ctx.command.name != 'tiprandom_cmd' and ctx.command.name != 'burn' and send_amount < Constants.TIP_MINIMUM: raise AmountMissingException( f"Tip amount is too low, minimum is {Constants.TIP_MINIMUM}" ) elif ctx.command.name == 'burn' and send_amount < 1.0: raise AmountMissingException(f"Come on, burn at least 1 BAN") elif Validators.too_many_decimals(send_amount): await Messages.send_error_dm( ctx.message.author, f"You are only allowed to use {Env.precision_digits()} digits after the decimal." ) ctx.error = True return except AmountMissingException: ctx.error = True if ctx.command.name == 'tip_cmd': await Messages.send_usage_dm(msg.author, TIP_INFO) elif ctx.command.name == 'tipsplit_cmd': await Messages.send_usage_dm(msg.author, TIPSPLIT_INFO) elif ctx.command.name == 'tiprandom_cmd': await Messages.send_usage_dm(msg.author, TIPRANDOM_INFO) elif ctx.command.name == 'burn': await Messages.send_basic_dm( msg.author, 'Come on, burn at least 1 ya cheap skate') return ctx.send_amount = send_amount