Esempio n. 1
0
    async def on_guild_join(guild):
        #Creates new settings entry for guild
        Sudo.server_settings_check(hex(guild.id), bot)
        Sudo.save_configs(bot)

        owner = await bot.fetch_user(guild.owner_id)
        dm = await owner.create_dm()
        try:
            embed = Embed(
                title=f"Search.io was added to your server: '{guild.name}'.",
                description=f"""
            Search.io is a bot that searches through multiple search engines/APIs.
            The activation command is `&`, and a list of various commands can be found using `&help`.
            
            • A list of admin commands can be found by using `&help sudo`. These commands may need ID numbers, which requires Developer Mode.
            • To turn on Developer Mode, go to Settings > Appearances > Advanced > Developer Mode. Then right click on users, roles, channels, or guilds to copy their ID.

            • Guild-specific settings can be accessed with `&config`
            • As a start, it is suggested to designate an administrator role that can use Search.io's sudo commands. Do `&config adminrole [roleID]` to designate an admin role.
            • You can change the command prefix with `&config prefix [character]`
            • You can also block or unblock specific commands with `&config [command]`
            • It is also suggested to turn on Safe Search, if needed. Do `&config safesearch on`. 

            • If you need to block a specific user from using Search.io, do `&sudo blacklist [userID]`. 
            • Unblock with `&sudo whitelist [userID]`

            If you have any problems with Search.io, join the help server: https://discord.gg/YB8VGYMZSQ"""
            )
            await dm.send(embed=embed)

        except discord_error.Forbidden:
            pass
        finally:
            return
Esempio n. 2
0
async def on_guild_join(guild):
    #Reads settings of server
    Sudo.settingsCheck(serverSettings, guild.id)

    owner = await bot.fetch_user(guild.owner_id)
    dm = await owner.create_dm()
    appInfo = await bot.application_info()

    embed = discord.Embed(title=f"Search.io was added to your server: '{guild.name}'.", 
        description = f"""
    Search.io is a bot that searches through multiple search engines/APIs.
    The activation command is '&', and a list of various commands can be found using '&help'.
            
    A list of admin commands can be found by using '&help sudo'. These commands may need ID numbers, which requires Developer Mode.
    To turn on Developer Mode, go to Settings > Appearances > Advanced > Developer Mode. Then right click on users, roles, channels, or guilds to copy their ID.
    If you need to block a specific user from using Search.io, do '&sudo blacklist [userID]'. Unblock with '&sudo whitelist [userID]'

    Guild-specific settings can be accessed with '&config'
    As a start, it is suggested to designate an administrator role that can use Search.io's sudo commands. Do '&config adminrole [roleID]' to designate an admin role.
    You can change the command prefix with '&config prefix [character]'
    You can also block or unblock specific commands with '&config [command]'
    It is also suggested to turn on Safe Search, if needed. Do '&config safesearch'. The default is off. 

    If you have any problems with Search.io, DM {str(appInfo.owner)}""")
    await dm.send(embed=embed)
    return
Esempio n. 3
0
    async def on_connect():
        t0 = time()
        DiscordComponents(bot)

        bot.load_extension('src.cogs.search_engine_cog')
        bot.load_extension('src.cogs.administration_cog')
        bot.load_extension('src.cogs.administration_slashcog')
        bot.load_extension('src.cogs.search_engine_slashcog')

        auto_save.start()
        cache_clear.start()

        #add new servers to settings
        for servers in bot.guilds:
            bot.serverSettings = Sudo.server_settings_check(servers.id, bot)

        #sets bot globals
        bot.devmode = False

        #remove old servers from settings
        delete_queue = []
        guild_list = [g.id for g in bot.guilds]
        for keys in bot.serverSettings.keys():
            if int(keys, 0) not in guild_list:
                delete_queue.append(keys)

        for keys in delete_queue:
            del bot.serverSettings[keys]

        Sudo.save_configs(bot)

        with open("logs.csv", "r", newline='', encoding='utf-8-sig') as file:
            lines = [
                dict(row) for row in DictReader(file)
                if datetime.now(timezone.utc) -
                datetime.fromisoformat(row["Time"]) < timedelta(weeks=8)
            ]

        with open("logs.csv", "w", newline='', encoding='utf-8-sig') as file:
            logFieldnames = [
                "Time", "Guild", "User", "User_Plaintext", "Command", "Args"
            ]
            writer = DictWriter(file,
                                fieldnames=logFieldnames,
                                extrasaction='ignore')
            writer.writeheader()
            writer.writerows(lines)

        bot.session = ClientSession()

        bot.botuser = await bot.application_info()
        await bot.change_presence(activity=Activity(
            type=ActivityType.listening, name="command prefix '&'"))
        t1 = time()
        print(f"Bot alive. Took {t1-t0:.3f}s")
        return
