async def t20(self, ctx: commands.Context): async with aiohttp.ClientSession() as session: async with session.get( 'http://www.projectdivar.com/eventdata/t20') as resp: leaderboard = await resp.json(encoding='utf-8') event = self.bot.asset_filters.events.get_latest_event(ctx) embed = discord.Embed(title=f'{event.name} t20') embed.set_thumbnail(url=self.bot.asset_url + get_event_logo_path(event)) max_points_digits = len(str(leaderboard[0]['points'])) nl = "\n" update_date = dateutil.parser.isoparse( leaderboard[0]["date"]).replace(microsecond=0) update_date = update_date.astimezone(pytz.timezone('Asia/Tokyo')) header = f'Updated {update_date}\n\nRank {"Points":<{max_points_digits}} Name' listing = [ f'{player["rank"]:<4} {player["points"]:<{max_points_digits}} {player["name"].replace(nl, "")}' for player in leaderboard ] paged = run_paged_message(ctx, embed, listing, header=header, page_size=10, numbered=False) asyncio.ensure_future(paged)
async def cards(self, ctx: commands.Context, *, arg: commands.clean_content = ''): self.logger.info(f'Searching for cards "{arg}".') try: arguments = parse_arguments(arg) cards = self.get_cards(ctx, arguments) sort, sort_op = arguments.single('sort', None, allowed_operators=['<', '>', '='], converter=card_attribute_aliases) display, _ = arguments.single(['display', 'disp'], sort or CardAttribute.Power, allowed_operators=['='], converter=card_attribute_aliases) except ArgumentError as e: await ctx.send(str(e)) return listing = [] for card in cards: display_prefix = display.get_formatted_from_card(card) if display_prefix: listing.append( f'{display_prefix} {self.format_card_name_for_list(card)}') else: listing.append(self.format_card_name_for_list(card)) embed = discord.Embed(title=f'Card Search "{arg}"' if arg else 'Cards') asyncio.ensure_future(run_paged_message(ctx, embed, listing))
async def command_usage(self, ctx: commands.Context): usage_counts = (await CommandUsageCount.all().annotate( use_count=Sum('counter') ).order_by('name').group_by('name').values_list('name', 'use_count')) embed = discord.Embed(title='Command Usage') asyncio.create_task( run_paged_message( ctx, embed, [f'{name}: {count}' for name, count in usage_counts] + [f'total: {sum(c for _, c in usage_counts)}'], page_size=40))
async def command(ctx, *, arg: Optional[ParsedArguments]): arg = arg or await ParsedArguments.convert(ctx, '') sort = None display = None reverse_sort = arg.tag('reverse') if sortable_data_attributes: sort, sort_op = arg.single_op( 'sort', None, allowed_operators=['<', '>', '='], converter=sort_arguments) if sort: reverse_sort ^= (sort_op == '<') ^ sort.reverse_sort display = arg.single(['display', 'disp'], sort if sort and sort.formatter else None, converter={ **sort_arguments, 'none': None }) tag_arguments = { a: arg.tags(a.value_mapping.keys()) for a in tag_data_attributes } keyword_arguments = { a: arg.words(a.value_mapping.keys()) for a in keyword_data_attributes } flag_arguments = { a: bool(arg.tags([a.name] + a.aliases)) for a in flag_data_attributes } comparable_arguments = { a: arg.repeatable_op( [a.name] + a.aliases, is_list=True, allowed_operators=['=', '==', '!=', '>', '<', '>=', '<='], converter=self.wrap_compare_converter( ctx, a.compare_converter) or (lambda s: float(s))) for a in comparable_data_attributes } eq_arguments = { a: arg.repeatable_op([a.name] + a.aliases, is_list=True, allowed_operators=['=', '==', '!='], converter=self.wrap_compare_converter( ctx, a.compare_converter) or a.value_mapping or (lambda s: float(s))) for a in eq_data_attributes } text = arg.text() arg.require_all_arguments_used() values = self.get_by_relevance(text, ctx) for attr, tags in tag_arguments.items(): if tags: targets = {attr.value_mapping[t] for t in tags} if attr.is_plural: values = [ v for v in values if targets.issubset(attr.accessor(self, ctx, v)) ] else: values = [ v for v in values if attr.accessor(self, ctx, v) in targets ] for attr, tags in keyword_arguments.items(): if tags: targets = {attr.value_mapping[t] for t in tags} if attr.is_plural: values = [ v for v in values if targets.issubset(attr.accessor(self, ctx, v)) ] else: values = [ v for v in values if attr.accessor(self, ctx, v) in targets ] for attr, flag_present in flag_arguments.items(): if flag_present: if attr.flag_callback: callback_value = attr.flag_callback(self, ctx, values) if callback_value is not None: values = callback_value else: values = [ v for v in values if attr.accessor(self, ctx, v) ] for attr, arguments in { **comparable_arguments, **eq_arguments }.items(): for argument in arguments: argument_value, operation = argument if attr.is_plural: operator = list_to_list_operator_for(operation) else: operator = list_operator_for(operation) values = [ v for v in values if operator( attr.accessor(self, ctx, v), argument_value) ] display = display or source.default_display if source.default_sort and not text: values = sorted( values, key=lambda v: source.default_sort.accessor(self, ctx, v)) if source.default_sort.reverse_sort ^ bool(sort and reverse_sort): values = values[::-1] if sort: values = sorted(values, key=lambda v: sort.accessor(self, ctx, v)) if reverse_sort: values = values[::-1] if display and display.formatter: listing = [ f'{display.formatter(self, ctx, value)} {source.list_formatter(self, ctx, value)}' for value in values ] else: listing = [ source.list_formatter(self, ctx, value) for value in values ] embed = discord.Embed(title=self.l10n[ctx].format_value( source.list_name or 'search')) asyncio.create_task(run_paged_message(ctx, embed, listing))
async def songs(self, ctx: commands.Context, *, arg: commands.clean_content = ''): self.logger.info( f'Searching for songs "{arg}".' if arg else 'Listing songs.') arguments = parse_arguments(arg) try: sort, sort_op = arguments.single('sort', MusicAttribute.DefaultOrder, allowed_operators=['<', '>', '='], converter=music_attribute_aliases) reverse_sort = sort_op == '<' or arguments.tag('reverse') display, _ = arguments.single(['display', 'disp'], sort, allowed_operators=['='], converter=music_attribute_aliases) units = { self.bot.aliases.units_by_name[unit].id for unit in arguments.tags( names=self.bot.aliases.units_by_name.keys(), aliases=self.bot.aliases.unit_aliases) } def difficulty_converter(d): return int(d[:-1]) + 0.5 if d[-1] == '+' else int(d) difficulty = arguments.repeatable(['difficulty', 'diff', 'level'], is_list=True, converter=difficulty_converter) songs = self.bot.asset_filters.music.get_sorted( arguments.text(), ctx) arguments.require_all_arguments_used() except ArgumentError as e: await ctx.send(str(e)) return for value, op in difficulty: operator = list_operator_for(op) songs = [ song for song in songs if operator(song.charts[4].level, value) ] if units: songs = [song for song in songs if song.unit.id in units] if not (arguments.text_argument and sort == MusicAttribute.DefaultOrder): songs = sorted(songs, key=lambda s: sort.get_sort_key_from_music(s)) if sort == MusicAttribute.DefaultOrder and songs and songs[ 0].id == 1: songs = [*songs[1:], songs[0]] if sort in [MusicAttribute.Level, MusicAttribute.Date]: songs = songs[::-1] if reverse_sort: songs = songs[::-1] listing = [] for song in songs: display_prefix = display.get_formatted_from_music(song) if display_prefix: listing.append( f'{display_prefix} : {song.name}{" (" + song.special_unit_name + ")" if song.special_unit_name else ""}' ) else: listing.append( f'{song.name}{" (" + song.special_unit_name + ")" if song.special_unit_name else ""}' ) embed = discord.Embed(title=f'Song Search "{arg}"' if arg else 'Songs') asyncio.ensure_future(run_paged_message(ctx, embed, listing))