Exemplo n.º 1
0
async def add(ctx: MrvnCommandContext,
              status: Option(str, choices=[
                  OptionChoice("Online", "online"),
                  OptionChoice("Invisible", "invisible"),
                  OptionChoice("Idle", "idle"),
                  OptionChoice("Do Not Disturb", "dnd")
              ]),
              activity: Option(str, choices=[
                  OptionChoice("Playing", "playing"),
                  OptionChoice("Streaming", "streaming"),
                  OptionChoice("Listening", "listening"),
                  OptionChoice("Watching", "watching"),
                  OptionChoice("Competing", "competing")
              ]),
              text: ParseUntilEndsOption(str)):
    if len(await BotStatusEntry.filter()) == ENTRIES_LIMIT:
        await ctx.respond_embed(Style.ERROR, ctx.translate("bot_status_command_add_limit_reached"))

        return
    elif len(text) > 50:
        await ctx.respond_embed(Style.ERROR, ctx.translate("bot_status_command_add_text_too_long"))

        return

    await BotStatusEntry.create(status=status, activity=activity.lower(), text=text)

    status_update.start_task()

    await ctx.respond_embed(Style.OK, ctx.translate("bot_status_command_add_status_added"))
Exemplo n.º 2
0
 async def generate(self, ctx, server: Option(str, 'Guild ID'),
                    user: Option(str, 'User ID')):
     try:
         guild = await self.bot.fetch_guild(server)
     except:
         await ctx.respond("Guild not found.", ephemeral=True)
         return
     messages = []
     earliest = datetime.now(timezone.utc)
     foundOne = True
     await ctx.defer()
     while foundOne:
         foundOne = False
         for channel in await guild.fetch_channels():
             if channel.type == ChannelType.text:
                 try:
                     async for message in channel.history(before=earliest):
                         if str(message.author.id) == user:
                             foundOne = True
                             messages.append(message)
                         if message.created_at < earliest:
                             earliest = message.created_at
                 except Exception as e:
                     print(e)
     msg = f'Found {len(messages)} messages. Delete all (deletion may find more)?'
     confirm_view = Confirm(delete_history(messages))
     await ctx.respond(msg, ephemeral=True, view=confirm_view)
Exemplo n.º 3
0
 async def ban(self, ctx, member: Option(Member,
                                         'Ban a member of the server.',
                                         required=False),
               userid: Option(str, 'Ban any user by id.', required=False)):
     if not ctx.user.guild_permissions.ban_members:
         await ctx.respond(conf.get_string(ctx.user,
                                           'insufficientUserPermissions'),
                           ephemeral=True)
         return
     if not member and not userid:
         await ctx.respond('Must enter at least one of member or userid.',
                           ephemeral=True)
     if member:
         user = member
     else:
         user = Object(userid)
     try:
         await ctx.guild.ban(user)
     except NotFound:
         await ctx.respond(f'User {user.id} could not be found',
                           ephemeral=True)
         return
     except Forbidden:
         log.exception(
             f'Could not ban {user.id} from server {ctx.guild.id}. Check permissions.'
         )
         await ctx.respond(
             'Ban failed due to permissions issue. Do I have the "ban" permission?',
             ephemeral=True)
         return
     await ctx.respond(f'Banned user {user.id}.')
Exemplo n.º 4
0
 async def make_sprint(self,
                       ctx,
                       delay: Option(int,
                                     'Minutes until the sprint starts.',
                                     required=False) = DEFAULT_DELAY,
                       duration: Option(int,
                                        'Sprint duration in minutes',
                                        required=False) = DEFAULT_DURATION):
     start_time = datetime.datetime.now() + datetime.timedelta(
         minutes=delay)
     end_time = start_time + datetime.timedelta(minutes=duration)
     activeSprints[ctx.channel.id] = {
         'start': start_time,
         'end': end_time,
         'members': {}
     }
     await delay_function(start_time, send_message,
                          (ctx.channel, 'Starting a ' + str(duration) +
                           '-minute sprint with {mentions}!'))
     await delay_function(end_time, send_message, (
         ctx.channel,
         'Sprint has ended, {mentions}, you have 1 minute to submit your final word counts!'
     ))
     await delay_function(end_time + datetime.timedelta(minutes=1),
                          end_sprint, [ctx.channel])
     view = NewSprintView(delay * 60 + duration * 60, ctx.channel)
     view.interaction = await ctx.respond(
         '{0}-minute sprint starting in {1} minutes.'.format(
             duration, delay),
         view=view)