Esempio n. 4
0
    async def config(self, ctx, *args):
        args = list(args)
        global serverSettings
        command = Sudo(bot, ctx, serverSettings)
        if Sudo.isSudoer(bot, ctx, serverSettings) == True:
            await command.config(args)
        else: await command.config([])

        with open('serverSettings.json', 'r') as data:
            serverSettings = json.load(data, object_hook=lambda d: {int(k) if k.isdigit() else k: v for k, v in d.items()})
        return
Esempio n. 5
0
    async def sudo(self, ctx, *args):
        global serverSettings
        args = list(args)
        if Sudo.isSudoer(bot, ctx, serverSettings) == False:
            await ctx.send(f"{ctx.author} is not in the sudoers file.  This incident will be reported.")
            Log.appendToLog(ctx, 'sudo', 'unauthorised')
        else:
            Log.appendToLog(ctx, "sudo", ' '.join(args).strip())
            command = Sudo(bot, ctx, serverSettings)
            await command.sudo(args)

        with open('serverSettings.json', 'r') as data:
            serverSettings = json.load(data, object_hook=lambda d: {int(k) if k.isdigit() else k: v for k, v in d.items()})
        return
Esempio n. 6
0
    async def sudo(self, ctx, *args):

        if Sudo.is_sudoer(self.bot, ctx):
            Log.append_to_log(ctx, None, args)
            command = Sudo(self.bot, ctx)

            self.bot.serverSettings, self.bot.userSettings = await command.sudo(
                list(args))
            Sudo.save_configs(self.bot)
        else:
            await ctx.send(
                f"`{ctx.author}` is not in the sudoers file.  This incident will be reported."
            )
            Log.append_to_log(ctx, None, 'unauthorised')
        return
Esempio n. 7
0
    async def config(self, ctx, *args):
        args = list(args)

        command = Sudo(self.bot, ctx)
        if len(args) > 0:
            localSetting = args[0] in ['locale', 'alias']
        else:
            localSetting = False

        if Sudo.is_sudoer(self.bot, ctx) or localSetting:
            self.bot.serverSettings, self.bot.userSettings = await command.config(
                args)

        else:
            self.bot.serverSettings, self.bot.userSettings = await command.config(
                [])
        Sudo.save_configs(self.bot)
        Log.append_to_log(ctx)
Esempio n. 8
0
    async def cog_before_invoke(self, ctx):
        if Sudo.is_authorized_command(self.bot, ctx):
            old_userSettings = deepcopy(self.bot.userSettings)
            self.bot.userSettings = Sudo.user_settings_check(
                self.bot.userSettings, ctx.author.id)
            if old_userSettings != self.bot.userSettings:
                Sudo.save_configs(self.bot)

            #Leveling system
            self.bot.userSettings[ctx.author.id]['level']['xp'] += 1
            if self.bot.userSettings[
                    ctx.author.id]['level']['xp'] >= self.bot.userSettings[
                        ctx.author.id]['level']['rank'] * 10:
                self.bot.userSettings[ctx.author.id]['level']['xp'] = 0
                self.bot.userSettings[ctx.author.id]['level']['rank'] += 1

                Sudo.save_configs(self.bot)

                await ctx.send(embed=Embed(
                    description=
                    f"Congratulations {ctx.author}, you are now level {self.bot.userSettings[ctx.author.id]['level']['rank']}"
                ))

            # if ctx.command.name == 's' and self.bot.userSettings[ctx.author.id]['searchAlias'] is not None:
            #     Log.append_to_log(ctx, self.bot.userSettings[ctx.author.id]['searchAlias'])
            # elif ctx.command.name == 's':
            #     Log.append_to_log(ctx, 's', 'Not set')
            # else:
            Log.append_to_log(ctx)
            return
Esempio n. 9
0
async def on_connect():
    global serverSettings
    await bot.change_presence(activity=discord.Activity(type=discord.ActivityType.listening, name="command prefix '&'"))

    appInfo = await bot.application_info()
    bot.owner_id = appInfo.owner.id

    for servers in bot.guilds:
        serverSettings = Sudo.settingsCheck(serverSettings, servers.id)
    
    with open('serverSettings.json', 'w') as data:
        data.write(json.dumps(serverSettings, indent=4))
    return
