Updated some files

This commit is contained in:
davfsa 2018-06-21 20:04:07 +02:00
parent 8f70fcc142
commit fe143678fe
6 changed files with 130 additions and 820 deletions

View File

@ -1,10 +1,9 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
import asyncio
from discord.ext import commands
import discord
import asyncio
class BasicCommands:
def __init__(self, bot):
@ -12,83 +11,58 @@ class BasicCommands:
@commands.command()
async def tutorial(self, ctx):
await ctx.send(
f"Hello, {ctx.author.display_name}. Welcome to Sebi's Bot Tutorials. \nFirst off, would you like a quick walkthrough on the server channels?"
)
await ctx.send(f"Hello, {ctx.author.display_name}. Welcome to Sebi's Bot Tutorials. \nFirst off, would you like a quick walkthrough on the server channels?")
channel_list = {
"channel-1": self.bot.get_channel(333149949883842561).mention,
"d.py-rewrite-start": self.bot.get_channel(386419285439938560).mention,
"js-klasa-start": self.bot.get_channel(341816240186064897).mention,
"d.js": self.bot.get_channel(436771798303113217).mention,
}
channel_list = {'channel-1' : self.bot.get_channel(333149949883842561).mention,
'd.py-rewrite-start' : self.bot.get_channel(386419285439938560).mention,
'js-klasa-start' : self.bot.get_channel(341816240186064897).mention,
'async2rewrite-start' : self.bot.get_channel(392223495389577217).mention,
'd.js' : self.bot.get_channel(436771798303113217).mention}
bots_channels = (
self.bot.get_channel(339112602867204097).mention,
self.bot.get_channel(411586546551095296).mention,
)
bots_channels = (self.bot.get_channel(339112602867204097).mention,
self.bot.get_channel(411586546551095296).mention)
help_channels = (
self.bot.get_channel(425315253153300488).mention,
self.bot.get_channel(392215236612194305).mention,
self.bot.get_channel(351034776985141250).mention,
)
help_channels = (self.bot.get_channel(425315253153300488).mention,
self.bot.get_channel(392215236612194305).mention,
self.bot.get_channel(351034776985141250).mention)
def check(m):
return (
True
if m.author.id == ctx.author.id and m.channel.id == ctx.channel.id
else False
)
return True if m.author.id == ctx.author.id and m.channel.id == ctx.channel.id else False
msg = await self.bot.wait_for("message", check=check, timeout=15)
msg = await self.bot.wait_for('message', check = check, timeout = 15)
agree = ("yes", "yep", "yesn't", "ya", "ye")
agree = ("yes", "yep", "non't", "ya", "ye", "yup", "ok", "why not")
if msg is None:
await ctx.send(
"Sorry, {ctx.author.mention}, you didn't reply on time. You can run the command again when you're free :)"
)
await ctx.send("Sorry, {ctx.author.mention}, you didn't reply on time. You can run the command again when you're free :)")
else:
if msg.content.lower() in agree:
async with ctx.typing():
await ctx.send("Alrighty-Roo... Check your DMs!")
await ctx.author.send("Alrighty-Roo...")
await ctx.author.send(
f"To start making your bot from scratch, you first need to head over to {channel_list['channel-1']}"
" (Regardless of the language you're gonna use)."
)
await ctx.author.send(f"To start making your bot from scratch, you first need to head over to {channel_list['channel-1']}"
" (Regardless of the language you're gonna use).")
await asyncio.sleep(0.5)
await ctx.author.send(
f"After you have a bot account, you can either continue with {channel_list['d.py-rewrite-start']}"
f"if you want to make a bot in discord.py rewrite __or__ go to {channel_list['js-klasa-start']} or "
f"{channel_list['d.js']} for making a bot in JavaScript."
)
await ctx.author.send(f"After you have a bot account, you can either continue with {channel_list['d.py-rewrite-start']} "
f"if you want to make a bot in discord.py rewrite __or__ go to {channel_list['js-klasa-start']} or "
f"{channel_list['d.js']} for making a bot in JavaScript."
f"If you already have old Discord.py async code and you want to use it with the new Rewrite versions, head to {channel_list['async2rewrite-start']}")
await ctx.author.send(
"...Read all the tutorials and still need help? You have two ways to get help."
)
await ctx.author.send("...Read all the tutorials and still need help? You have two ways to get help.")
await asyncio.sleep(1.5)
await ctx.author.send(
"**Method-1**\nThis is the best method of getting help. You help yourself.\n"
f"To do so, head over to a bots dedicated channel (either {bots_channels[0]} or {bots_channels[1]})"
" and type `?rtfm rewrite thing_you_want_help_with`.\nThis will trigger the bot R.Danny Bot and will"
"give you links on your query on the official discord.py rewrite docs. *PS: Let the page completely load*"
)
await ctx.author.send("**Method-1**\nThis is the best method of getting help. You help yourself.\n"
f"To do so, head over to a bots dedicated channel (either {bots_channels[0]} or {bots_channels[1]})"
" and type `?rtfm rewrite thing_you_want_help_with`.\nThis will trigger the bot R.Danny Bot and will "
"give you links on your query on the official discord.py rewrite docs. *PS: Let the page completely load*")
await asyncio.sleep(5)
await ctx.author.send(
"**Method-2**\nIf you haven't found anything useful with Method-1, feel free to ask your question "
f"in any of the related help channels. ({', '.join(help_channels)})\nMay the force be with you!!"
)
await ctx.author.send("**Method-2**\nIf you haven't found anything useful with Method-1, feel free to ask your question "
f"in any of the related help channels. ({', '.join(help_channels)})\nMay the force be with you!!")
else:
return await ctx.send(
"Session terminated. You can run this command again whenever you want."
)
return await ctx.send("Session terminated. You can run this command again whenever you want.")
def setup(bot):
bot.add_cog(BasicCommands(bot))

