def source(self, command : str = None):
"""Displays my full source code or for a specific command.
To display the source code of a subcommand you have to separate it by
periods, e.g. tag.create for the create subcommand of the tag command.
"""
source_url = 'https://github.com/miraai/LunaBot'
if command is None:
await self.bot.say(source_url)
return
code_path = command.split('.')
obj = self.bot
for cmd in code_path:
try:
obj = obj.get_command(cmd)
if obj is None:
await self.bot.say('Could not find the command ' + cmd)
return
except AttributeError:
await self.bot.say('{0.name} command has no subcommands'.format(obj))
return
# since we found the command we're looking for, presumably anyway, let's
# try to access the code itself
src = obj.callback.__code__
if not obj.callback.__module__.startswith('discord'):
# not a built-in command
location = os.path.relpath(src.co_filename).replace('\\', '/')
final_url = '<{}/blob/master/{}#L{}>'.format(source_url, location, src.co_firstlineno)
else:
location = obj.callback.__module__.replace('.', '/') + '.py'
base = 'https://github.com/Rapptz/discord.py'
final_url = '<{}/blob/master/{}#L{}>'.format(base, location, src.co_firstlineno)
await self.bot.say(final_url)
python类py()的实例源码
def on_ready():
print("discord.py version: {}".format(discord.__version__))
print('Running script as: {}#{}({})'.format(bot.user.name, bot.user.discriminator, bot.user.id))
print('------------------------------------------------------------------')
if not hasattr(bot, 'game_name'):
bot.game_name = None
if not hasattr(bot, 'status'):
bot.status = discord.Status.online
await bot.change_presence(status=bot.status)
# reset these to empty list
bot.log_servers = []
bot.log_private_channels_list = []
if bot.log_all_messages_on_start:
print("Beginning to dump previous messages to log...")
log.info("====================== Dumping Previous Messages ======================")
# first log all servers and channels in servers
for server in bot.servers:
for channel in server.channels:
permissions = channel.permissions_for(server.get_member(bot.user.id))
if all(getattr(permissions, perm, None) == True for perm in ["read_messages", "read_message_history"]):
async for message in bot.logs_from(channel, limit=bot.message_channel_max):
log_message(message)
# now the same for PrivateChannels
for channel in bot.private_channels:
async for message in bot.logs_from(channel, limit=bot.message_channel_max):
log_message(message)
log.info("====================== End Previous Message Dump ======================")
print("Finished dumping previous messages!")
def parse_commandline(argv):
# get token from command line, if less than 1 (script), print error and exit
if len(argv) > 1:
# try to parse args
try:
# apparently needs to be sys.argv[1:], or it wont work...
opts, args = getopt.getopt(argv[1:],"h",["token=", "help"])
# if no args, print error, usage and exit
except:
cleanup_handlers()
invalid_token()
usage(argv[0])
sys.exit(-1)
for opt, arg in opts:
# print usage statement and exit
if opt in ('-h', "--help"):
cleanup_handlers()
usage(argv[0])
sys.exit(0)
# grab token from arg for discord.py usage
elif opt == '--token':
token = arg
token = token.strip()
if token is None or token == "":
cleanup_handlers()
invalid_token()
usage(argv[0])
sys.exit(-1)
else:
# DERP! forgot to add this here >.<
cleanup_handlers()
invalid_token()
usage(argv[0])
sys.exit(-1)
def botinformation(cmd, message, args):
version_data = cmd.bot.info.version.raw
author_data = cmd.bot.info.authors.raw
sigma_image = 'https://i.imgur.com/mGyqMe1.png'
support_url = 'https://discordapp.com/invite/aEUCHwX'
ver_nest = version_data["version"]
full_version = f'{ver_nest["major"]}.{ver_nest["minor"]}.{ver_nest["patch"]}'
if version_data['beta']:
full_version += ' Beta'
sigma_title = f'Apex Sigma: v{full_version} {version_data["codename"]}'
env_text = f'Language: **Python {sys.version.split()[0]}**'
env_text += f'\nLibrary: **discord.py** {discord.__version__}'
env_text += f'\nPlatform: **{sys.platform.upper()}**'
auth_text = ''
for author in author_data:
auth = discord.utils.find(lambda x: x.id == author['id'], cmd.bot.get_all_members())
if auth:
auth_text += f'\n**{auth.name}**#{auth.discriminator}'
else:
auth_text += f'\n**{author["name"]}**#{author["discriminator"]}'
response = discord.Embed(color=0x1B6F5F, timestamp=arrow.get(version_data['build_date']).datetime)
response.set_author(name=sigma_title, icon_url=sigma_image, url=support_url)
response.add_field(name='Authors', value=auth_text)
response.add_field(name='Environment', value=env_text)
response.set_footer(text=f'Last updated {arrow.get(version_data["build_date"]).humanize()}')
await message.channel.send(embed=response)
def info(self, ctx):
"""Prints info about mangobyte"""
github = "https://github.com/mdiller/MangoByte"
python_version = "[Python {}.{}.{}]({})".format(*os.sys.version_info[:3], "https://www.python.org/")
discordpy = "https://github.com/Rapptz/discord.py"
embed = discord.Embed(description="The juiciest unsigned 8 bit integer you eva gonna see", color=discord.Color.green())
embed.set_author(name=self.bot.user.name, icon_url=self.bot.user.avatar_url, url=github)
embed.add_field(name="Development Info", value=(
"Developed as an open source project, hosted on [GitHub]({}). "
"Implemented using {} and a python discord api wrapper [discord.py]({})".format(github, python_version, discordpy)))
embed.add_field(name="Features", value=(
"• Answers questions (`?ask`)\n"
"• Plays audio clips (`?play`, `?dota`)\n"
"• Greets users joining a voice channel\n"
"• For a list of command categories, try `?help`"))
help_guild_link = "https://discord.gg/d6WWHxx"
embed.add_field(name="Help", value=(
f"If you want to invite mangobyte to your server/guild, click this [invite link]({invite_link}). "
f"If you have a question, suggestion, or just want to try out mah features, check out the [Help Server/Guild]({help_guild_link})."))
owner = (await self.bot.application_info()).owner
embed.set_footer(text="MangoByte developed by {}".format(owner.name), icon_url=owner.avatar_url)
await ctx.send(embed=embed)
def on_command_error(error, ctx):
if isinstance(error, commands.errors.CommandNotFound):
pass # ...don't need to know if commands don't exist
if isinstance(error, commands.errors.CheckFailure):
await bot.send_message(ctx.message.channel, "{} You don't have permission to use this command.".format(ctx.message.author.mention))
elif isinstance(error, commands.errors.MissingRequiredArgument):
formatter = commands.formatter.HelpFormatter()
await bot.send_message(ctx.message.channel, "{} You are missing required arguments.\n{}".format(ctx.message.author.mention, formatter.format_help_for(ctx, ctx.command)[0]))
elif isinstance(error, commands.errors.CommandOnCooldown):
try:
await bot.delete_message(ctx.message)
except discord.errors.NotFound:
pass
message = await bot.send_message(ctx.message.channel, "{} This command was used {:.2f}s ago and is on cooldown. Try again in {:.2f}s.".format(ctx.message.author.mention, error.cooldown.per - error.retry_after, error.retry_after))
await asyncio.sleep(10)
await bot.delete_message(message)
else:
await bot.send_message(ctx.message.channel, "An error occured while processing the `{}` command.".format(ctx.command.name))
print('Ignoring exception in command {0.command} in {0.message.channel}'.format(ctx))
mods_msg = "Exception occured in `{0.command}` in {0.message.channel.mention}".format(ctx)
# traceback.print_exception(type(error), error, error.__traceback__, file=sys.stderr)
tb = traceback.format_exception(type(error), error, error.__traceback__)
print(''.join(tb))
await bot.send_message(bot.boterr_channel, mods_msg + '\n```' + ''.join(tb) + '\n```')
# mostly taken from https://github.com/Rapptz/discord.py/blob/async/discord/client.py
def info(self, ctx):
"""Bot Info"""
me = self.bot.user if not ctx.guild else ctx.guild.me
appinfo = await self.bot.application_info()
embed = discord.Embed()
embed.set_author(name=me.display_name, icon_url=appinfo.owner.avatar_url, url="https://github.com/henry232323/PokeRPG-Bot")
embed.add_field(name="Author", value='Henry#6174 (Discord ID: 122739797646245899)')
embed.add_field(name="Library", value='discord.py (Python)')
embed.add_field(name="Uptime", value=await self.bot.get_bot_uptime())
embed.add_field(name="Servers", value="{} servers".format(len(self.bot.guilds)))
embed.add_field(name="Commands Run", value='{} commands'.format(sum(self.bot.commands_used.values())))
total_members = sum(len(s.members) for s in self.bot.guilds)
total_online = sum(1 for m in self.bot.get_all_members() if m.status != discord.Status.offline)
unique_members = set(map(lambda x: x.id, self.bot.get_all_members()))
channel_types = Counter(isinstance(c, discord.TextChannel) for c in self.bot.get_all_channels())
voice = channel_types[False]
text = channel_types[True]
embed.add_field(name="Total Members", value='{} ({} online)'.format(total_members, total_online))
embed.add_field(name="Unique Members", value='{}'.format(len(unique_members)))
embed.add_field(name="Channels", value='{} text channels, {} voice channels'.format(text, voice))
embed.add_field(name="Shards", value=f'Currently running {ctx.bot.shard_count} shards. This server is on shard {getattr(ctx.guild, "shard_id", 0)}')
a = monotonic()
await (await ctx.bot.shards[getattr(ctx.guild, "shard_id", 0)].ws.ping())
b = monotonic()
ping = "{:.3f}ms".format((b - a) * 1000)
embed.add_field(name="CPU Percentage", value="{}%".format(psutil.cpu_percent()))
embed.add_field(name="Memory Usage", value=self.bot.get_ram())
embed.add_field(name="Observed Events", value=sum(self.bot.socket_stats.values()))
embed.add_field(name="Ping", value=ping)
embed.add_field(name="Source", value="[Github](https://github.com/henry232323/RPGBot)")
embed.set_footer(text='Made with discord.py', icon_url='http://i.imgur.com/5BFecvA.png')
embed.set_thumbnail(url=self.bot.user.avatar_url)
await ctx.send(delete_after=60, embed=embed)
def source(self, ctx, command: str = None):
"""Displays my full source code or for a specific command.
To display the source code of a subcommand you have to separate it by
periods, e.g. tag.create for the create subcommand of the tag command.
"""
source_url = 'https://github.com/henry232323/RPGBot'
if command is None:
await ctx.send(source_url)
return
code_path = command.split('.')
obj = self.bot
for cmd in code_path:
try:
obj = obj.get_command(cmd)
if obj is None:
await ctx.send('Could not find the command ' + cmd)
return
except AttributeError:
await ctx.send('{0.name} command has no subcommands'.format(obj))
return
# since we found the command we're looking for, presumably anyway, let's
# try to access the code itself
src = obj.callback.__code__
if not obj.callback.__module__.startswith('discord'):
# not a built-in command
location = os.path.relpath(src.co_filename).replace('\\', '/')
final_url = '<{}/tree/master/{}#L{}>'.format(source_url, location, src.co_firstlineno)
else:
location = obj.callback.__module__.replace('.', '/') + '.py'
base = 'https://github.com/Rapptz/discord.py'
final_url = '<{}/blob/master/{}#L{}>'.format(base, location, src.co_firstlineno)
await ctx.send(final_url)
def _command_signature(cmd):
# this is modified from discord.py source
# which I wrote myself lmao
result = [cmd.qualified_name]
if cmd.usage:
result.append(cmd.usage)
return ' '.join(result)
params = cmd.clean_params
if not params:
return ' '.join(result)
for name, param in params.items():
if param.default is not param.empty:
# We don't want None or '' to trigger the [name=value] case and instead it should
# do [name] since [name=None] or [name=] are not exactly useful for the user.
should_print = param.default if isinstance(param.default, str) else param.default is not None
if should_print:
result.append(f'[{name}={param.default!r}]')
else:
result.append(f'[{name}]')
elif param.kind == param.VAR_POSITIONAL:
result.append(f'[{name}...]')
else:
result.append(f'<{name}>')
return ' '.join(result)
def on_message(self, message):
channel = message.channel
author = message.author
if channel.id != DISCORD_PY_ID:
return
if author.status is discord.Status.offline:
fmt = f'{author} (ID: {author.id}) has been automatically blocked for 5 minutes for being invisible'
await channel.set_permissions(author, read_messages=False, reason='invisible block')
await channel.send(fmt)
try:
msg = f'Heya. You have been automatically blocked from <#{DISCORD_PY_ID}> for 5 minutes for being ' \
'invisible.\nTry chatting again in 5 minutes when you change your status. If you\'re curious ' \
'why invisible users are blocked, it is because they tend to break the client and cause them to ' \
'be hard to mention. Since we want to help you usually, we expect mentions to work without ' \
'headaches.\n\nSorry for the trouble.'
await author.send(msg)
except discord.HTTPException:
pass
await asyncio.sleep(300)
await channel.set_permissions(author, overwrite=None, reason='invisible unblock')
return
m = self.issue.search(message.content)
if m is not None:
url = 'https://github.com/Rapptz/discord.py/issues/'
await channel.send(url + m.group('number'))
def rtfm(self, ctx, *, obj: str = None):
"""Gives you a documentation link for a discord.py entity.
Events, objects, and functions are all supported through a
a cruddy fuzzy algorithm.
"""
await self.do_rtfm(ctx, 'latest', obj)
def rtfm_rewrite(self, ctx, *, obj: str = None):
"""Gives you a documentation link for a rewrite discord.py entity."""
await self.do_rtfm(ctx, 'rewrite', obj)
def faq(self, ctx, *, query: str = None):
"""Shows an FAQ entry from the discord.py documentation"""
if not hasattr(self, 'faq_entries'):
await self.refresh_faq_cache()
if query is None:
return await ctx.send('http://discordpy.readthedocs.io/en/latest/faq.html')
matches = fuzzy.extract_matches(query, self.faq_entries, scorer=fuzzy.partial_ratio, score_cutoff=40)
if len(matches) == 0:
return await ctx.send('Nothing found...')
fmt = '\n'.join(f'**{key}**\n{value}' for key, _, value in matches)
await ctx.send(fmt)
def join(self, invite_url: discord.Invite=None):
"""Joins new server"""
if hasattr(self.bot.user, 'bot') and self.bot.user.bot is True:
# Check to ensure they're using updated discord.py
msg = ("I have a **BOT** tag, so I must be invited with an OAuth2"
" link:\nFor more information: "
"---"
"---")
await self.bot.say(msg)
if hasattr(self.bot, 'oauth_url'):
await self.bot.whisper("Here's my OAUTH2 link:\n{}".format(
self.bot.oauth_url))
return
if invite_url is None:
await self.bot.say("I need a Discord Invite link for the "
"server you want me to join.")
return
try:
await self.bot.accept_invite(invite_url)
await self.bot.say("Server joined.")
log.debug("We just joined {}".format(invite_url))
except discord.NotFound:
await self.bot.say("The invite was invalid or expired.")
except discord.HTTPException:
await self.bot.say("I wasn't able to accept the invite."
" Try again.")
def _list_cogs(self):
cogs = [os.path.basename(f) for f in glob.glob("cogs/*.py")]
return ["cogs." + os.path.splitext(f)[0] for f in cogs]
def set_cog(cog, value): # TODO: move this out of red.py
data = dataIO.load_json("data/red/cogs.json")
data[cog] = value
dataIO.save_json("data/red/cogs.json", data)
def status(self, ctx):
'''Infos über den Bot'''
timeUp = time.time() - self.bot.startTime
hours = timeUp / 3600
minutes = (timeUp / 60) % 60
seconds = timeUp % 60
admin = self.bot.get_user(self.bot.owner_id)
users = 0
channel = 0
if len(self.bot.commands_used.items()):
commandsChart = sorted(self.bot.commands_used.items(), key=lambda t: t[1], reverse=False)
topCommand = commandsChart.pop()
commandsInfo = '{} (Top-Command: {} x {})'.format(sum(self.bot.commands_used.values()), topCommand[1], topCommand[0])
else:
commandsInfo = str(sum(self.bot.commands_used.values()))
for guild in self.bot.guilds:
users += len(guild.members)
channel += len(guild.channels)
embed = discord.Embed(color=ctx.me.top_role.colour)
embed.set_footer(text='Dieser Bot ist Open-Source auf GitHub: https://github.com/Der-Eddy/discord_bot')
embed.set_thumbnail(url=ctx.me.avatar_url)
embed.add_field(name='Admin', value=admin, inline=False)
embed.add_field(name='Uptime', value='{0:.0f} Stunden, {1:.0f} Minuten und {2:.0f} Sekunden\n'.format(hours, minutes, seconds), inline=False)
embed.add_field(name='Beobachtete Benutzer', value=users, inline=True)
embed.add_field(name='Beobachtete Server', value=len(self.bot.guilds), inline=True)
embed.add_field(name='Beobachtete Channel', value=channel, inline=True)
embed.add_field(name='Ausgeführte Commands', value=commandsInfo, inline=True)
embed.add_field(name='Bot Version', value=self.bot.botVersion, inline=True)
embed.add_field(name='Discord.py Version', value=discord.__version__, inline=True)
embed.add_field(name='Python Version', value=platform.python_version(), inline=True)
# embed.add_field(name='Speicher Auslastung', value=f'{round(memory_usage(-1)[0], 3)} MB', inline=True)
embed.add_field(name='Betriebssystem', value=f'{platform.system()} {platform.release()} {platform.version()}', inline=False)
await ctx.send('**:information_source:** Informationen über diesen Bot:', embed=embed)
def about(self, ctx):
'''Info über mich'''
msg = 'Shinobu Oshino gehört wohl zu den mysteriösesten Charakteren in Bakemonogatari. Sie war bis vorletzten Frühling ein hochangesehener, adeliger, skrupelloser Vampir, der weit über 500 Jahre alt ist. Gnadenlos griff sie Menschen an und massakrierte sie nach Belieben. Auch Koyomi Araragi wurde von ihr attackiert und schwer verwundet. Nur durch das Eingreifen des Exorzisten Meme Oshino konnte Kiss-shot Acerola-orion Heart-under-blade, wie sie damals bekannt war, bezwungen werden. Dabei verlor sie jedoch all ihre Erinnerungen und wurde von einer attraktiven, erwachsenen Frau in einen unschuldigen Mädchenkörper verwandelt.\n\n'
msg += 'Seitdem lebt sie zusammen mit Meme in einem verlassenen Gebäude und wurde von ihm aufgenommen. Er gab ihr auch ihren Namen Shinobu. Das Vampirblut in ihr verlangt immer noch nach Opfern und da sich Koyomi in gewisser Art und Weise schuldig fühlt, stellt er sich regelmäßig als Nahrungsquelle für Shinobu zur Verfügung.\n\n'
msg += 'Quelle: http://www.anisearch.de/character/6598,shinobu-oshino/\n\n'
embed = discord.Embed(color=ctx.me.top_role.colour)
embed.set_footer(text='Dieser Bot ist außerdem free, Open-Source, in Python und mit Hilfe von discord.py geschrieben! https://github.com/Der-Eddy/discord_bot\n')
embed.set_thumbnail(url=ctx.me.avatar_url)
embed.add_field(name='**:information_source: Shinobu Oshino (500 Jahre alt)**', value=msg, inline=False)
await ctx.send(embed=embed)
def source(self, ctx, *, command: str = None):
'''Zeigt den Quellcode für einen Befehl auf GitHub an
Beispiel:
-----------
:source kawaii
'''
source_url = 'https://github.com/Der-Eddy/discord_bot'
if command is None:
await ctx.send(source_url)
return
obj = self.bot.get_command(command.replace('.', ' '))
if obj is None:
return await ctx.send(':x: Konnte den Befehl nicht finden')
# since we found the command we're looking for, presumably anyway, let's
# try to access the code itself
src = obj.callback.__code__
lines, firstlineno = inspect.getsourcelines(src)
sourcecode = inspect.getsource(src).replace('```', '')
if not obj.callback.__module__.startswith('discord'):
# not a built-in command
location = os.path.relpath(src.co_filename).replace('\\', '/')
else:
location = obj.callback.__module__.replace('.', '/') + '.py'
source_url = 'https://github.com/Rapptz/discord.py'
if len(sourcecode) > 1900:
final_url = '{}/blob/master/{}#L{}-L{}'.format(source_url, location, firstlineno, firstlineno + len(lines) - 1)
else:
final_url = '<{}/blob/master/{}#L{}-L{}>\n```Python\n{}```'.format(source_url, location, firstlineno, firstlineno + len(lines) - 1, sourcecode)
await ctx.send(final_url)
def _command_signature(cmd):
# this is modified from discord.py source
# which I wrote myself lmao
result = [cmd.qualified_name]
if cmd.usage:
result.append(cmd.usage)
return ' '.join(result)
params = cmd.clean_params
if not params:
return ' '.join(result)
for name, param in params.items():
if param.default is not param.empty:
# We don't want None or '' to trigger the [name=value] case and instead it should
# do [name] since [name=None] or [name=] are not exactly useful for the user.
should_print = param.default if isinstance(param.default, str) else param.default is not None
if should_print:
result.append(f'[{name}={param.default!r}]')
else:
result.append(f'[{name}]')
elif param.kind == param.VAR_POSITIONAL:
result.append(f'[{name}...]')
else:
result.append(f'<{name}>')
return ' '.join(result)