示例#1
0
 async def checkout(self, ctx, branch: str = "master"):
     """Checks out the requested branch.
     If no branch name is provided will checkout the master branch"""
     pag = Paginator(self.bot, max_line_length=44, max_lines=30, embed=True)
     branches_str = await asyncio.wait_for(
         self.bot.loop.create_task(run_command(f"git branch -a")), 120
     )
     existing_branches = [
         b.strip().split("/")[-1]
         for b in branches_str.replace("*", "").split("\n")[:-1]
     ]
     if branch not in existing_branches:
         pag.add(f"There is no existing branch named {branch}.")
         pag.set_embed_meta(
             title="Git Checkout",
             color=self.bot.error_color,
             thumbnail=f"{ctx.guild.me.avatar_url}",
         )
     else:
         pag.set_embed_meta(
             title="Git Checkout",
             color=self.bot.embed_color,
             thumbnail=f"{ctx.guild.me.avatar_url}",
         )
         result = await asyncio.wait_for(
             self.bot.loop.create_task(run_command(f"git checkout -f {branch}")), 120
         )
         pag.add(result)
     book = Book(pag, (None, ctx.channel, self.bot, ctx.message))
     await book.create_book()
示例#2
0
 async def os(self, ctx, *, body: str):
     if ctx.author.id != self.bot.owner_id:
         return
     try:
         body = self.cleanup_code(body)
         pag = Paginator(self.bot)
         pag.add(await asyncio.wait_for(
             self.bot.loop.create_task(run_command(body)), 120))
         book = Book(pag, (None, ctx.channel, ctx.bot, ctx.message))
         await book.create_book()
         await ctx.message.add_reaction('✅')
     except asyncio.TimeoutError:
         await ctx.send(f"Command did not complete in the time allowed.")
         await ctx.message.add_reaction('❌')
示例#3
0
 async def _eval(self, ctx, *, body: str):
     if ctx.author.id != self.bot.owner_id:
         return
     pag = Paginator(self.bot)
     env = {
         'bot': self.bot,
         'ctx': ctx,
         'channel': ctx.channel,
         'author': ctx.author,
         'server': ctx.guild,
         'message': ctx.message,
         '_': self._last_result,
     }
     env.update(globals())
     body = self.cleanup_code(body)
     stdout = io.StringIO()
     to_compile = 'async def func():\n%s' % textwrap.indent(body, '  ')
     try:
         exec(to_compile, env)
     except SyntaxError as e:
         return await ctx.send(self.get_syntax_error(e))
     func = env['func']
     # noinspection PyBroadException
     try:
         with redirect_stdout(stdout):
             ret = await func()
     except Exception:
         pag.add(stdout.getvalue())
         pag.add(f'\n\uFFF8{traceback.format_exc()}')
         book = Book(pag, (None, ctx.channel, ctx.bot, ctx.message))
         await book.create_book()
     else:
         value = stdout.getvalue()
         # noinspection PyBroadException
         try:
             await ctx.message.add_reaction('✅')
         except Exception:
             pass
         value = format_output(value)
         pag.add(value)
         pag.add(f'\n\uFFF8Returned: {ret}')
         self._last_result = ret
         book = Book(pag, (None, ctx.channel, ctx.bot, ctx.message))
         await book.create_book()
示例#4
0
 async def status(self, ctx):
     """Gets status of current branch."""
     pag = Paginator(self.bot, max_line_length=44, max_lines=30, embed=True)
     pag.set_embed_meta(
         title="Git Status",
         color=self.bot.embed_color,
         thumbnail=f"{ctx.guild.me.avatar_url}",
     )
     result = await asyncio.wait_for(
         self.bot.loop.create_task(run_command("git status")), 120
     )
     pag.add(result)
     book = Book(pag, (None, ctx.channel, self.bot, ctx.message))
     await book.create_book()
示例#5
0
 async def pull(self, ctx):
     """Pulls updates from GitHub rebasing branch."""
     pag = Paginator(self.bot, max_line_length=100, embed=True)
     pag.set_embed_meta(
         title="Git Pull",
         color=self.bot.embed_color,
         thumbnail=f"{ctx.guild.me.avatar_url}",
     )
     pag.add(
         "\uFFF6"
         + await asyncio.wait_for(
             self.bot.loop.create_task(run_command("git fetch --all")), 120
         )
     )
     pag.add("\uFFF7\n\uFFF8")
     pag.add(
         await asyncio.wait_for(
             self.bot.loop.create_task(
                 run_command(
                     "git reset --hard "
                     "origin/$(git "
                     "rev-parse --symbolic-full-name"
                     " --abbrev-ref HEAD)"
                 )
             ),
             120,
         )
     )
     pag.add("\uFFF7\n\uFFF8")
     pag.add(
         await asyncio.wait_for(
             self.bot.loop.create_task(
                 run_command("git show --stat | " 'sed "s/.*@.*[.].*/ /g"')
             ),
             10,
         )
     )
     book = Book(pag, (None, ctx.channel, self.bot, ctx.message))
     await book.create_book()