View File

@ -1,7 +1,6 @@
import discord
from discord.ext import commands
class BotManager:
def __init__(self, bot):
self.bot = bot
@ -12,16 +11,13 @@ class BotManager:
return
else:
# The member is a bot
await member.add_roles(discord.utils.get(member.guild.roles, name="Bots"))
bot_owner = member.guild.get_member((await self.bot.db_con.fetchval('select owner from bots where id = $1', member.id))
await bot_owner.add_roles(discord.utils.get(member.guild.roles, name='Bot Developers'))
await member.add_roles(discord.utils.get(member.guild.roles, name='Bots'))
try:
await member.edit(
nick="["
+ await self.bot.db_con.fetch(
"select prefix from bots where id = $1", member.id
)
+ "] "
+ member.name
)
await member.edit(nick='[' + await self.bot.db_con.fetchval('select prefix from bots where id = $1', member.id)
+ '] ' + member.name)
except:
pass
@ -31,69 +27,60 @@ class BotManager:
return
else:
# The member is a bot
await self.bot.db_con.execute("DELETE FROM bots WHERE id = $1", member.id)
await self.bot.db_con.execute('DELETE FROM bots WHERE id = $1', member.id)
async def on_member_ban(self, guild, user):
if member.bot is True:
return
else:
# I need to finish this
pass
@commands.command()
async def invite(self, ctx, bot=None, prefix=None):
bot = await ctx.bot.get_user_info(bot)
if not bot:
raise Warning(
"You must include the id of the bot you are trying to invite... Be exact."
)
raise Warning('You must include the id of the bot you are trying to invite... Be exact.')
if not bot.bot:
raise Warning("You can only invite bots.")
raise Warning('You can only invite bots.')
if not prefix:
raise Warning("Please provide a prefix")
raise Warning('Please provide a prefix')
# Make sure that the bot has not been invited already and it is not being tested
if (
await self.bot.db_con.fetch(
"select count(*) from bots where id = $1", bot.id
)
== 1
):
raise Warning("The bot has already been invited or is being tested")
if await self.bot.db_con.fetch('select count(*) from bots where id = $1', bot.id) == 1:
raise Warning('The bot has already been invited or is being tested')
await self.bot.db_con.execute(
"insert into bots (id, owner, prefix) values ($1, $2, $3)",
bot.id,
ctx.author.id,
prefix,
)
await self.bot.db_con.execute('insert into bots (id, owner, prefix) values ($1, $2, $3)',
bot.id, ctx.author.id, prefix)
em = discord.Embed(colour=self.bot.embed_color)
em.title = "Hello {},".format(ctx.author.name)
em.description = "Thanks for inviting your bot! It will be tested and invited shortly. " "Please open your DMs if they are not already so the bot can contact " "you to inform you about the progress of the bot!"
em.description = "Thanks for inviting your bot! It will be tested and invited shortly. " \
"Please open your DMs if they are not already so the bot can contact " \
"you to inform you about the progress of the bot!"
await ctx.send(embed=em)
em = discord.Embed(title="Bot invite", colour=discord.Color(0x363941))
em.description = discord.utils.oauth_url(client_id, permissions=None, guild=ctx.guild))
em.set_thumbnail(url=bot.avatar_url)
em.add_field(name="Bot name", value=bot.name)
em.add_field(name="Bot id", value="`" + str(bot.id) + "`")
em.add_field(name="Bot owner", value=ctx.author.mention)
em.add_field(name="Bot prefix", value="`" + prefix + "`")
await ctx.bot.get_channel(448803675574370304).send(embed=em)
await ctx.bot.get_channel(459280759945953300).send(embed=em)
@commands.command(name="claim", aliases=["makemine", "gimme"])
@commands.command(name='claim', aliases=['makemine', 'gimme'])
@commands.cooldown(1, 5, commands.BucketType.user)
async def _claim_bot(
self,
ctx,
bot: discord.Member = None,
prefix: str = None,
owner: discord.Member = None,
):
async def _claim_bot(self, ctx, bot: discord.Member = None, prefix: str = None, owner: discord.Member = None):
if not bot:
raise Warning(
"You must include the name of the bot you are trying to claim... Be exact."
)
raise Warning('You must include the name of the bot you are trying to claim... Be exact.')
if not bot.bot:
raise Warning("You can only claim bots.")
raise Warning('You can only claim bots.')
if not prefix:
if bot.display_name.startswith("["):
prefix = bot.display_name.split("]")[0].strip("[")
if bot.display_name.startswith('['):
prefix = bot.display_name.split(']')[0].strip('[')
else:
raise Warning("Prefix not provided and can't be found in bot nick.")
raise Warning('Prefix not provided and can\'t be found in bot nick.')
if owner is not None and ctx.author.guild_permissions.manage_roles:
author_id = owner.id
@ -102,126 +89,100 @@ class BotManager:
em = discord.Embed()
if (
await self.bot.db_con.fetchval(
"select count(*) from bots where owner = $1", author_id
)
>= 10
):
if await self.bot.db_con.fetchval('select count(*) from bots where owner = $1', author_id) >= 10:
em.colour = self.bot.error_color
em.title = "Too Many Bots Claimed"
em.description = "Each person is limited to claiming 10 bots as that is how " "many bots are allowed by the Discord API per user."
em.title = 'Too Many Bots Claimed'
em.description = 'Each person is limited to claiming 10 bots as that is how ' \
'many bots are allowed by the Discord API per user.'
return await ctx.send(embed=em)
existing = await self.bot.db_con.fetchrow(
"select * from bots where id = $1", bot.id
)
existing = await self.bot.db_con.fetchrow('select * from bots where id = $1', bot.id)
if not existing:
await self.bot.db_con.execute(
"insert into bots (id, owner, prefix) values ($1, $2, $3)",
bot.id,
author_id,
prefix,
)
await self.bot.db_con.execute('insert into bots (id, owner, prefix) values ($1, $2, $3)',
bot.id, author_id, prefix)
em.colour = self.bot.embed_color
em.title = "Bot Claimed"
em.description = f"You have claimed {bot.display_name} with a prefix of {prefix}\n" f"If there is an error please run command again to correct the prefix,\n" f"or {ctx.prefix}unclaim {bot.mention} to unclaim the bot."
elif existing["owner"] and existing["owner"] != author_id:
em.title = 'Bot Claimed'
em.description = f'You have claimed {bot.display_name} with a prefix of {prefix}\n' \
f'If there is an error please run command again to correct the prefix,\n' \
f'or {ctx.prefix}unclaim {bot.mention} to unclaim the bot.'
elif existing['owner'] and existing['owner'] != author_id:
em.colour = self.bot.error_color
em.title = "Bot Already Claimed"
em.description = "This bot has already been claimed by someone else.\n" "If this is actually your bot please let the guild Administrators know."
elif existing["owner"] and existing["owner"] == author_id:
em.title = 'Bot Already Claimed'
em.description = 'This bot has already been claimed by someone else.\n' \
'If this is actually your bot please let the guild Administrators know.'
elif existing['owner'] and existing['owner'] == author_id:
em.colour = self.bot.embed_color
em.title = "Bot Already Claimed"
em.description = "You have already claimed this bot.\n" "If the prefix you provided is different from what is already in the database" " it will be updated for you."
if existing["prefix"] != prefix:
await self.bot.db_con.execute(
"update bots set prefix = $1 where id = $2", prefix, bot.id
)
elif not existing["owner"]:
await self.bot.db_con.execute(
"update bots set owner = $1, prefix = $2 where id = $3",
author_id,
prefix,
bot.id,
)
em.title = 'Bot Already Claimed'
em.description = 'You have already claimed this bot.\n' \
'If the prefix you provided is different from what is already in the database' \
' it will be updated for you.'
if existing['prefix'] != prefix:
await self.bot.db_con.execute("update bots set prefix = $1 where id = $2", prefix, bot.id)
elif not existing['owner']:
await self.bot.db_con.execute('update bots set owner = $1, prefix = $2 where id = $3',
author_id, prefix, bot.id)
em.colour = self.bot.embed_color
em.title = "Bot Claimed"
em.description = f"You have claimed {bot.display_name} with a prefix of {prefix}\n" f"If there is an error please run command again to correct the prefix,\n" f"or {ctx.prefix}unclaim {bot.mention} to unclaim the bot."
em.title = 'Bot Claimed'
em.description = f'You have claimed {bot.display_name} with a prefix of {prefix}\n' \
f'If there is an error please run command again to correct the prefix,\n' \
f'or {ctx.prefix}unclaim {bot.mention} to unclaim the bot.'
else:
em.colour = self.bot.error_color
em.title = "Something Went Wrong..."
em.title = 'Something Went Wrong...'
await ctx.send(embed=em)
@commands.command(name="unclaim")
@commands.command(name='unclaim')
@commands.cooldown(1, 5, commands.BucketType.user)
async def _unclaim_bot(self, ctx, bot: discord.Member = None):
if not bot:
raise Warning(
"You must include the name of the bot you are trying to claim... Be exact."
)
raise Warning('You must include the name of the bot you are trying to claim... Be exact.')
if not bot.bot:
raise Warning("You can only unclaim bots.")
raise Warning('You can only unclaim bots.')
em = discord.Embed()
existing = await self.bot.db_con.fetchrow(
"select * from bots where id = $1", bot.id
)
if not existing or not existing["owner"]:
existing = await self.bot.db_con.fetchrow('select * from bots where id = $1', bot.id)
if not existing or not existing['owner']:
em.colour = self.bot.error_color
em.title = "Bot Not Found"
em.description = "That bot is not claimed"
elif (
existing["owner"] != ctx.author.id
and not ctx.author.guild_permissions.manage_roles
):
em.title = 'Bot Not Found'
em.description = 'That bot is not claimed'
elif existing['owner'] != ctx.author.id and not ctx.author.guild_permissions.manage_roles:
em.colour = self.bot.error_color
em.title = "Not Claimed By You"
em.description = "That bot is claimed by someone else.\n" "You can't unclaim someone else's bot"
em.title = 'Not Claimed By You'
em.description = 'That bot is claimed by someone else.\n' \
'You can\'t unclaim someone else\'s bot'
else:
await self.bot.db_con.execute(
"update bots set owner = null where id = $1", bot.id
)
await self.bot.db_con.execute('update bots set owner = null where id = $1', bot.id)
em.colour = self.bot.embed_color
em.title = "Bot Unclaimed"
em.description = f"You have unclaimed {bot.display_name}\n" f"If this is an error please reclaim using\n" f'{ctx.prefix}claim {bot.mention} {existing["prefix"]}'
em.title = 'Bot Unclaimed'
em.description = f'You have unclaimed {bot.display_name}\n' \
f'If this is an error please reclaim using\n' \
f'{ctx.prefix}claim {bot.mention} {existing["prefix"]}'
await ctx.send(embed=em)
@commands.command(name="listclaims", aliases=["claimed", "mybots"])
@commands.command(name='listclaims', aliases=['claimed', 'mybots'])
@commands.cooldown(1, 5, commands.BucketType.user)
async def _claimed_bots(self, ctx, usr: discord.Member = None):
if usr is None:
usr = ctx.author
bots = await self.bot.db_con.fetch(
"select * from bots where owner = $1", usr.id
)
bots = await self.bot.db_con.fetch('select * from bots where owner = $1', usr.id)
if bots:
em = discord.Embed(
title=f"{usr.display_name} has claimed the following bots:",
colour=self.bot.embed_color,
)
em = discord.Embed(title=f'{usr.display_name} has claimed the following bots:',
colour=self.bot.embed_color)
for bot in bots:
member = ctx.guild.get_member(int(bot["id"]))
em.add_field(
name=member.display_name,
value=f'Stored Prefix: {bot["prefix"]}',
inline=False,
)
member = ctx.guild.get_member(int(bot['id']))
em.add_field(name=member.display_name, value=f'Stored Prefix: {bot["prefix"]}', inline=False)
else:
em = discord.Embed(
title="You have not claimed any bots.", colour=self.bot.embed_color
)
em = discord.Embed(title='You have not claimed any bots.',
colour=self.bot.embed_color)
await ctx.send(embed=em)
@commands.command(name="whowns")
@commands.command(name='whowns')
async def _whowns(self, ctx, bot: discord.Member):
if not bot.bot:
await ctx.send("this commands only for bots")
await ctx.send('this commands only for bots')
else:
owner = await self.bot.db_con.fetchrow(
"select * from bots where id = $1", bot.id
)
await ctx.send(ctx.guild.get_member(owner["owner"]).display_name)
owner = await self.bot.db_con.fetchrow('select * from bots where id = $1', bot.id)
await ctx.send(ctx.guild.get_member(owner['owner']).display_name)
def setup(bot):