Esempio n. 10
0
    async def finance(self, ctx, *args):
        args = list(args)
        if args[0] == 'help' or len(args) == 1:
            if len(args) == 1:
                helpmessage = Embed(title='finance',
                                    description=ctx.command.help)

            elif args[1] == 'stock':
                helpmessage = Embed(title='Stock',
                                    description="""
                finance stock [ticker] [range] [interval] [display] [moving average values]
                
                Ex: finance stock AAPL 1y 1d candle 2 3 5
                Example creates a candle chart displaying 1 year of AAPL with 1 day data points and MAV lines of 2, 3, and 5 days.
                """)
                helpmessage.add_field(name='ticker', value='Symbol')
                helpmessage.add_field(name='range',
                                      value='Length of time for data')
                helpmessage.add_field(name='interval',
                                      value='Time between data points')
                helpmessage.add_field(name='display', value='candle OR line')
                helpmessage.add_field(
                    name='moving average values',
                    value='number of days for a simple moving average line')

            await ctx.send(embed=helpmessage)
            try:
                resp = await self.bot.wait_for(
                    "button_click",
                    check=lambda b_ctx: Sudo.pageTurnCheck(bot=self.bot,
                                                           ctx=ctx,
                                                           button_ctx=b_ctx,
                                                           message=helpmessage
                                                           ),
                    timeout=60)

                if str(resp.custom_id) == "🗑️":
                    await helpmessage.delete()
                    return

            except TimeoutError:
                await helpmessage.edit(components=[])
                return
        else:
            await self.genericSearch(ctx, FinancialSearch, args)
Esempio n. 11
0
    async def __call__(self):

        UserCancel = KeyboardInterrupt

        def search_pages(result_) -> discord.Embed:
            return discord.Embed(
                title=f"Titles matching '{self.query}'",
                description="\n".join([
                    f"[{index_}]: {value.title}"
                    for index_, value in enumerate(result_)
                ]),
            )

        try:
            errorMessage = None
            search = AnimeSearch(self.query)

            while 1:
                result = [
                    [anime for anime in search.results][x:x + 10]
                    for x in range(0, len([anime
                                           for anime in search.results]), 10)
                ]
                embeds = list(map(search_pages, result))
                cur_page = 0

                for index, item in enumerate(embeds):
                    item.set_footer(
                        text=
                        f"Please choose option or cancel\nPage {index+1}/{len(embeds)}"
                    )

                if len(embeds) > 1:
                    emojis = ["🗑️", "◀️", "▶️"]
                else:
                    emojis = ["🗑️"]

                await self.message.edit(content='',
                                        embed=embeds[cur_page % len(embeds)],
                                        components=[[
                                            Button(style=ButtonStyle.blue,
                                                   label=e,
                                                   custom_id=e) for e in emojis
                                        ]])

                while 1:
                    try:
                        emojitask = asyncio.create_task(
                            self.bot.wait_for(
                                "button_click",
                                check=lambda b_ctx: Sudo.pageTurnCheck(
                                    bot=self.bot,
                                    ctx=self.ctx,
                                    button_ctx=b_ctx,
                                    message=self.message),
                                timeout=60,
                            ))

                        responsetask = asyncio.create_task(
                            self.bot.wait_for(
                                "message",
                                check=lambda m: m.author == self.ctx.author,
                                timeout=30,
                            ))

                        waiting = [emojitask, responsetask]
                        done, waiting = await asyncio.wait(
                            waiting, return_when=asyncio.FIRST_COMPLETED
                        )  # 30 seconds wait either reply or react

                        if emojitask in done:
                            emojitask = emojitask.result()

                            if str(emojitask.custom_id) == "🗑️":
                                await self.message.delete()
                                return
                            elif str(emojitask.custom_id) == "◀️":
                                cur_page -= 1
                            elif str(emojitask.custom_id) == "▶️":
                                cur_page += 1

                            await emojitask.respond(type=7,
                                                    content='',
                                                    embed=embeds[cur_page %
                                                                 len(embeds)])

                        elif responsetask in done:
                            try:
                                emojitask.cancel()
                                input = responsetask.result()
                                await input.delete()
                                if input.content.lower() == "cancel":
                                    raise UserCancel
                                input = int(input.content)
                                anime_item = result[cur_page][input]

                                if errorMessage is not None:
                                    await errorMessage.delete()

                                embed = discord.Embed(
                                    title=f"{anime_item.title}",
                                    description=anime_item.synopsis,
                                    url=anime_item.url,
                                )  # Myanimelist data

                                embed.add_field(
                                    name="MyAnimeListID",
                                    value=str(anime_item.mal_id),
                                    inline=True,
                                )
                                embed.add_field(
                                    name="Rating",
                                    value=str(anime_item.score),
                                    inline=True,
                                )
                                embed.add_field(
                                    name="Episodes",
                                    value=str(anime_item.episodes),
                                    inline=True,
                                )

                                embed.set_thumbnail(url=anime_item.image_url)
                                embed.set_footer(
                                    text=f"Requested by {self.ctx.author}")

                                Log.append_to_log(
                                    self.ctx, f"{self.ctx.command} result",
                                    anime_item.title)
                                await self.message.edit(
                                    embed=embed,
                                    components=[
                                        Button(style=ButtonStyle.blue,
                                               label="🗑️",
                                               custom_id="🗑️")
                                    ])
                                await self.bot.wait_for(
                                    "button_click",
                                    check=lambda button_ctx: Sudo.
                                    pageTurnCheck(bot=self.bot,
                                                  ctx=self.ctx,
                                                  button_ctx=button_ctx,
                                                  message=self.message),
                                    timeout=60,
                                )
                                return

                            except (ValueError, IndexError):
                                errorMessage = await self.ctx.send(
                                    content=
                                    "Invalid choice. Please choose a number between 0-9 or cancel"
                                )
                                continue

                            except asyncio.TimeoutError:
                                await self.message.edit(components=[])
                                return

                    except UserCancel:
                        await self.message.delete()

                    except asyncio.TimeoutError:
                        await self.message.delete()

                    except (asyncio.CancelledError, discord.errors.NotFound):
                        pass

                    except Exception:
                        await self.message.delete()
                        raise

        except Exception as e:
            await error_handler(self.bot, self.ctx, e, self.query)
        finally:
            return