示例#6
0
 async def on_command_error(self, ctx, error):
     pag = Paginator(ctx.bot, embed=True)
     pag.set_embed_meta(color=self.bot.error_color)
     pag.add(f'\uFFF6Command Error')
     pag.add(error)
     pag.add('\uFFF7\n\uFFF8')
     full_error = ''.join(traceback.format_exception(type(error), error, error.__traceback__))
     pag.add(full_error)
     book = Book(pag, (None, ctx.channel, self.bot, ctx.message))
     await book.create_book()
     command_logger.error(full_error)
示例#7
0
    async def update(self, ctx, request_id=None, *, comment: str = None):
        try:
            request_id = int(request_id)
        except ValueError:
            await ctx.send(
                "Please include the ID of the request you would like to update as the first thing after the command."
            )
            return

        if not comment:
            await ctx.send(
                "There is nothing to update since you didn't include a message."
            )
            return

        data = {"author": ctx.author.id, "content": comment}

        comment_resp = await self.bot.aio_session.post(
            f"{self.bot.api_base}/messages/{ctx.guild.id}/requests/{request_id}/comments/",
            headers=self.bot.auth_header,
            json=data,
        )

        if comment_resp.status == 201:
            comment = await comment_resp.json()
            admin_channel_resp = await self.bot.aio_session.get(
                f"{self.bot.api_base}/channels/{ctx.guild.id}/admin/",
                headers=self.bot.auth_header,
            )

            if admin_channel_resp.status == 200:
                admin_channel_data = await admin_channel_resp.json()
                admin_channel = ctx.guild.get_channel(int(admin_channel_data["id"]))
                if admin_channel:
                    request_resp = await self.bot.aio_session.get(
                        f"{self.bot.api_base}/messages/{ctx.guild.id}/requests/{request_id}/",
                        headers=self.bot.auth_header,
                    )
                    pag = Paginator(self.bot, prefix="```md", suffix="```")
                    header = (
                        f"{ctx.author.mention} has commented on request {request_id}\n"
                    )
                    if request_resp.status == 200:
                        request = await request_resp.json()
                        requestor = await ctx.guild.fetch_member(int(request["author"]))
                        header += (
                            f'Original Request by {requestor.mention if requestor else "`User cannot be found`"}:\n'
                            f'```{request["content"]}```'
                        )
                        pag.set_header(header)

                        if request.get("comments"):
                            comments = request["comments"]
                            for comment in comments:
                                author = await ctx.guild.fetch_member(
                                    int(comment["author"])
                                )
                                pag.add(
                                    f'{author.display_name}: {comment["content"]}',
                                    keep_intact=True,
                                )
                        if ctx.author != requestor and requestor:
                            for page in pag.pages(page_headers=False):
                                await requestor.send(page)
                    book = Book(pag, (None, admin_channel, self.bot, ctx.message))
                    await book.create_book()
            await ctx.send(
                f"{ctx.author.mention} Your comment has been added to the request."
            )
示例#8
0
    async def view(self, ctx, id=None):
        if not id:
            await ctx.send(
                "Please include the id of the request you would like to view."
            )
            return

        admin = False
        admin_roles_resp = await self.bot.aio_session.get(
            f"{self.bot.api_base}/guilds/{ctx.guild.id}/roles/admin/",
            headers=self.bot.auth_header,
        )
        if admin_roles_resp.status == 200:
            admin_roles_data = await admin_roles_resp.json()
            admin_roles = [
                ctx.guild.get_role(int(role["id"])) for role in admin_roles_data
            ]
            if any([role in ctx.author.roles for role in admin_roles]):
                admin = True

        request_resp = await self.bot.aio_session.get(
            f"{self.bot.api_base}/messages/{ctx.guild.id}/requests/{id}/",
            headers=self.bot.auth_header,
        )
        if request_resp.status == 200:
            request = await request_resp.json()
            requestor = await ctx.guild.fetch_member(int(request["author"]))
            if requestor == ctx.author or admin:
                pag = Paginator(self.bot, prefix="```md", suffix="```")
                header = (
                    f'Request {id} by {requestor.mention if requestor else "`User cannot be found`"}:\n'
                    f'```{request["content"]}```'
                )
                pag.set_header(header)

                if request.get("comments"):
                    pag.add("Comments: \n")
                    comments = request["comments"]
                    for comment in comments:
                        author = await ctx.guild.fetch_member(int(comment["author"]))
                        pag.add(
                            f'{author.display_name}: {comment["content"]}',
                            keep_intact=True,
                        )
                else:
                    pag.add("No Comments")

                if request.get("completed"):
                    closer = await ctx.guild.fetch_member(
                        int(request.get("completed_by"))
                    )
                    pag.add(
                        f'Closed By: {closer.name}#{closer.discriminator}\n{request.get("completed_message")}'
                    )
                book = Book(pag, (None, ctx.channel, self.bot, ctx.message))
                await book.create_book()
            else:
                await ctx.send("That is not your request to close.")