View File

@ -1,68 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
from discord.ext import commands
import discord
import asyncio
class BasicCommands:
def __init__(self, bot):
self.bot = bot
@commands.command()
async def tutorial(self, ctx):
await ctx.send(f"Hello, {ctx.author.display_name}. Welcome to Sebi's Bot Tutorials. \nFirst off, would you like a quick walkthrough on the server channels?")
channel_list = {'channel-1' : self.bot.get_channel(333149949883842561).mention,
'd.py-rewrite-start' : self.bot.get_channel(386419285439938560).mention,
'js-klasa-start' : self.bot.get_channel(341816240186064897).mention,
'async2rewrite-start' : self.bot.get_channel(392223495389577217).mention,
'd.js' : self.bot.get_channel(436771798303113217).mention}
bots_channels = (self.bot.get_channel(339112602867204097).mention,
self.bot.get_channel(411586546551095296).mention)
help_channels = (self.bot.get_channel(425315253153300488).mention,
self.bot.get_channel(392215236612194305).mention,
self.bot.get_channel(351034776985141250).mention)
def check(m):
return True if m.author.id == ctx.author.id and m.channel.id == ctx.channel.id else False
msg = await self.bot.wait_for('message', check = check, timeout = 15)
agree = ("yes", "yep", "non't", "ya", "ye", "yup", "ok", "why not")
if msg is None:
await ctx.send("Sorry, {ctx.author.mention}, you didn't reply on time. You can run the command again when you're free :)")
else:
if msg.content.lower() in agree:
async with ctx.typing():
await ctx.send("Alrighty-Roo... Check your DMs!")
await ctx.author.send("Alrighty-Roo...")
await ctx.author.send(f"To start making your bot from scratch, you first need to head over to {channel_list['channel-1']}"
" (Regardless of the language you're gonna use).")
await asyncio.sleep(0.5)
await ctx.author.send(f"After you have a bot account, you can either continue with {channel_list['d.py-rewrite-start']} "
f"if you want to make a bot in discord.py rewrite __or__ go to {channel_list['js-klasa-start']} or "
f"{channel_list['d.js']} for making a bot in JavaScript."
f"If you already have old Discord.py async code and you want to use it with the new Rewrite versions, head to {channel_list['async2rewrite-start']}")
await ctx.author.send("...Read all the tutorials and still need help? You have two ways to get help.")
await asyncio.sleep(1.5)
await ctx.author.send("**Method-1**\nThis is the best method of getting help. You help yourself.\n"
f"To do so, head over to a bots dedicated channel (either {bots_channels[0]} or {bots_channels[1]})"
" and type `?rtfm rewrite thing_you_want_help_with`.\nThis will trigger the bot R.Danny Bot and will "
"give you links on your query on the official discord.py rewrite docs. *PS: Let the page completely load*")
await asyncio.sleep(5)
await ctx.author.send("**Method-2**\nIf you haven't found anything useful with Method-1, feel free to ask your question "
f"in any of the related help channels. ({', '.join(help_channels)})\nMay the force be with you!!")
else:
return await ctx.send("Session terminated. You can run this command again whenever you want.")
def setup(bot):
bot.add_cog(BasicCommands(bot))