Esempio n. 12
0
 async def cog_before_invoke(self, ctx):
     self.bot.userSettings = Sudo.user_settings_check(
         self.bot.userSettings, ctx.author.id)
     Sudo.save_configs(self.bot)
     return
Esempio n. 13
0
    async def genericSearch(self,
                            ctx,
                            searchObject,
                            query: str,
                            optionals: str = None):
        if Sudo.is_authorized_command(self.bot, ctx):
            old_userSettings = deepcopy(self.bot.userSettings)
            self.bot.userSettings = Sudo.user_settings_check(
                self.bot.userSettings, ctx.author.id)
            if old_userSettings != self.bot.userSettings:
                Sudo.save_configs(self.bot)

            #Leveling system
            self.bot.userSettings[ctx.author.id]['level']['xp'] += 1
            if self.bot.userSettings[
                    ctx.author.id]['level']['xp'] >= self.bot.userSettings[
                        ctx.author.id]['level']['rank'] * 10:
                self.bot.userSettings[ctx.author.id]['level']['xp'] = 0
                self.bot.userSettings[ctx.author.id]['level']['rank'] += 1

                Sudo.save_configs(self.bot)

                await ctx.send(embed=Embed(
                    description=
                    f"Congratulations {ctx.author}, you are now level {self.bot.userSettings[ctx.author.id]['level']['rank']}"
                ))

            # if ctx.command.name == 's' and self.bot.userSettings[ctx.author.id]['searchAlias'] is not None:
            #     Log.append_to_log(ctx, self.bot.userSettings[ctx.author.id]['searchAlias'])
            # elif ctx.command.name == 's':
            #     Log.append_to_log(ctx, 's', 'Not set')
            # else:
            Log.append_to_log(ctx)

            #allows users to edit their search query after results are returned
            continueLoop = True
            while continueLoop:
                try:
                    message = await ctx.send(content=get_loading_message())
                    messageEdit = create_task(
                        self.bot.wait_for('message_edit',
                                          check=lambda var, m: m.author == ctx.
                                          author and m == ctx.message))

                    search = create_task(
                        searchObject(
                            bot=self.bot,
                            ctx=ctx,
                            server_settings=self.bot.serverSettings,
                            user_settings=self.bot.userSettings,
                            message=message,
                            args=optionals.split(' ')
                            if optionals is not None else [],
                            query=query,
                        )())

                    #checks for message edit
                    waiting = [messageEdit, search]
                    done, waiting = await wait(
                        waiting, return_when=asyncio.FIRST_COMPLETED)

                    if messageEdit in done:  #if the message is edited, the search is cancelled, message deleted, and command is restarted
                        if type(messageEdit.exception()) == TimeoutError:
                            raise TimeoutError
                        await message.delete()
                        messageEdit.cancel()
                        search.cancel()

                        messageEdit = messageEdit.result()
                        userquery = messageEdit[1].content.replace(
                            f'{Sudo.print_prefix(self.bot.serverSettings, ctx)}{ctx.invoked_with} ',
                            '')  #finds the new user query
                        continue
                    else:
                        raise TimeoutError

                except TimeoutError:  #after a minute, everything cancels
                    await message.edit(components=[])
                    messageEdit.cancel()
                    search.cancel()
                    continueLoop = False
                    return

                except Exception as e:
                    await error_handler(self.bot, ctx, e, userquery)
                    return