Exemplo n.º 5
0
 async def message_reminder(
     self, ctx, content: Option(str, 'What should I remind you about?'),
     time: Option(str,
                  'A time and/or date in UTC, or a duration from now.')):
     when_time = parse_time(time)
     if not when_time:
         await ctx.respond(f'Unable to parse time string: ' + time,
                           ephemeral=True)
         return
     msg = f'Reminder: {content}'
     reminder_id = save_one_reminder(ctx.user, when_time, msg)
     await set_reminder(reminder_id, when_time, ctx.user, msg)
     await ctx.respond(
         f'I\'ll DM you "{msg}" {friendly_until_string(when_time, True)}.',
         ephemeral=True)
Exemplo n.º 6
0
 async def roll_dice(self, ctx, rolls: str,
                     label: Option(str, 'Would you like to label this roll?', required=False)):
     embed = Embed()
     command_name, results = roll_command(str(ctx.user.id), rolls)
     for key, value in results.items():
         embed.add_field(name=key, value=value)
     follow_up = False
     if label:
         embed.title = label
         if not command_name and not any(char.isdigit() for char in label):
             follow_up = True
     else:
         label = rolls
         if command_name:
             embed.title = command_name
             label = command_name
     msg = ctx.user.mention + ' rolled ' + label + '!'
     await ctx.respond(msg, embed=embed)
     if follow_up:
         suppress_until = userconfig.get_key(ctx.user.id, SUPPRESS_SAVE_CONFIG_KEY)
         sanitize_suppress_save_config(ctx.user.id, suppress_until)
         if not suppress_until or suppress_until < datetime.now():
             confirmer = Confirm(saver(label, rolls),
                                 middle_callback=suppress_autosave,
                                 middle_label="Don't show for 24H",
                                 cancel_callback=never_show_autosave,
                                 cancel_label="Never show this")
             await ctx.respond(f'Would you like to save {rolls} as {label}?', view=confirmer, ephemeral=True)
Exemplo n.º 7
0
 async def pick(
     self,
     ctx,
     number: Option(int,
                    'How many to pick of the given choices.',
                    required=False) = 1,
     options: Option(str,
                     'What to pick from. Separated by spaces or commas.',
                     required=False) = None,
     role: Option(
         Role,
         'Pick a random member that has a given role on this server.',
         required=False) = None):
     embed = Embed()
     if options:
         if ',' in options:
             optionset = options.split(',')
         else:
             optionset = options.split()
         embed.set_footer(text='Options were:\n> ' + '\n> '.join(optionset))
     elif role:
         optionset = [member.mention for member in role.members]
         embed.set_footer(
             text=
             f'Randomly selected from all members with the {role.name} role.'
         )
         if role.is_default():
             embed.set_footer(
                 text='Randomly selected from all members of this server.')
     else:
         await ctx.respond(
             'Sorry, you have to give me something to pick from, either options or a role.',
             ephemeral=True)
         return
     if number < 1:
         await ctx.respond(
             'I have chosen nothing. I award you no points, and may the gods have mercy on your soul.',
             ephemeral=True)
         return
     if number > len(optionset):
         number = len(optionset)
     embed.insert_field_at(0,
                           name='Chosen:',
                           value='**' +
                           '**\n**'.join(sample(optionset, number)) + '**',
                           inline=False)
     await ctx.respond('I have chosen!', embed=embed)
Exemplo n.º 8
0
    async def permathread(self, ctx: ApplicationContext, name: Option(str, "Thread name")):
        if not isinstance(ctx.channel, TextChannel):
            await ctx.respond('Must be inside a text channel')
            return

        thread: Thread = await ctx.channel.create_thread(name=name, type=ChannelType.public_thread)
        await self.permathreads.insert_one({'_id': thread.id})
        await ctx.respond('Created permathread')
Exemplo n.º 9
0
async def choices(ctx,
                  choice_str: Option(str,
                                     choices=[
                                         OptionChoice("Choice 1", "Anus"),
                                         OptionChoice("Choice 2", "Amogus"),
                                         OptionChoice("Choice 3", "Test")
                                     ])):
    await ctx.respond_embed(Style.INFO, f"{choice_str}")