View File

@ -1,189 +0,0 @@
import discord
from discord.ext import commands
class BotManager:
def __init__(self, bot):
self.bot = bot
async def on_member_join(self, member):
# If the member is not a bot
if member.bot is False:
return
else:
# The member is a bot
bot_owner = member.guild.get_member((await self.bot.db_con.fetchval('select owner from bots where id = $1', member.id))
await bot_owner.add_roles(discord.utils.get(member.guild.roles, name='Bot Developers'))
await member.add_roles(discord.utils.get(member.guild.roles, name='Bots'))
try:
await member.edit(nick='[' + await self.bot.db_con.fetchval('select prefix from bots where id = $1', member.id)
+ '] ' + member.name)
except:
pass
async def on_member_remove(self, member):
# If the member is not a bot
if member.bot is False:
return
else:
# The member is a bot
await self.bot.db_con.execute('DELETE FROM bots WHERE id = $1', member.id)
async def on_member_ban(self, guild, user):
if member.bot is True:
return
else:
# I need to finish this
pass
@commands.command()
async def invite(self, ctx, bot=None, prefix=None):
bot = await ctx.bot.get_user_info(bot)
if not bot:
raise Warning('You must include the id of the bot you are trying to invite... Be exact.')
if not bot.bot:
raise Warning('You can only invite bots.')
if not prefix:
raise Warning('Please provide a prefix')
# Make sure that the bot has not been invited already and it is not being tested
if await self.bot.db_con.fetch('select count(*) from bots where id = $1', bot.id) == 1:
raise Warning('The bot has already been invited or is being tested')
await self.bot.db_con.execute('insert into bots (id, owner, prefix) values ($1, $2, $3)',
bot.id, ctx.author.id, prefix)
em = discord.Embed(colour=self.bot.embed_color)
em.title = "Hello {},".format(ctx.author.name)
em.description = "Thanks for inviting your bot! It will be tested and invited shortly. " \
"Please open your DMs if they are not already so the bot can contact " \
"you to inform you about the progress of the bot!"
await ctx.send(embed=em)
em = discord.Embed(title="Bot invite", colour=discord.Color(0x363941))
em.description = discord.utils.oauth_url(client_id, permissions=None, guild=ctx.guild))
em.set_thumbnail(url=bot.avatar_url)
em.add_field(name="Bot name", value=bot.name)
em.add_field(name="Bot id", value="`" + str(bot.id) + "`")
em.add_field(name="Bot owner", value=ctx.author.mention)
em.add_field(name="Bot prefix", value="`" + prefix + "`")
await ctx.bot.get_channel(459280759945953300).send(embed=em)
@commands.command(name='claim', aliases=['makemine', 'gimme'])
@commands.cooldown(1, 5, commands.BucketType.user)
async def _claim_bot(self, ctx, bot: discord.Member = None, prefix: str = None, owner: discord.Member = None):
if not bot:
raise Warning('You must include the name of the bot you are trying to claim... Be exact.')
if not bot.bot:
raise Warning('You can only claim bots.')
if not prefix:
if bot.display_name.startswith('['):
prefix = bot.display_name.split(']')[0].strip('[')
else:
raise Warning('Prefix not provided and can\'t be found in bot nick.')
if owner is not None and ctx.author.guild_permissions.manage_roles:
author_id = owner.id
else:
author_id = ctx.author.id
em = discord.Embed()
if await self.bot.db_con.fetchval('select count(*) from bots where owner = $1', author_id) >= 10:
em.colour = self.bot.error_color
em.title = 'Too Many Bots Claimed'
em.description = 'Each person is limited to claiming 10 bots as that is how ' \
'many bots are allowed by the Discord API per user.'
return await ctx.send(embed=em)
existing = await self.bot.db_con.fetchrow('select * from bots where id = $1', bot.id)
if not existing:
await self.bot.db_con.execute('insert into bots (id, owner, prefix) values ($1, $2, $3)',
bot.id, author_id, prefix)
em.colour = self.bot.embed_color
em.title = 'Bot Claimed'
em.description = f'You have claimed {bot.display_name} with a prefix of {prefix}\n' \
f'If there is an error please run command again to correct the prefix,\n' \
f'or {ctx.prefix}unclaim {bot.mention} to unclaim the bot.'
elif existing['owner'] and existing['owner'] != author_id:
em.colour = self.bot.error_color
em.title = 'Bot Already Claimed'
em.description = 'This bot has already been claimed by someone else.\n' \
'If this is actually your bot please let the guild Administrators know.'
elif existing['owner'] and existing['owner'] == author_id:
em.colour = self.bot.embed_color
em.title = 'Bot Already Claimed'
em.description = 'You have already claimed this bot.\n' \
'If the prefix you provided is different from what is already in the database' \
' it will be updated for you.'
if existing['prefix'] != prefix:
await self.bot.db_con.execute("update bots set prefix = $1 where id = $2", prefix, bot.id)
elif not existing['owner']:
await self.bot.db_con.execute('update bots set owner = $1, prefix = $2 where id = $3',
author_id, prefix, bot.id)
em.colour = self.bot.embed_color
em.title = 'Bot Claimed'
em.description = f'You have claimed {bot.display_name} with a prefix of {prefix}\n' \
f'If there is an error please run command again to correct the prefix,\n' \
f'or {ctx.prefix}unclaim {bot.mention} to unclaim the bot.'
else:
em.colour = self.bot.error_color
em.title = 'Something Went Wrong...'
await ctx.send(embed=em)
@commands.command(name='unclaim')
@commands.cooldown(1, 5, commands.BucketType.user)
async def _unclaim_bot(self, ctx, bot: discord.Member = None):
if not bot:
raise Warning('You must include the name of the bot you are trying to claim... Be exact.')
if not bot.bot:
raise Warning('You can only unclaim bots.')
em = discord.Embed()
existing = await self.bot.db_con.fetchrow('select * from bots where id = $1', bot.id)
if not existing or not existing['owner']:
em.colour = self.bot.error_color
em.title = 'Bot Not Found'
em.description = 'That bot is not claimed'
elif existing['owner'] != ctx.author.id and not ctx.author.guild_permissions.manage_roles:
em.colour = self.bot.error_color
em.title = 'Not Claimed By You'
em.description = 'That bot is claimed by someone else.\n' \
'You can\'t unclaim someone else\'s bot'
else:
await self.bot.db_con.execute('update bots set owner = null where id = $1', bot.id)
em.colour = self.bot.embed_color
em.title = 'Bot Unclaimed'
em.description = f'You have unclaimed {bot.display_name}\n' \
f'If this is an error please reclaim using\n' \
f'{ctx.prefix}claim {bot.mention} {existing["prefix"]}'
await ctx.send(embed=em)
@commands.command(name='listclaims', aliases=['claimed', 'mybots'])
@commands.cooldown(1, 5, commands.BucketType.user)
async def _claimed_bots(self, ctx, usr: discord.Member = None):
if usr is None:
usr = ctx.author
bots = await self.bot.db_con.fetch('select * from bots where owner = $1', usr.id)
if bots:
em = discord.Embed(title=f'{usr.display_name} has claimed the following bots:',
colour=self.bot.embed_color)
for bot in bots:
member = ctx.guild.get_member(int(bot['id']))
em.add_field(name=member.display_name, value=f'Stored Prefix: {bot["prefix"]}', inline=False)
else:
em = discord.Embed(title='You have not claimed any bots.',
colour=self.bot.embed_color)
await ctx.send(embed=em)
@commands.command(name='whowns')
async def _whowns(self, ctx, bot: discord.Member):
if not bot.bot:
await ctx.send('this commands only for bots')
else:
owner = await self.bot.db_con.fetchrow('select * from bots where id = $1', bot.id)
await ctx.send(ctx.guild.get_member(owner['owner']).display_name)
def setup(bot):
bot.add_cog(BotManager(bot))