Esempio n. 14
0
 async def auto_save():
     Sudo.save_configs(bot)
     return
Esempio n. 15
0
    async def help(ctx, *args):
        try:

            def check(reaction, user):
                return user == ctx.author and str(reaction.emoji) in ["🗑️"]

            commandPrefix = Sudo.print_prefix(bot.serverSettings, ctx)
            searchEngineCog = dict(bot.cogs)['Search Engines']
            adminCog = dict(bot.cogs)['Administration']

            maxAdminCommandStrLength = len(
                max([command.name for command in adminCog.get_commands()],
                    key=len))
            args = list(args)

            embed = Embed(
                title="SearchIO",
                description=
                "Search.io is a bot that searches through multiple search engines/APIs.\nIt is developed by ACEslava#1984, K1NG#6219, and Nanu#3294"
            )

            embed.add_field(
                name="Administration",
                inline=False,
                value="\n".join([
                    f'`{command.name:>{maxAdminCommandStrLength}}:` {command.brief}'
                    for command in adminCog.get_commands()
                ]))

            embed.add_field(
                name="Search Engines",
                inline=False,
                value='\n'.join([
                    f"`{command.name:>10}:` {command.brief}"
                    for command in searchEngineCog.get_commands()
                    if command.enabled is True and bot.serverSettings[hex(
                        ctx.guild.id)]['searchEngines'][command.name] is True
                ]))

            embed.set_footer(
                text=f"Do {commandPrefix}help [command] for more information")

            if args:
                try:
                    command = getattr(searchEngineCog, args[0].lower())
                except AttributeError:
                    try:
                        command = getattr(adminCog, args[0].lower())
                    except AttributeError:
                        command = None

                if command is not None:
                    embed = Embed(title=command.name,
                                  description=f"""
                        {command.help}
                        Usage:
                        ```{command.usage}```
                        {'Optionals:```'+command.description+'```' if command.description != '' else ''}"""
                                  )
                    embed.set_footer(text=f"Requested by {ctx.author}")
                    helpMessage = await ctx.send(embed=embed)
                    try:
                        await helpMessage.add_reaction('🗑️')
                        reaction, _ = await bot.wait_for("reaction_add",
                                                         check=check,
                                                         timeout=60)
                        if str(reaction.emoji) == '🗑️':
                            await helpMessage.delete()
                            return

                    except TimeoutError as e:
                        await helpMessage.clear_reactions()
                else:
                    pass
            else:
                invite_link = discord_utils.oauth_url(
                    client_id=bot.botuser.id,
                    permissions=Permissions(4228381776),
                    scopes=['bot', 'applications.commands'])
                dm = await ctx.author.create_dm()
                await dm.send(embed=embed)
                await dm.send('\n'.join([
                    'If you have further questions, feel free to join the support server: https://discord.gg/YB8VGYMZSQ',
                    f'Want to add the bot to your server? Use this invite link: {invite_link}'
                ]))

        except discord_error.Forbidden:
            await ctx.send(embed=Embed(
                description=
                'Sorry, I cannot open a DM at this time. Please check your privacy settings'
            ))

        except Exception as e:
            await error_handler(bot, ctx, e)
        finally:
            return