Exemplo n.º 10
0
 async def submit_words(self, ctx, words: Option(int,
                                                 'Your final wordcount.')):
     if ctx.channel.id in activeSprints:
         activeSprints[ctx.channel.id]['members'][
             ctx.user.mention]['endCount'] = words
         await ctx.respond('Word count for {0} updated to {1}'.format(
             ctx.user.mention, words))
     else:
         await ctx.respond('No active sprints.', ephemeral=True)
Exemplo n.º 11
0
 async def add_notice(self, ctx,
                      title: Option(str, 'Title to find the notice by.'),
                      text: Option(str, 'Content of the notice.')):
     if ctx.user.guild_permissions.administrator:
         curr_notices = load_notices(ctx.guild.id)
         new_notice = {
             'text': text,
             'created': datetime.utcnow().isoformat()
         }
         reply = f'Create notice "{title}"?\n'
         if title in curr_notices:
             reply = f'Update notice "{title}"?\n'
             reply += f'Old content:\n```\n{curr_notices[title]["text"]}\n```\n'
             new_notice['created'] = curr_notices[title]['created']
         reply += f'New content:\n>>> {text}'
         confirm_view = Confirm(update_notice(title, new_notice))
         await ctx.respond(reply, view=confirm_view, ephemeral=True)
     else:
         await ctx.respond("Only a server admin can add notices.",
                           ephemeral=True)
Exemplo n.º 12
0
 async def generate(self,
                    ctx,
                    name: Option(str,
                                 'Which generator?',
                                 autocomplete=gen_autocomplete),
                    count: Option(int,
                                  'How many? Default 1.',
                                  required=False) = 1,
                    public: Option(
                        bool,
                        'Should others see output? Default false.',
                        required=False) = False):
     if name in conf.get_object(ctx.guild, 'generators'):
         await ctx.respond('\n'.join([
             generator.extract_text(generator.generate(name))
             for _ in range(count)
         ]),
                           ephemeral=not public)
     else:
         await ctx.respond(f"{name} is not a recognized generator.")
Exemplo n.º 13
0
 async def read_notice(self, ctx,
                       title: Option(str,
                                     'Read which notice?',
                                     autocomplete=notice_autocomplete,
                                     required=False)):
     curr_notices = load_notices(ctx.guild.id)
     if not title:
         msg = '>>> ' + get_latest(curr_notices)
     elif title in curr_notices:
         msg = '>>> ' + curr_notices[title]['text']
     else:
         msg = f'Notice "{title}" not found. Try using the autocomplete.'
     await ctx.respond(msg)
Exemplo n.º 14
0
async def purge(ctx: MrvnCommandContext,
                number: Option(int, min_value=1, max_value=200),
                member: Member = None):
    try:
        deleted = await ctx.channel.purge(
            limit=number,
            check=lambda msg: member is None or msg.author == member,
            bulk=True)
    except Forbidden:
        await ctx.respond_embed(
            Style.ERROR, ctx.translate("moderation_bot_insufficient_perms"))
    else:
        await ctx.respond_embed(
            Style.OK,
            ctx.format("moderation_command_purge_messages_removed",
                       ctx.author.mention, deleted))
Exemplo n.º 15
0
 async def delete_notice(self, ctx,
                         title: Option(str,
                                       'Delete which notice?',
                                       autocomplete=notice_autocomplete)):
     if ctx.user.guild_permissions.administrator:
         curr_notices = load_notices(ctx.guild.id)
         if title in curr_notices:
             reply = f'Delete notice {title}?\nFormer content was:\n```\n{curr_notices[title]["text"]}\n```'
             confirm_view = Confirm(remove_notice(title))
             await ctx.respond(reply, view=confirm_view, ephemeral=True)
         else:
             await ctx.respond(f'Notice "{title}" not found.',
                               ephemeral=True)
     else:
         await ctx.respond("Only a server admin can delete notices.",
                           ephemeral=True)
Exemplo n.º 16
0
 async def search(self, ctx,
                  site_name: Option(str,
                                    'What wiki to search',
                                    autocomplete=wikis_autocomplete),
                  query: str):
     mw_options = conf.get_object(ctx.guild, 'mwSites')
     if site_name not in mw_options:
         return await ctx.respond(
             f'"{site_name}" is not a valid search source on this server.')
     site = Site(mw_options[site_name]['url'],
                 path=mw_options[site_name]['path'],
                 clients_useragent=USER_AGENT)
     results = site.search(query)
     title = results.next().get('title').replace(' ', '_')
     await ctx.respond(f'First result for "{query}":\n' + str(
         f'https://{mw_options[site_name]["url"]}{mw_options[site_name]["pagePath"]}{title}'
     ))