View File

@ -1,62 +0,0 @@
#!/usr/bin/python
# -*- coding: utf-8 -*-
from discord.ext import commands
import discord
class Moderation:
"""
Moderation Commands
"""
def __init__(self, bot):
self.bot = bot
@commands.command()
async def kick(self, ctx, member: discord.Member = None):
"""
Kick a discord member from your server.
Only contributors can use this command.
Usage:
- kick <discord.member>
"""
await ctx.trigger_typing()
if ctx.author.id not in self.bot.ownerlist:
return await ctx.send('Only my contributors can use me like this :blush:', delete_after=10)
if member is None:
await ctx.send('Are you sure you are capable of this command?')
try:
await member.kick()
await ctx.send(f'You kicked **`{member.name}`** from **`{ctx.guild.name}`**')
except Exception as e:
await ctx.send('You may not use this command, as you do not have permission to do so:\n\n**`{ctx.guild.name}`**'
f'\n\n```py\n{e}\n```')
@commands.command()
async def ban(self, ctx, member: discord.Member = None):
"""
Ban a discord member from your server.
Only contributors can use this command.
Usage:
- ban <discord.member>
"""
await ctx.trigger_typing()
if ctx.author.id not in self.bot.ownerlist:
return await ctx.send('Only my contributors can use me like this :blush:', delete_after=10)
if member is None:
await ctx.send('Are you sure you are capable of this command?')
try:
await member.ban()
await ctx.send(f'You banned **`{member.name}`** from **`{ctx.guild.name}`**')
except Exception as e:
await ctx.send('You may not use this command, as you do not have permission to do so:\n\n**`{ctx.guild.name}`**'
f'\n\n```py\n{e}\n```')
def setup(bot):
bot.add_cog(Moderation(bot))