示例#9
0
 async def _requests_list(self, ctx, closed: str = ""):
     pag = Paginator(self.bot)
     admin_roles_resp = await self.bot.aio_session.get(
         f"{self.bot.api_base}/guilds/{ctx.guild.id}/roles/admin/",
         headers=self.bot.auth_header,
     )
     if admin_roles_resp.status == 200:
         admin_roles_data = await admin_roles_resp.json()
         admin_roles = [
             ctx.guild.get_role(int(role["id"])) for role in admin_roles_data
         ]
         if any([role in ctx.author.roles for role in admin_roles]):
             requests_resp = await self.bot.aio_session.get(
                 f"{self.bot.api_base}/messages/{ctx.guild.id}/requests/",
                 headers=self.bot.auth_header,
             )
             if requests_resp.status == 200:
                 requests_data = await requests_resp.json()
                 requests_list = (
                     requests_data["requests"]
                     if isinstance(requests_data, dict)
                     else requests_data
                 )
                 while isinstance(requests_data, dict) and requests_data.get("next"):
                     requests_resp = await self.bot.aio_session.get(
                         requests_data["next"], headers=self.bot.auth_header
                     )
                     if requests_resp.status == 200:
                         requests_data = await requests_resp.json()
                         requests_list.extend(
                             requests_data["requests"]
                             if isinstance(requests_data, dict)
                             else requests_data
                         )
                 for request in requests_list:
                     member = await ctx.guild.fetch_member(int(request["author"]))
                     title = (
                         f"<{'Request ID':^20} {'Requested By':^20}>\n"
                         f"<{request['id']:^20} {member.display_name if member else 'None':^20}>"
                     )
                     orig_channel = ctx.guild.get_channel(
                         int(request.get("channel"))
                     )
                     comments_count_resp = await self.bot.aio_session.get(
                         f'{self.bot.api_base}/messages/{ctx.guild.id}/requests/{request["id"]}/comments/count/',
                         headers=self.bot.auth_header,
                     )
                     pag.add(
                         f"\n\n{title}\n"
                         f"{request['content']}\n\n"
                         f"Comments: {await comments_count_resp.text() if comments_count_resp.status == 200 else 0}\n"
                         f"Requested at: "
                         f"{request['requested_at'].split('.')[0].replace('T', ' ')} GMT\n"
                         f"In {orig_channel.name if orig_channel else 'N/A'}",
                         keep_intact=True,
                     )
                 pag.add(
                     f"\n\uFFF8\nThere are currently {len(requests_list)} requests open."
                 )
             else:
                 pag.add(
                     "There are no open requests for this guild.", keep_intact=True
                 )
         else:
             requests_resp = await self.bot.aio_session.get(
                 f"{self.bot.api_base}/messages/{ctx.guild.id}/requests/user/{ctx.author.id}/",
                 headers=self.bot.auth_header,
             )
             if requests_resp.status == 200:
                 requests_data = await requests_resp.json()
                 requests_list = (
                     requests_data["requests"]
                     if isinstance(requests_data, dict)
                     else requests_data
                 )
                 while isinstance(requests_data, dict) and requests_data.get("next"):
                     requests_resp = await self.bot.aio_session.get(
                         requests_data["next"], headers=self.bot.auth_header
                     )
                     if requests_resp.status == 200:
                         requests_data = await requests_resp.json()
                         requests_list.extend(
                             requests_data["requests"]
                             if isinstance(requests_data, dict)
                             else requests_data
                         )
                 for request in requests_list:
                     title = f"<{'Request ID':^20}>\n" f"<{request['id']:^20}>"
                     orig_channel = ctx.guild.get_channel(
                         int(request.get("channel"))
                     )
                     comments_count_resp = await self.bot.aio_session.get(
                         f'{self.bot.api_base}/messages/{ctx.guild.id}/requests/{request["id"]}/comments/count/',
                         headers=self.bot.auth_header,
                     )
                     pag.add(
                         f"\n\n{title}\n"
                         f"{request['content']}\n\n"
                         f"Comments: {await comments_count_resp.text() if comments_count_resp.status == 200 else 0}\n"
                         f"Requested at: "
                         f"{request['requested_at'].split('.')[0].replace('T', ' ')} GMT\n"
                         f"In {orig_channel.name if orig_channel else 'N/A'}",
                         keep_intact=True,
                     )
                 pag.add(
                     f"\n\uFFF8\nYou currently have {len(requests_list)} requests open."
                 )
             else:
                 pag.add(
                     "You have no open requests for this guild.", keep_intact=True
                 )
     for page in pag.pages():
         await ctx.send(page)