Exemplo n.º 17
0
 async def join_sprint(
     self,
     ctx,
     words: Option(
         int,
         'Your starting wordcount. Will be subtracted from your total.',
         required=False) = 0):
     if ctx.channel.id in activeSprints:
         activeSprints[ctx.channel.id]['members'][ctx.user.mention] = {
             'startCount': words,
             'endCount': words
         }
         await ctx.respond(
             'Added {0} to {1:.0f}-minute sprint starting in {2:.1f} minutes.'
             .format(ctx.user.mention, *describe_sprint(ctx.channel)))
     else:
         await ctx.respond('No active sprints.', ephemeral=True)
Exemplo n.º 18
0
async def vision(ctx: MrvnCommandContext, image: Option(Attachment)):
    if not image.content_type.startswith("image"):
        await ctx.respond_embed(
            Style.ERROR,
            ctx.translate("vision_command_vision_invalid_content_type"))

        return

    await ctx.defer()

    session = aiohttp.ClientSession(timeout=ClientTimeout(20))

    try:
        response = await session.post(
            SERVICE_URL,
            data="userlink=%s" % parse.quote(image.url, safe=''),
            headers={
                "Cookie": "textonly=true; imageonly=true; qronly=false",
                "Content-Type": "application/x-www-form-urlencoded"
            })
    except (aiohttp.ClientConnectionError, asyncio.TimeoutError):
        await ctx.respond_embed(
            Style.ERROR,
            ctx.translate("vision_command_vision_connection_error"))

        return
    finally:
        await session.close()

    text = await response.text()

    response.close()

    soup = BeautifulSoup(text, "html.parser")
    results = soup.find_all("div", {"class": "success description"})

    if not len(results):
        await ctx.respond_embed(Style.ERROR,
                                ctx.translate("vision_command_vision_fail"))
        return

    embed = ctx.get_embed(Style.INFO, results[0].text,
                          ctx.translate("vision_command_vision_title"))
    embed.set_image(url=image.url)

    await ctx.respond(embed=embed)
Exemplo n.º 19
0
async def mute(ctx: MrvnCommandContext, member: Member, time: int,
               unit: Option(str,
                            choices=[
                                OptionChoice("Seconds", "s"),
                                OptionChoice("Minutes", "m"),
                                OptionChoice("Hours", "h"),
                                OptionChoice("Days", "d"),
                                OptionChoice("Weeks", "w"),
                                OptionChoice("Months", "mo"),
                                OptionChoice("Years", "y")
                            ])):
    if member == runtime.bot.user:
        await ctx.respond_embed(
            Style.ERROR, ctx.translate("moderation_cant_do_this_to_bot"))

        return
    elif member == ctx.author:
        await ctx.respond_embed(
            Style.ERROR, ctx.translate("moderation_cant_do_this_to_self"))

        return
    elif member.guild_permissions.administrator:
        await ctx.respond_embed(
            Style.ERROR,
            ctx.translate("moderation_command_mute_cant_mute_administrator"))

        return
    elif ctx.author.top_role.position < member.top_role.position or ctx.author.guild_permissions < member.guild_permissions:
        await ctx.respond_embed(
            Style.ERROR, ctx.translate("moderation_cant_do_this_to_this_user"))

        return

    timestamp = datetime.datetime.utcnow() + datetime.timedelta(
        0, time * TIME_DICT[unit])

    try:
        await member.edit(communication_disabled_until=timestamp)
    except Forbidden:
        await ctx.respond_embed(
            Style.ERROR, ctx.translate("moderation_bot_insufficient_perms"))
    else:
        await ctx.respond_embed(
            Style.OK,
            ctx.format("moderation_command_mute_successful", member.mention))
Exemplo n.º 20
0
    async def complete(self,
                       ctx,
                       prompt: Option(str, "Text to autocomplete")):

        base = f'**{discord.utils.escape_markdown(prompt)}**'
        await ctx.defer()
        json = {
            'prompt': prompt,
            'max_tokens': 80,
            'temperature': 0.9,
        }
        async with self.session.post(URL, headers=HEADERS, json=json) as r:
            result = await r.json()
            error = result.get('error')
            if error:
                await ctx.send(f"<:pepeLaugh:665663440014147616> {error['message']}")
            else:
                final = base + result['choices'][0]['text']
                await ctx.send(truncate_string(final))