View File

@ -1,306 +0,0 @@
import asyncio
import inspect
import traceback
import weakref
from typing import Dict
import async_timeout
import dataclasses
import discord
from discord.ext import commands
import youtube_dl
# noinspection PyUnresolvedReferences,PyUnresolvedReferences,PyPackageRequirements
from . utils import noblock
YT_DL_OPTS = {
"format": 'mp3[abr>0]/bestaudio/best',
"ignoreerrors": True,
"default_search": "auto",
"source_address": "0.0.0.0",
'quiet': True
}
# Let it be waiting on an empty queue for about 30 minutes
# before closing the connection from being idle.
IDLE_FOR = 60 * 30
@dataclasses.dataclass(repr=True)
class Request:
"""Track request."""
who: discord.Member
what: str # Referral
title: str # Video title
actual_url: str # Actual URL to play
def __str__(self):
return self.title
def __hash__(self):
return hash(str(self.who.id) + self.what)
# noinspection PyBroadException
class Session:
"""
Each player being run is a session; (E.g. if you open a player in one server and I did in another).
Sessions will have a queue, an event that can fire to stop the current track and move on, and a voice
channel to bind to. This is defined as the voice channel the owner of the session was in when they made the channel.
To create a session, call ``Session.new_session``. Do not call the constructor directly.
Attributes:
ctx: discord.ext.commands.Context
The context of the original command invocation we are creating a session for.
loop: asyncio.AbstractEventLoop
The event loop to run this in.
voice_client: discord.VoiceClient
Voice client we are streaming audio through.
queue: asyncio.Queue
Track queue.
"""
@classmethod
async def new_session(cls, ctx: commands.Context):
"""
Helper to make a new session. Invoke constructor using this, as it handles any errors. It also ensures
we connect immediately.
"""
try:
s = cls(ctx)
await s.connect()
except Exception as ex:
traceback.print_exc()
await ctx.send(f"I couldn't connect! Reason: {str(ex) or type(ex).__qualname__}")
return None
else:
return s
def __init__(self, ctx: commands.Context) -> None:
"""Create a new session."""
if ctx.author.voice is None:
raise RuntimeError('Please enter a voice channel I have access to first.')
# Holds the tasks currently running associated with this.
self.voice_channel = ctx.author.voice.channel
self.ctx: commands.Context = ctx
self.voice_client: discord.VoiceClient = None
self.loop: asyncio.AbstractEventLoop = weakref.proxy(self.ctx.bot.loop)
self.queue = asyncio.Queue()
# Lock-based event to allow firing a handler to advance to the next track.
self._start_next_track_event = asyncio.Event()
self._on_stop_event = asyncio.Event()
self._player: asyncio.Task = None
self._track: asyncio.Task = None
@property
def is_connected(self) -> bool:
return self.voice_client and self.voice_client.is_connected()
async def connect(self) -> None:
"""Connects to the VC."""
if not self.is_connected and not self._player:
# noinspection PyUnresolvedReferences
self.voice_client = await self.voice_channel.connect()
self._start_next_track_event.clear()
self._player = self.__spawn_player()
else:
raise RuntimeError('I already have a voice client/player running.')
async def disconnect(self) -> None:
"""Disconnects from the VC."""
await self.voice_client.disconnect()
self.voice_client = None
def __spawn_player(self) -> asyncio.Task:
"""Starts a new player."""
async def player():
try:
while True:
# Wait on an empty queue for a finite period of time.
with async_timeout.timeout(IDLE_FOR):
request = await self.queue.get()
await self.ctx.send(f'Playing `{request}` requested by {request.who}')
# Clear the skip event if it is set.
self._start_next_track_event.clear()
# Start the player if it was a valid request, else continue to the next track.
if not self.__play(request.actual_url):
await self.ctx.send(f'{request.referral} was a bad request and was skipped.')
continue
await self._start_next_track_event.wait()
if self.voice_client.is_playing():
self.voice_client.stop()
except asyncio.CancelledError:
# Hit when someone kills the player using stop().
print('Requested to stop player', repr(self))
except asyncio.TimeoutError:
await self.ctx.send('Was idle for too long...')
print('Player queue was empty for too long and was stopped', repr(self))
except Exception:
traceback.print_exc()
finally:
if self.voice_client.is_playing():
await self.voice_client.stop()
if self.is_connected:
await self.disconnect()
return self.loop.create_task(player())
def __play(self, url):
"""Tries to play the given URL. If it fails, we return False, else we return True."""
try:
ffmpeg_player = discord.FFmpegPCMAudio(url)
# Play the stream. After we finish, either from being cancelled or otherwise, fire the
# skip track event to start the next track.
self.voice_client.play(ffmpeg_player, after=lambda error: self._start_next_track_event.set())
except Exception:
traceback.print_exc()
return False
else:
return True
def skip(self):
"""Request to skip track."""
self._start_next_track_event.set()
def stop(self):
"""Request to stop playing."""
if self._player:
self._player.cancel()
self._on_stop_event.set()
self._on_stop_event.clear()
def on_exit(self, func):
"""Decorates a function to invoke it on exit."""
async def callback():
await self._on_stop_event.wait()
inspect.iscoroutinefunction(func) and await func() or func()
self.loop.create_task(callback())
return func
# noinspection PyBroadException
class PlayerCog:
def __init__(self):
self.sessions: Dict[discord.Guild, Session] = {}
# noinspection PyMethodMayBeStatic
async def __local_check(self, ctx):
return ctx.guild
@commands.command()
async def join(self, ctx):
if ctx.guild not in self.sessions:
p = await Session.new_session(ctx)
if p:
self.sessions[ctx.guild] = p
@p.on_exit
def when_terminated():
try:
self.sessions.pop(ctx.guild)
finally:
return
await ctx.send("*hacker voice*\n**I'm in.**", delete_after=15)
else:
await ctx.send(f'I am already playing in {self.sessions[ctx.guild].voice_channel.mention}')
# noinspection PyNestedDecorators
@staticmethod
@noblock.no_block
def _get_video_meta(referral):
downloader = youtube_dl.YoutubeDL(YT_DL_OPTS)
info = downloader.extract_info(referral, download=False)
return info
@commands.command()
async def queue(self, ctx):
if ctx.guild not in self.sessions:
return await ctx.send('Please join me into a voice channel first.')
sesh = self.sessions[ctx.guild]
if sesh.queue.empty():
return await ctx.send(
'There is nothing in the queue at the moment!\n\n'
'Add something by running `<>play https://url` or `<>play search term`!')
# We cannot faff around with the actual queue so make a shallow copy of the internal
# non-async dequeue.
# noinspection PyProtectedMember
agenda = sesh.queue._queue.copy()
message = ['**Queue**']
for i, item in enumerate(list(agenda)[:15]):
message.append(f'`{i+1: >2}: {item.title} ({item.who})`')
if len(agenda) >= 15:
message.append('')
message.append(f'There are {len(agenda)} items in the queue currently.')
await ctx.send('\n'.join(message)[:2000])
@commands.command()
async def play(self, ctx, *, referral):
if ctx.guild not in self.sessions:
return await ctx.send('Please join me into a voice channel first.')
try:
try:
info = await self._get_video_meta(referral)
# If it was interpreted as a search, it appears this happens?
# The documentation is so nice.
if info.get('_type') == 'playlist':
info = info['entries'][0]
# ...wait... did I say nice? I meant "non existent."
url = info['url']
title = info.get('title') or referral
except IndexError:
return await ctx.send('No results...', delete_after=15)
except Exception as ex:
return await ctx.send(f"Couldn't add this to the queue... reason: {ex!s}")
await self.sessions[ctx.guild].queue.put(Request(ctx.author, referral, title, url))
await ctx.send(f'Okay. Queued `{title or referral}`.')
except KeyError:
await ctx.send('I am not playing in this server.')
@commands.command()
async def stop(self, ctx):
try:
await self.sessions[ctx.guild].stop()
except KeyError:
await ctx.send('I am not playing in this server.')
except TypeError:
await ctx.send("I wasn't playing anything, but okay.", delete_after=15)
@commands.command()
async def skip(self, ctx):
try:
self.sessions[ctx.guild].skip()
try:
await ctx.message.add_reaction('\N{OK HAND SIGN}')
except discord.Forbidden:
await ctx.send('\N{OK HAND SIGN}')
except KeyError:
await ctx.send('I am not playing in this server.')
@commands.command()
async def disconnect(self, ctx):
await self.sessions[ctx.guild].stop()
await self.disconnect()
def setup(bot):
bot.add_cog(PlayerCog())