Esempio n. 16
0
    async def genericSearch(self, ctx: commands.context, searchObject,
                            args: list) -> None:
        '''A generic search handler for bot search functions.
        
        Args:
            ctx: discord.commands.context
            searchObject: function
            args: list
        
        Raises:
            None
        
        Returns:
            None
        '''
        if Sudo.is_authorized_command(self.bot, ctx):
            # region args parsing
            UserCancel = KeyboardInterrupt
            if not args:  #checks if search is empty
                await ctx.send("Enter search query or cancel"
                               )  #if empty, asks user for search query
                try:
                    userquery = await self.bot.wait_for(
                        'message',
                        check=lambda m: m.author == ctx.author,
                        timeout=30)  # 30 seconds to reply
                    if userquery.content.lower() == 'cancel': raise UserCancel
                    else: userquery = userquery.content.split('--')

                except TimeoutError:
                    await ctx.send(
                        f'{ctx.author.mention} Error: You took too long. Aborting'
                    )  #aborts if timeout

                except UserCancel:
                    await ctx.send('Aborting')
                    return
            else:
                userquery = ' '.join([
                    query.strip() for query in list(args)
                ]).split('--')  #turns multiword search into single string.

            if len(userquery) > 1:
                args = userquery[1:]
            else:
                args = None

            userquery = userquery[0]
            #check if user actually searched something
            if userquery is None: return
            #endregion

            #allows users to edit their search query after results are returned
            continueLoop = True
            while continueLoop:
                try:
                    message = await ctx.send(get_loading_message())
                    messageEdit = create_task(
                        self.bot.wait_for('message_edit',
                                          check=lambda var, m: m.author == ctx.
                                          author and m == ctx.message))

                    search = create_task(
                        searchObject(
                            bot=self.bot,
                            ctx=ctx,
                            server_settings=self.bot.serverSettings,
                            user_settings=self.bot.userSettings,
                            message=message,
                            args=args,
                            query=userquery,
                        )())

                    #checks for message edit
                    waiting = [messageEdit, search]
                    done, waiting = await wait(
                        waiting, return_when=asyncio.FIRST_COMPLETED)

                    if messageEdit in done:  #if the message is edited, the search is cancelled, message deleted, and command is restarted
                        if type(messageEdit.exception()) == TimeoutError:
                            raise TimeoutError
                        await message.delete()
                        messageEdit.cancel()
                        search.cancel()

                        messageEdit = messageEdit.result()
                        userquery = messageEdit[1].content.replace(
                            f'{Sudo.print_prefix(self.bot.serverSettings, ctx)}{ctx.invoked_with} ',
                            '')  #finds the new user query
                        continue
                    else:
                        raise TimeoutError

                except TimeoutError:  #after a minute, everything cancels
                    await message.clear_reactions()
                    messageEdit.cancel()
                    search.cancel()
                    continueLoop = False
                    return

                except Exception as e:
                    await error_handler(self.bot, ctx, e, userquery)
                    return
        return
