Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Source Command #485

Closed
wants to merge 4 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 16 additions & 13 deletions bot/cogs/source.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import inspect
import logging
import os

import discord
from discord.ext import commands
Expand All @@ -18,42 +19,44 @@ def __init__(self, bot: commands.Bot) -> None:

@in_channel(constants.Channels.bot)
@commands.command(name="source")
async def command_source(self, ctx: commands.Context, command_name: str = None, sub_command: str = None) -> None:
async def command_source(self, ctx: commands.Context, *, command_name: str = None) -> None:
"""View the source of a command."""
if command_name is None:
await ctx.send("> https://github.com/python-discord/bot")
Copy link

@nekitdev nekitdev Oct 4, 2019

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure why wouldn't we do return await ctx.send(...) in one line honestly, but ok if there is a reason.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're annotating that our function returns None then it should return None, not maybe None

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I have just checked in discord.py. send returns a discord.Message instance, well then, we should return None.

return

if sub_command:
await ctx.send(sub_command)
command = self.bot.get_command(f"{command_name} {sub_command}")
else:
command = self.bot.get_command(command_name)

command = self.bot.get_command(command_name)
if command is None:
await ctx.send("No such command found.")
return

url = self.get_command_url(command)
if command.name == "help":
url = "https://github.com/python-discord/bot/blob/master/bot/cogs/help.py#L475-L490"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my opinion, we would better send a link without the lines here.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which lines

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The #L475-L490 should not be hard-coded in my opinion. I think we should just return the link to the help.py file.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should just return the correct lines, but without hardcoding them.

@RohanJnr we can't have any hardcoded edge cases in this solution. Please try to find a solution that solves this without hardcoding.


else:
url = self.get_command_url(command)

prefix = constants.Bot.prefix

embed = discord.Embed(colour=discord.Colour.red())
embed.title = "Command Source"
embed.description = f"**{command.name.capitalize()}**\n"
embed.description += f"`{prefix}{command.name}`\n\n {url}"
embed.description += f"`{prefix}{command.qualified_name}`\n\n {url}"

await ctx.send(embed=embed)

@staticmethod
def get_command_url(command: commands.Command) -> str:
"""Make up the url for the source of the command."""
# Get the source code
src_code_object = command.callback.__code__
file_path = src_code_object.co_filename[5:]
src = command.callback.__code__
file_name = src.co_filename

# get the file path
file_path = os.path.relpath(file_name).replace('\\', '/')

# Get line number and set last line number
lines_list, starting_line_no = inspect.getsourcelines(src_code_object)
lines_list, starting_line_no = inspect.getsourcelines(src)
lines = len(lines_list)

# Get module
Expand All @@ -66,7 +69,7 @@ def get_command_url(command: commands.Command) -> str:
base_url = "https://github.com/python-discord/bot/tree/master/"

# use the module name if the file path goes into the decorators.
if file_path == "bot/decorators.py":
if "bot/decorators.py" in file_path:
final_url = f"{base_url}{module_name}#L{starting_line_no}-L{last_line_no}"
else:
final_url = f"{base_url}{file_path}#L{starting_line_no}-L{last_line_no}"
Expand Down