Exemplo n.º 21
0
 async def view(self, ctx, target: Option(Member,
                                          'Whose pet?',
                                          required=False)):
     owner = ctx.user
     if target is not None:
         owner = target
     try:
         my_pet = load_pet(str(owner.id))
     except KeyError:
         if owner == ctx.user:
             await ctx.respond(
                 "Failed to load your pet. Maybe you don't have one? Try `/summon` to get one now!",
                 ephemeral=True)
         else:
             await ctx.respond(
                 f"Failed to load {owner.display_name}'s pet. Maybe they don't have one? They should try /summon!",
                 ephemeral=True)
         return
     embed = my_pet.render()
     view = PetView(my_pet, str(owner.id))
     view.interaction = await ctx.respond(f'{owner.mention}\'s pet!',
                                          view=view,
                                          embed=embed)
Exemplo n.º 22
0
    async def color(self, ctx: ApplicationContext,
                    hex_code: Option(str, "Hex code")):

        if not is_hex_color_code(hex_code):
            await ctx.respond("Invalid hex code. Color format example: 44ff00`"
                              )

        # Make sure we have guild space
        if not (len(ctx.guild.roles) < 250):
            await ctx.respond('No custom role slots left!')
            return

        prefix = self.bot.cfg['color-role-prefix']

        color = discord.Colour(int(hex_code, 16))
        new_role = await ctx.guild.create_role(name=f'{prefix} #{hex_code}',
                                               color=color)

        user: Member = ctx.author

        # Unequip old colors
        for role in ctx.user.roles:
            if role.name.startswith(prefix):
                await user.remove_roles(role)

                # Delete if we're the last owner
                if len(role.members) < 2:
                    await role.delete()

        # Give new color
        try:
            await user.add_roles(new_role)
        except Exception as e:
            await ctx.respond(f'Failed to assign new color: {e}')
        else:
            await ctx.respond("✅")
Exemplo n.º 23
0
 async def show_swatch(self, ctx, color_code: Option(
     str, 'Hex color string, such as #131071')):
     swatch = get_swatch(color_code)
     await ctx.respond('', file=File(swatch, filename=color_code + '.png'))
Exemplo n.º 24
0
async def edit(ctx: MrvnCommandContext, key: Option(
    str, autocomplete=basic_autocomplete(setting_autocomplete)), value: str):
    await edit_(ctx, key, value, True)