示例#10
0
 async def repl(self, ctx):
     if ctx.author.id != self.bot.owner_id:
         return
     msg = ctx.message
     variables = {
         'ctx': ctx,
         'bot': self.bot,
         'message': msg,
         'server': msg.guild,
         'channel': msg.channel,
         'author': msg.author,
         '_': None,
     }
     if msg.channel.id in self.sessions:
         await ctx.send(
             'Already running a REPL session in this channel. Exit it with `quit`.'
         )
         return
     self.sessions.add(msg.channel.id)
     await ctx.send(
         'Enter code to execute or evaluate. `exit()` or `quit` to exit.')
     while True:
         response = await self.bot.wait_for(
             'message', check=(lambda m: m.content.startswith('`')))
         if response.author.id == self.bot.owner_id:
             cleaned = self.cleanup_code(response.content)
             if cleaned in ('quit', 'exit', 'exit()'):
                 await response.channel.send('Exiting.')
                 self.sessions.remove(msg.channel.id)
                 return
             executor = exec
             if cleaned.count('\n') == 0:
                 try:
                     code = compile(cleaned, '<repl session>', 'eval')
                 except SyntaxError:
                     pass
                 else:
                     executor = eval
             if executor is exec:
                 try:
                     code = compile(cleaned, '<repl session>', 'exec')
                 except SyntaxError as e:
                     await response.channel.send(self.get_syntax_error(e))
                     continue
             variables['message'] = response
             fmt = None
             stdout = io.StringIO()
             # noinspection PyBroadException
             try:
                 with redirect_stdout(stdout):
                     result = executor(code, variables)
                     if inspect.isawaitable(result):
                         result = await result
             except Exception:
                 value = stdout.getvalue()
                 fmt = '{}{}'.format(value, traceback.format_exc())
             else:
                 value = stdout.getvalue()
                 if result is not None:
                     fmt = '{}{}'.format(value, result)
                     variables['_'] = result
                 elif value:
                     fmt = '{}'.format(value)
             try:
                 if fmt is not None:
                     pag = Paginator(self.bot)
                     pag.add(fmt)
                     for page in pag.pages():
                         await response.channel.send(page)
                         await ctx.send(response.channel)
             except discord.Forbidden:
                 pass
             except discord.HTTPException as e:
                 await msg.channel.send('Unexpected error: `{}`'.format(e))
示例#11
0
    async def haskell_compiler(self, ctx, *, body: str = None):
        if ctx.author.id != self.bot.owner_id:
            return

        if body is None:
            await ctx.send('Nothing to do.')
            return

        async with ctx.typing():
            msg = await ctx.send('Warming up GHC... Please wait.')
            try:
                body = self.cleanup_code(body)
                file_name = f'haskell_{datetime.utcnow().strftime("%Y%m%dT%H%M%S%f")}'
                with open(f'{file_name}.hs', 'w') as f:
                    f.write(body)
                pag = Paginator(self.bot)
                compile_start = time.time()
                pag.add(await asyncio.wait_for(self.bot.loop.create_task(
                    run_command(f'ghc -o {file_name} {file_name}.hs')),
                                               timeout=60))
                compile_end = time.time()
                compile_real = compile_end - compile_start
                book = Book(pag, (msg, ctx.channel, ctx.bot, ctx.message))
                await book.create_book()
                pag = Paginator(self.bot)
                if file_name in os.listdir():
                    run_start = time.time()
                    pag.add(await asyncio.wait_for(self.bot.loop.create_task(
                        run_command(f'./{file_name}')),
                                                   timeout=600))
                    run_end = time.time()
                    run_real = run_end - run_start
                    total_real = run_real + compile_real
                    pag.add(f'\n\nCompile took {compile_real:.2f} seconds')
                    pag.add(f'Total Time {total_real:.2f} seconds')
                    book = Book(pag, (None, ctx.channel, ctx.bot, ctx.message))
                    await msg.delete()
                    await book.create_book()
                os.remove(file_name)
                os.remove(f'{file_name}.hs')
                os.remove(f'{file_name}.o')
                os.remove(f'{file_name}.hi')
            except asyncio.TimeoutError:
                await msg.delete()
                await ctx.send(f"Command did not complete in the time allowed."
                               )
                await ctx.message.add_reaction('❌')
            except FileNotFoundError as e:
                repl_log.warning(e)