Esempio n. 17
0
    async def __call__(self):
        UserCancel = KeyboardInterrupt

        if self.args is None:
            Wikipedia.set_lang("en")
        elif any("lang" in i for i in self.args):
            language = self.args[[
                idx for idx, s in enumerate(self.args) if "lang" in s
            ][0]].replace("lang ", "")
            Wikipedia.set_lang(language)

        def search_pages(result_) -> discord.Embed:
            return discord.Embed(
                title=f"Titles matching '{self.query}'",
                description="\n".join([
                    f"[{index_}]: {value}"
                    for index_, value in enumerate(result_)
                ]),
            )

        try:
            errorMessage = None
            result = Wikipedia.search(self.query)

            while 1:
                result = [result[x:x + 10] for x in range(0, len(result), 10)]
                embeds = list(map(search_pages, result))
                cur_page = 0

                for index, item in enumerate(embeds):
                    item.set_footer(
                        text=
                        f"Please choose option or cancel\nPage {index+1}/{len(embeds)}"
                    )

                if len(embeds) > 1:
                    emojis = ["🗑️", "◀️", "▶️"]
                else:
                    emojis = ["🗑️"]

                await self.message.edit(content='',
                                        embed=embeds[cur_page % len(embeds)],
                                        components=[[
                                            Button(style=ButtonStyle.blue,
                                                   label=e,
                                                   custom_id=e) for e in emojis
                                        ]])

                while 1:
                    try:
                        emojitask = asyncio.create_task(
                            self.bot.wait_for(
                                "button_click",
                                check=lambda b_ctx: Sudo.pageTurnCheck(
                                    bot=self.bot,
                                    ctx=self.ctx,
                                    button_ctx=b_ctx,
                                    message=self.message),
                                timeout=60,
                            ))

                        responsetask = asyncio.create_task(
                            self.bot.wait_for(
                                "message",
                                check=lambda m: m.author == self.ctx.author,
                                timeout=30,
                            ))

                        waiting = [emojitask, responsetask]
                        done, waiting = await asyncio.wait(
                            waiting, return_when=asyncio.FIRST_COMPLETED
                        )  # 30 seconds wait either reply or react

                        if emojitask in done:
                            emojitask = emojitask.result()

                            if str(emojitask.custom_id) == "🗑️":
                                await self.message.delete()
                                return
                            elif str(emojitask.custom_id) == "◀️":
                                cur_page -= 1
                            elif str(emojitask.custom_id) == "▶️":
                                cur_page += 1

                            await emojitask.respond(type=7,
                                                    content='',
                                                    embed=embeds[cur_page %
                                                                 len(embeds)])

                        elif responsetask in done:
                            try:
                                emojitask.cancel()
                                input = responsetask.result()
                                await input.delete()
                                if input.content.lower() == "cancel":
                                    raise UserCancel

                                input = int(input.content)

                                if errorMessage is not None:
                                    await errorMessage.delete()

                                self.query = result[cur_page][input]
                                page = Wikipedia.WikipediaPage(
                                    title=self.query)
                                summary = page.summary[:page.summary.
                                                       find(". ") + 1]
                                embed = discord.Embed(
                                    title=
                                    f"Wikipedia Article: {page.original_title}",
                                    description=summary,
                                    url=page.url,
                                )  # outputs wikipedia article
                                embed.set_footer(
                                    text=f"Requested by {self.ctx.author}")

                                await self.message.edit(
                                    embed=embed,
                                    components=[
                                        Button(style=ButtonStyle.blue,
                                               label="🗑️",
                                               custom_id="🗑️")
                                    ])
                                await self.bot.wait_for(
                                    "button_click",
                                    check=lambda button_ctx: Sudo.
                                    pageTurnCheck(bot=self.bot,
                                                  ctx=self.ctx,
                                                  button_ctx=button_ctx,
                                                  message=self.message),
                                    timeout=60,
                                )
                                await self.message.delete()
                                return

                            except Wikipedia.DisambiguationError as e:
                                result = str(e).split("\n")
                                result.pop(0)
                                await self.message.edit(
                                    content=f"{get_loading_message()}",
                                    components=[])
                                break

                            except (ValueError, IndexError):
                                errorMessage = await self.ctx.send(
                                    "Invalid choice. Please choose a number between 0-9 or cancel"
                                )
                                continue

                            except asyncio.TimeoutError:
                                await self.message.edit(components=[])
                                return

                    except (UserCancel, asyncio.TimeoutError):
                        await self.message.delete()

                    except Exception:
                        raise

        except Exception as e:
            await error_handler(self.bot, self.ctx, e, self.query)
        finally:
            return