Exemplo n.º 25
0
    async def lowadm(
        self, ctx, adm: Option(float,
                               description="Optional ADM Level to flag under.",
                               required=False)):
        """
        Systems with low ADMs.
        """
        if not adm:
            adm = app_settings.get_low_adm()
        #    @commands.command(pass_context=True)
        #    @message_in_channels(settings.SOV_DISCORD_BOT_CHANNELS)

        if ctx.channel.id not in settings.SOV_DISCORD_BOT_CHANNELS:
            return await ctx.respond(
                f"You do not have permission to use this command here.",
                ephemeral=True)

        await ctx.defer()

        own_ids = settings.DISCORD_BOT_SOV_STRUCTURE_OWNER_IDS

        include_regions = settings.DISCORD_BOT_ADM_REGIONS
        include_systems = settings.DISCORD_BOT_ADM_SYSTEMS
        include_constel = settings.DISCORD_BOT_ADM_CONSTELLATIONS

        sov_structures = providers.esi.client.Sovereignty.get_sovereignty_structures(
        ).result()

        names = {}
        for s in sov_structures:
            if s.get('alliance_id') in own_ids:
                if s.get('vulnerability_occupancy_level'):
                    if s.get('vulnerability_occupancy_level') < adm:
                        names[s.get('solar_system_id')] = {
                            "system_name": s.get('solar_system_id'),
                            "adm": s.get('vulnerability_occupancy_level')
                        }

        if len(names) == 0:
            await ctx.respond(f"All above {adm} :ok_hand:")
            return True

        systems = [k for k, v in names.items()]
        constelations = {}
        for n in systems:
            system = providers.esi.client.Universe.get_universe_systems_system_id(
                system_id=n).result()
            names[n]["system_name"] = system.get("name")
            names[n]["system_id"] = system.get("system_id")
            names[n]["constellation_id"] = system.get("constellation_id")
            if system.get("constellation_id") not in constelations:
                constelations[system.get("constellation_id")] = {}

        for c, v in constelations.items():
            const = providers.esi.client.Universe.get_universe_constellations_constellation_id(
                constellation_id=c).result()
            region = providers.esi.client.Universe.get_universe_regions_region_id(
                region_id=const.get("region_id")).result()
            v["region_id"] = const.get("region_id")
            v["region_name"] = region.get("name")
            v["constellation_name"] = const.get("name")

        out_array = {}
        for k, v in names.items():
            out_array[k] = {**v, **constelations[v["constellation_id"]]}

        output = {}
        base_str = "**{}** ADM:{}"
        urls = {}
        for k, h in sorted(out_array.items(), key=lambda e: e[1]['adm']):
            show = False
            if h['region_id'] in include_regions:
                show = True
            elif h['constellation_id'] in include_constel:
                show = True
            elif h['system_id'] in include_systems:
                show = True
            if show:
                if h['region_name'] not in output:
                    output[h['region_name']] = []
                output[h['region_name']].append(
                    base_str.format(h['system_name'], h['adm']))
                if h['region_name'].replace(" ", "_") not in urls:
                    urls[h['region_name'].replace(" ", "_")] = []
                urls[h['region_name'].replace(" ", "_")].append(
                    h['system_name'].replace(" ", "_"))
        url = "https://evemaps.dotlan.net/map/{}/{}#adm"

        if len(output) > 0:
            embed = Embed(title="Low ADMs!")
            embed.set_thumbnail(
                url=
                "https://avatars3.githubusercontent.com/u/39349660?s=200&v=4")
            embed.colour = Color.red()
            embed.description = f"Showing systems with ADMs below {adm}. Due to an ESI bug this data might only update once a day at around 2200-2300 Eve Time. **YMMY**\n[For more info please see this issue](https://github.com/esi/esi-issues/issues/1092)"

            await ctx.respond(embed=embed)

            for k, v in output.items():
                n = 25
                chunks = [
                    list(v[i * n:(i + 1) * n])
                    for i in range((len(v) + n - 1) // n)
                ]
                for chunk in chunks:
                    await ctx.send("__{}__\n{}".format(k, "\n".join(chunk)))
            _urls = []
            for r, s in urls.items():
                _urls.append(url.format(r, ",".join(s)))
            await ctx.send("\n\n".join(_urls))
        else:
            await ctx.respond(f"No Systems with ADM below {adm}!")

        return True
Exemplo n.º 26
0
    async def sov(self, ctx, name_search: Option(
        str, description="String to search against the sov database.")):
        """
        Sov Details for region/constelation/system/alliance
        """
        if ctx.channel.id not in settings.SOV_DISCORD_BOT_CHANNELS:
            return await ctx.respond(
                f"You do not have permission to use this command here.",
                ephemeral=True)

        await ctx.defer()

        name_ids = providers.esi.client.Search.get_search(
            categories=['constellation', 'solar_system', 'region', 'alliance'],
            search=name_search).result()

        hit_ids = {
            "a": name_ids.get("alliance") or [],
            "c": name_ids.get("constellation") or [],
            "s": name_ids.get("solar_system") or [],
            "r": name_ids.get("region") or [],
        }

        for r in hit_ids['r']:
            constellations = providers.esi.client.Universe.get_universe_regions_region_id(
                region_id=r).result()["constellations"]
            for c in constellations:
                if c not in hit_ids["c"]:
                    hit_ids["c"].append(c)

        for c in hit_ids['c']:
            systems = providers.esi.client.Universe.get_universe_constellations_constellation_id(
                constellation_id=c).result()["systems"]
            for s in systems:
                if s not in hit_ids["s"]:
                    hit_ids["s"].append(s)

        sov_structures = providers.esi.client.Sovereignty.get_sovereignty_structures(
        ).result()

        hits = []
        names = []
        alliances = []

        for s in sov_structures:
            start = s.get('vulnerable_start_time', False)
            if start:
                if s.get('solar_system_id') in hit_ids["s"] or s.get(
                        'alliance_id') in hit_ids["a"]:
                    alliances.append(s.get('alliance_id'))
                    names.append(s.get('solar_system_id'))
                    names.append(s.get('structure_type_id'))
                    hits.append(s)

        if len(names) == 0:
            await ctx.respond(
                ":sad: Nothing found for '{}'".format(name_search))
            return True

        names_alli = {}
        for a in set(alliances):
            res = providers.esi.client.Alliance.get_alliances_alliance_id(
                alliance_id=a).result()
            names_alli[a] = res.get("ticker")

        names = providers.esi.client.Universe.post_universe_names(
            ids=list(set(names))).result()

        nms = {}
        for n in names:
            nms[n.get("id")] = n.get("name")

        for hit in hits:
            hit['system_name'] = nms[hit.get('solar_system_id')]
            if hit.get("structure_type_id") == 32226:
                hit['structure'] = "TCU"
            elif hit.get("structure_type_id") == 32458:
                hit['structure'] = "IHUB"
            else:
                hit['structure'] = "¯\\_(ツ)_/¯"

            hit['alliance_name'] = names_alli[hit.get('alliance_id')]

        output = []
        base_str = "**{}** {} (ADM {})[**{}**] Vulnerable{}"
        dt_now = pendulum.now(tz="UTC")
        for h in sorted(hits, key=lambda k: k['vulnerable_start_time']):
            time = ""
            time = " for **{}**".format(
                pendulum.now(tz="UTC").diff_for_humans(
                    h['vulnerable_end_time'], absolute=True))

            if h['vulnerable_start_time']:
                if h['vulnerable_start_time'] > dt_now:
                    time = " in **{}**".format(
                        pendulum.now(tz="UTC").diff_for_humans(
                            h['vulnerable_start_time'], absolute=True))
            output.append(
                base_str.format(h['system_name'], h['structure'],
                                h['vulnerability_occupancy_level'],
                                h['alliance_name'], time))

        n = 15
        chunks = [
            list(output[i * n:(i + 1) * n])
            for i in range((len(output) + n - 1) // n)
        ]
        overflow = ""
        if len(output) > 50:
            overflow = "Only showing first 50..."

        await ctx.respond("Found {} Sov structures for `{}`\n{}\n".format(
            len(output), name_search, overflow))

        for c in chunks[:5]:
            await ctx.send("\n".join(c))
Exemplo n.º 27
0
    # noinspection PyMethodOverriding
    @staticmethod
    async def convert(converter, ctx: MrvnCommandContext, argument: str) -> Union[SlashCommand, SlashCommandGroup]:
        try:
            command = next(filter(lambda it: it.name == argument, runtime.bot.application_commands))
        except StopIteration:
            raise ArgumentParseException(ctx.translate("std_command_override_command_not_found"))

        return command


async def command_searcher(ctx: AutocompleteContext):
    return command_names


command_option = Option(str, autocomplete=basic_autocomplete(command_searcher))
command_option.converter = CommandConverter()


@event_handler()
async def startup():
    global command_names

    command_names = set(
        [cmd.name for cmd in runtime.bot.application_commands if isinstance(cmd, (SlashCommand, SlashCommandGroup))])


@override_group.command(description=Translatable("std_command_override_info_desc"))
async def info(ctx: MrvnCommandContext, command: command_option):
    override = await CommandOverride.get_or_none(guild_id=ctx.guild_id, command_name=command.name)
Exemplo n.º 28
0
 async def save_macro(self, ctx,
                      name: Option(str, 'Name of the macro. Letters and spaces only.'),
                      rolls: Option(str, 'The dice to roll. Separate with a comma. Modifiers allowed.')
                      ):
     await ctx.respond(save_command(name, rolls, ctx.user), ephemeral=True)
Exemplo n.º 29
0
async def giveaway(ctx,
                   prize: Option(str),
                   winners: Option(int, required=True),
                   duration: Option(str, required=True),
                   url: Option(str) = "",
                   image: Option(str) = ""):
    if discord.utils.get(bot.get_guild(server).roles,
                         name="Admin") in ctx.author.roles:
        winners = int(winners)
        if winners > 1:
            description = '''
            Click the :tada: to be entered into a giveaway!
            There are %d winners!
            ''' % winners
        elif winners == 1:
            description = '''
            Click the :tada: to be entered into a giveaway!
            There is %d winner!
            ''' % winners
        else:
            await ctx.send(content="ERROR! Must have at least 1 winner!")
            return

        days, hours, minutes = [
            int(x) if x else 0 for x in re.match(
                '(?:(\d+)d)?(?:(\d+)h)?(?:(\d+)m)?', duration).groups()
        ]

        epoch_time = calendar.timegm(time.gmtime())

        duration_in_seconds = (int(days) * 24 * 60 * 60) + (
            int(hours) * 60 * 60) + (int(minutes) * 60)

        if duration_in_seconds < 60:
            await ctx.send(content="ERROR! Must be at least a minute long!")
            return

        giveaway_ends_in_seconds = epoch_time + duration_in_seconds
        giveaway_ends_in_date = time.strftime(
            "%b %dth", time.localtime(giveaway_ends_in_seconds))
        giveaway_ends_in_time = time.strftime(
            "%I:%M%p", time.localtime(giveaway_ends_in_seconds))

        footer = '''
        Giveaway ends on %s at %s.
        ''' % (giveaway_ends_in_date, giveaway_ends_in_time)

        url = url if url else ""
        image = image if image else ""

        embed = create_embed(title=":partying_face: GIVEAWAY :partying_face:",
                             description=description,
                             color=discord.Color.red(),
                             footer=footer,
                             image=image,
                             author=prize,
                             author_url=url)

        msg = await ctx.respond(embed=embed)
        await msg.add_reaction("🎉")

        giveaway_messages.append(msg)

        giveaways[prize] = []
        await countdown_giveaway(time_in_seconds=duration_in_seconds,
                                 giveaway_message=msg,
                                 prize=prize,
                                 winners_amount=winners)
    else:
        await ctx.send(
            content="You do not have permission to create a giveaway!")
Exemplo n.º 30
0
    async def weather(self, ctx, location: Option(
        str, "Location (country, city, address, etc)", required=False)):
        if not location:
            result = await self.locations.find_one({'_id': ctx.author.id})
            if not result:
                await ctx.respond('No location specified and no location saved'
                                  )
                return

            latitude = result['lat']
            longitude = result['long']
            address = result['addr']

        else:
            geoloc = self.geolocator.geocode(location)
            if not geoloc:
                await ctx.respond('Unknown location')
                return

            latitude = geoloc.latitude
            longitude = geoloc.longitude
            address = geoloc.address

        url = "https://data.climacell.co/v4/timelines"
        querystring = {"apikey": self.api_key}
        headers = {"Content-Type": "application/json"}
        payload = {
            "fields": [
                "temperature", "humidity", "windSpeed", "weatherCode",
                "sunsetTime", "sunriseTime"
            ],
            "timesteps": ["1h", "1d"],
            "location":
            f"{latitude}, {longitude}"
        }

        async with self.session.post(url,
                                     json=payload,
                                     headers=headers,
                                     params=querystring) as r:
            data = await r.json()
            sunset = data['data']['timelines'][1]['intervals'][0]['values'][
                'sunsetTime']
            sunrise = data['data']['timelines'][1]['intervals'][0]['values'][
                'sunriseTime']
            # print(f'sun rises at {arrow.get(sunrise).humanize()}')  # TODO: wtf these are wrong?
            # print(f'sun sets at {arrow.get(sunset).humanize()}')

            now_field = ''
            forecast_field = ''

            num_rows = 4
            hour_gap = 2
            for i in range(0, num_rows * hour_gap, hour_gap):

                temp = data['data']['timelines'][0]['intervals'][i]['values'][
                    'temperature']
                temp_f = self.celsius_to_fahrenheit(temp)
                weather_code = data['data']['timelines'][0]['intervals'][i][
                    'values']['weatherCode']
                time = data['data']['timelines'][0]['intervals'][i][
                    'startTime']
                is_night = sunset < time < sunrise

                weather_icon = self.get_emote_str_from_weather_code(
                    weather_code, night=is_night)

                if i == 0:  # Now
                    humidity = data['data']['timelines'][0]['intervals'][i][
                        'values']['humidity']
                    wind = data['data']['timelines'][0]['intervals'][i][
                        'values']['windSpeed'] * 3.6
                    now_field = f"""
                                {weather_icon} **{round(temp)}**°C / **{round(temp_f)}**°F 
                                💧 **{humidity}**%
                                🍃 **{round(wind)}** km/h"""
                else:
                    hours_from_now = arrow.get(time).humanize()
                    forecast_field += f'{weather_icon} **{round(temp)}**°C / **{round(temp_f)}**°F - {hours_from_now}\n'

            embed = discord.Embed(color=0x7fffd4)
            embed.add_field(inline=True, name='Now', value=now_field)
            embed.add_field(inline=True, name='Forecast', value=forecast_field)
            embed.set_footer(text=address)
            await ctx.respond(embed=embed)