Esempio n. 18
0
async def help(ctx, *args):
    try:
        def check(reaction, user):
            return user == ctx.author and str(reaction.emoji) in ["ЁЯЧСя╕П"]
        commandPrefix = Sudo.printPrefix(ctx)
        args = list(args)
        
        embed = discord.Embed(title="Help", 
            description="Search.io is a bot that searches through multiple search engines/APIs.\nIt is developed by ACEslava#9735, K1NG#6219, and Nanu#3294")
        
        embed.add_field(name="Administration", inline=False, value=textwrap.dedent(f"""\
            `  sudo:` Various admin commands. Usage: {commandPrefix}sudo [command] [args].
            `  logs:` DMs a .csv of personal logs or guild logs if user is a sudoer. Usage: {commandPrefix}log
            `config:` Views the guild settings. Requires sudo privileges to edit settings
        """))
        
        embed.add_field(name="Search Engines", inline=False, value=textwrap.dedent(f"""\
            {"`wikipedia:` Search through Wikipedia." if serverSettings[ctx.guild.id]['wikipedia'] == True else ''}
            {"` wikilang:` Lists supported languages for Wikipedia's --lang flag" if serverSettings[ctx.guild.id]['wikipedia'] == True else ''}
            {"`   google:` Search through Google" if serverSettings[ctx.guild.id]['google'] == True else ''}
            {"`    image:` Google's Reverse Image Search with an image URL or image reply" if serverSettings[ctx.guild.id]['google'] == True else ''}
            {"`  scholar:` Search through Google Scholar" if serverSettings[ctx.guild.id]['scholar'] == True else ''}
            {"`  youtube:` Search through Youtube" if serverSettings[ctx.guild.id]['youtube'] == True else ''}
            {"`    anime:` Search through MyAnimeList" if serverSettings[ctx.guild.id]['mal'] == True else ''}
            {"`     xkcd:` Search for XKCD comics" if serverSettings[ctx.guild.id]['xkcd'] == True else ''}
        """))
        embed.set_footer(text=f"Do {commandPrefix}help [command] for more information")

        if args:
            if args[0] == 'sudo':
                embed = discord.Embed(title="Sudo", description=f"Admin commands. Server owner has sudo privilege by default.\nUsage: {commandPrefix}sudo [command] [args]")
                embed.add_field(name="Commands", inline=False, value=
                    f"""`     echo:` Have the bot say something. 
                        Args: message 
                        Optional flag: --channel [channelID]

                        `blacklist:` Block a user from using the bot. 
                        Args: userName OR userID 

                        `whitelist:` Unblock a user from using the bot. 
                        Args: userName OR userID

                        `   sudoer:` Add a user to the sudo list. Only guild owners can do this. 
                        Args: userName OR userID  

                        ` unsudoer:` Remove a user from the sudo list. Only guild owners can do this. 
                        Args: userName OR userID""")
            elif args[0] == 'log':
                embed = discord.Embed(title="Log", description=
                    f"DMs a .csv file of all the logs that the bot has for your username or guild if a sudoer.\nUsage: {commandPrefix}log")  
            elif args[0] == 'config':
                embed = discord.Embed(title="Guild Configuration", description=f"Views the guild configuration. Only sudoers can edit settings.\nUsage: {commandPrefix}config")
            elif args[0] == 'wiki':
                embed = discord.Embed(title="Wikipedia", description=f"Wikipedia search. \nUsage: {commandPrefix}wiki [query] [flags]")
                embed.add_field(name="Optional Flags", inline=False, value=
                    f"""`--lang [ISO Language Code]:` Specifies a country code to search through Wikipedia. Use {commandPrefix}wikilang to see available codes""")
            elif args[0] == 'wikilang':
                embed = discord.Embed(title="WikiLang", description=
                """Lists Wikipedia's supported wikis in ISO codes. Common language codes are:
                    zh: ф╕нцЦЗ
                    es: Espa├▒ol
                    en: English
                    pt: Portugu├кs
                    hi: рд╣рд┐рдиреНрджреА
                    bn: ржмрж╛ржВрж▓рж╛
                    ru: ╤А╤Г╤Б╤Б╨║╨╕╨╣""")
            elif args[0] == 'google':
                embed = discord.Embed(title="Google", description=
                    f"Google search.\nUsage: {commandPrefix}google [query].\nIf a keyword is detected in [query], a special function will activate")
                embed.add_field(name="Keywords", inline=False, value=
                """`translate:` Uses Google Translate API to translate languages. 
                Input automatically detects language unless specified with 'from [language]' 
                Defaults to output English unless specified with 'to [language]'
                Example Query: translate ┘Е╪▒╪н╪и╪з from arabic to spanish""")
            elif args[0] == 'image':
                embed = discord.Embed(title="Google Image", description=
                    f"Uses Google's Reverse Image search to output URLs that contain the image.\nUsage: {commandPrefix}image [imageURL] OR reply to an image in the chat")
            elif args[0] == 'scholar':
                embed = discord.Embed(title="GoogleScholar", description=
                    f"Google Scholar search. \nUsage: {commandPrefix}scholar [query] [flags].")
                embed.add_field(name="Flags", inline=False, value="""
                    `--author:` Use [query] to search for a specific author. Cannot be used with --cite
                    `  --cite:` Outputs a citation for [query] in BibTex. Cannot be used with --author""")        
            elif args[0] == 'youtube':
                embed = discord.Embed(title="Youtube", description=
                f"Searches through Youtube videos.\nUsage: {commandPrefix}youtube [query].")
            elif args[0] == 'anime':
                embed = discord.Embed(title="MyAnimeList", description=
                f"Searches through MyAnimeList\nUsage:{commandPrefix}anime [query]")
            elif args[0] == 'xkcd':
                embed = discord.Embed(title="XKCD", description=
                f"Searches for an XKCD comic\nUsage:{commandPrefix}anime [XKCD Comic #]")
            else: pass
        else: pass
        
        helpMessage = await ctx.send(embed=embed)
        try:
            await helpMessage.add_reaction('ЁЯЧСя╕П')
            reaction, user = await bot.wait_for("reaction_add", check=check, timeout=60)
            if str(reaction.emoji) == 'ЁЯЧСя╕П':
                await helpMessage.delete()
                return
        
        except asyncio.TimeoutError as e: 
            await helpMessage.clear_reactions()
        
        finally: 
            return
    
    except Exception as e:
        ErrorHandler(bot, ctx, e, 'help', '')