def _signup_lottery(self, ctx):
"""Signs you up to track lottery stats.
You must have the required role to sign-up for stat tracking.
If you lose the role, or it changes your stats will still be tracked
and the information can be viewed when you get the role again.
By default, anyone can sign up.
"""
author = ctx.message.author
settings = self.check_server_settings(author.server)
if author.id in settings["Members"]:
return await self.bot.say("You are already signed-up to track stats.")
role = settings["Config"]["Role"]
if role not in [r.name for r in author.roles]:
return await self.bot.say("You do not have the required role to track stats.")
settings["Members"][author.id] = {"Name": author.name, "Entries": 0, "Won": 0}
self.save_system()
await self.bot.say("Congratulations {}, you can now start tracking your lottery stats. "
"To view your stats use the command "
"{}lottery stats.".format(author.name, ctx.prefix))
python类Role()的实例源码
def _stats_lottery(self, ctx):
"""Shows your lottery stats
Shows the number of times you have entered and the number
of times you have won a lottery."""
author = ctx.message.author
settings = self.check_server_settings(author.server)
if author.id not in settings["Members"]:
return await self.bot.say("You are not a lottery member. Only members can view and "
"track stats. Use [p]lottery signup to join.")
role = settings["Config"]["Role"]
if role not in [r.name for r in author.roles]:
return await self.bot.say("You do not have the required role to view stats.")
played = settings["Members"][author.id]["Entries"]
won = settings["Members"][author.id]["Won"]
embed = discord.Embed(description="Lottery Stat Tracker", color=0x50bdfe)
embed.set_author(name=author.name)
embed.set_thumbnail(url=author.avatar_url)
embed.add_field(name="Entries", value=played, inline=True)
embed.add_field(name="Won", value=won, inline=True)
await self.bot.say(embed=embed)
def _role_setlottery(self, ctx, role: discord.Role):
"""Sets the role required to track and view stats.
Must be a role that exists on your server. If you delete this role
you will need to update lottery with this command to the new role.
Otherwise, no one will be able to view their stats, but it will still
track if they were able to signup.
By default this command is set to @everyone, and anyone can join.
"""
server = ctx.message.server
settings = self.check_server_settings(server)
settings["Config"]["Role"] = role.name
self.save_system()
await self.bot.say("Changed the membership role to {}".format(role.name))
# ================== Helper Functions ===================================
def inventory(self, ctx):
"""Shows a list of items you have purchased"""
user = ctx.message.author
settings = self.check_server_settings(user.server)
self.user_check(settings, user)
title = "```{}```".format(self.bordered("{}'s\nI N V E N T O R Y".format(user.name)))
if not settings["Users"][user.id]["Inventory"]:
return await self.bot.say("Your inventory is empty.")
column1 = ["[{}]".format(subdict["Item Name"].title())
if "Role" in subdict else subdict["Item Name"].title()
for subdict in settings["Users"][user.id]["Inventory"].values()
]
column2 = [subdict["Item Quantity"]
for subdict in settings["Users"][user.id]["Inventory"].values()
]
headers = ["Item Name", "Item Quantity"]
data = sorted(list(zip(column1, column2)))
method = settings["Config"]["Inventory Output Method"]
msg = await self.inventory_split(user, title, headers, data, method)
if method == "Chat":
await self.bot.say(msg)
else:
await self.bot.whisper(msg)
def _list_shop(self, ctx):
"""Shows a list of all the shop items. Roles are blue."""
user = ctx.message.author
settings = self.check_server_settings(user.server)
shop_name = settings["Config"]["Shop Name"]
column1 = ["[{}]".format(subdict["Item Name"].title())
if "Role" in subdict else subdict["Item Name"].title()
for subdict in settings["Shop List"].values()]
column2 = [subdict["Quantity"] for subdict in settings["Shop List"].values()]
column3 = [subdict["Item Cost"] for subdict in settings["Shop List"].values()]
column4_raw = [subdict["Discount"] for subdict in settings["Shop List"].values()]
column4 = [x + "%" if x != "0" else "None" for x in list(map(str, column4_raw))]
if not column1:
await self.bot.say("There are no items for sale in the shop.")
else:
data, header = self.table_builder(settings, column1, column2,
column3, column4, shop_name)
msg = await self.shop_table_split(user, data)
await self.shop_list_output(settings, msg, header)
def redeem_handler(self, settings, ctx, user, itemname, confirmation):
time_now = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
item_dict = {"Name": user.name, "Confirmation Number": confirmation, "Status": "Pending",
"Time Stamp": time_now, "Item": itemname}
if "Role" in settings["Users"][user.id]["Inventory"][itemname]:
if "Buyrole" in self.bot.cogs:
roleid = settings["Users"][user.id]["Inventory"][itemname]["Role"]
role = [role for role in ctx.message.server.roles if roleid == role.id][0]
await self.bot.add_roles(user, role)
return True
else:
raise RuntimeError('I need the buyrole cog to process this request.')
elif user.id in settings["Pending"]:
if len(settings["Pending"][user.id].keys()) <= 12:
settings["Pending"][user.id][confirmation] = item_dict
dataIO.save_json(self.file_path, self.system)
return True
else:
return False
else:
settings["Pending"][user.id] = {}
settings["Pending"][user.id][confirmation] = item_dict
dataIO.save_json(self.file_path, self.system)
return True
def shop_item_add(self, settings, itemname, cost, quantity, role=False):
if role is False:
item = itemname.title()
settings["Shop List"][item] = {"Item Name": itemname, "Item Cost": cost,
"Discount": 0, "Members Only": "No",
"Buy Msg": []}
else:
item = str(itemname.name).title()
settings["Shop List"][item] = {"Item Name": item, "Item Cost": cost,
"Discount": 0, "Members Only": "No",
"Role": itemname.id, "Buy Msg": []}
if quantity == 0:
settings["Shop List"][item]["Quantity"] = "?"
else:
settings["Shop List"][item]["Quantity"] = quantity
dataIO.save_json(self.file_path, self.system)
def check_server_settings(self, server):
if server.id not in self.system["Servers"]:
self.system["Servers"][server.id] = {"Shop List": {},
"Users": {},
"Pending": {},
"Config": {"Shop Name": "Jumpman's",
"Shop Open": True,
"Shop Notify": False,
"Shop Role": None,
"Trade Cooldown": 30,
"Store Output Method": "Chat",
"Inventory Output Method": "Chat",
"Sort Method": "Alphabet",
"Member Discount": None,
"Pending Type": "Manual"}
}
dataIO.save_json(self.file_path, self.system)
print("Creating default Shop settings for Server: {}".format(server.name))
path = self.system["Servers"][server.id]
return path
else:
path = self.system["Servers"][server.id]
if "Shop Role" not in path["Config"]:
path["Config"]["Shop Role"] = None
return path
def getoff(self, ctx, role):
"""Removes a giveme from you, by name which should be defined in [p]giveme list."""
if ctx.message.server.id not in self.settings:
await self.bot.say("This server has no giveme's I can remove.")
elif role not in list(self.settings[ctx.message.server.id]['givemes'].keys()):
await self.bot.say("That's not a valid giveme.")
else:
try:
if not ctx.message.server.me.permissions_in(ctx.message.channel).manage_roles:
await self.bot.say("I do not have the manage roles permission here, I cannot remove roles from you untill I do.")
else:
role = discord.utils.get(ctx.message.server.roles, id=self.settings[ctx.message.server.id]['givemes'][role])
await self.bot.remove_roles(ctx.message.author, role)
await self.bot.say("Role removed.")
except Exception as e:
await self.bot.say("An error occured while remove the role from you ({}).".format(e))
def new_role(self, role, guild=None):
"""Creates a new Dwarf ?Role? object and connects it to the database.
Parameters
----------
role
Can be a Discord ?Role? object or a role ID.
guild : Optional
Can be a Discord ?Server? object or a guild ID.
Is not an optional parameter if ?role? is not a Discord ?Role? object.
"""
if isinstance(role, discord.Role):
return Role(id=role.id)
else:
if guild is None:
raise ValueError("Either a Role object or both role ID "
"and guild ID must be given as argument(s)")
return Role(id=role)
def base_command(self, ctx, *roles: discord.Role):
"""Base command for all opt-ins. With no subcommand, it functions like optin add."""
if not roles:
return await ctx.send('BAKA! You must specify roles!')
settings = ctx.get(GuildOptins, id=ctx.guild.id).one_or_none()
if settings is None or not settings.optin_roles:
return await ctx.send('BAKA! This guild has no optins!')
optin_ids = {optin.id for optin in settings.optin_roles}
optin_roles = {role for role in roles if role.id in optin_ids}
already_have = optin_roles & set(ctx.author.roles)
given = optin_roles - already_have
await ctx.author.add_roles(*given)
responses = []
if given:
responses.append('You have opted into {}.'.format(format.list(role.name for role in given)))
if already_have:
responses.append('BAKA! You have already opted into {}!'.format(format.list(role.name for role in already_have)))
if len(optin_roles) < len(roles):
responses.append('BAKA! {}!'.format(format.list((role.name for role in set(roles) - optin_roles), ' is not an optin', ' are not optins')))
await ctx.send('\n'.join(responses)) # One or more of the above is always true
def remove(self, ctx, *roles: discord.Role):
"""Takes the named opt-ins from you."""
if not roles:
return await ctx.send('BAKA! You must specify roles!')
settings = ctx.get(GuildOptins, id=ctx.guild.id).one_or_none()
if settings is None or not settings.optin_roles:
return await ctx.send('BAKA! This guild has no optins!')
optin_ids = {optin.id for optin in settings.optin_roles}
optin_roles = {role for role in roles if role.id in optin_ids}
removed = optin_roles & set(ctx.author.roles)
dont_have = optin_roles - removed
await ctx.author.remove_roles(*removed)
responses = []
if removed:
responses.append('You have opted out of {}.'.format(format.list(role.name for role in removed)))
if dont_have:
responses.append('BAKA! You have not opted into {}!'.format(format.list(role.name for role in dont_have)))
if len(optin_roles) < len(roles):
responses.append('BAKA! {}!'.format(format.list((role.name for role in set(roles) - optin_roles), ' is not an optin', ' are not optins')))
await ctx.send('\n'.join(responses)) # One or more of the above is always true
def protect_common(self, obj, protect=True):
if not isinstance(obj, (discord.Member, discord.Role)):
raise TypeError('Can only pass member or role objects.')
server = obj.server
id = ('r' if type(obj) is discord.Role else '') + obj.id
protected = self.duelists.get(server.id, {}).get("protected", [])
if protect == (id in protected):
return False
elif protect:
protected.append(id)
else:
protected.remove(id)
if server.id not in self.duelists:
self.duelists[server.id] = {}
self.duelists[server.id]['protected'] = protected
dataIO.save_json(JSON_PATH, self.duelists)
return True
def pingrole(self, ctx, role: discord.Role, *, message):
"""
Temporarily edits a role to be pingable, sends a message mentioning said role, then edits it to be
unpingable.
The role must be below my highest role.
"""
if role.position >= ctx.guild.me.top_role.position:
return await ctx.send("I can't edit that role because it's above my highest role.")
try:
await role.edit(mentionable=True, reason=f'Pingrole by {describe(ctx.author)}')
await ctx.send(f'{role.mention}: {message}')
finally:
try:
await role.edit(mentionable=False, reason=f'Pingrole by {describe(ctx.author)}')
except discord.HTTPException:
pass
def add(self, ctx: DogbotContext, type: AutoroleType, *roles: discord.Role):
"""Adds autoroles."""
for role in roles:
if role.position > ctx.guild.me.top_role.position:
await ctx.send('I can\'t autorole the role \"{0.name}\". It\'s too high on the role list. Move my '
'role above it.'.format(role))
return
log.debug('Adding autorole. (type=%s, roles=%s)', type, roles)
try:
async with ctx.acquire() as conn:
await conn.execute('INSERT INTO autoroles (guild_id, type, roles) VALUES ($1, $2, $3)', ctx.guild.id,
type.name, list(map(lambda r: r.id, roles)))
except asyncpg.UniqueViolationError:
return await ctx.send('There\'s already autoroles for that type on this server.')
await ctx.ok()
def on_member_autorole(self, member: discord.Member, roles_added: 'List[discord.Role]'):
# make embed
msg = (f'\N{BOOKMARK} Automatically assigned roles to {describe(member)}' if isinstance(roles_added, list) else
f'\N{CLOSED BOOK} Failed to automatically assign roles for {describe(member)}')
if roles_added:
# if roles were added, add them to the message
msg += ', added roles: ' + ', '.join(describe(role) for role in roles_added)
# make sure to add to debounce so we don't spew out "roles updated" messages
self.autorole_debounces.add(
role_ids=[role.id for role in roles_added],
member_id=member.id
)
await self.log(member.guild, msg)
def colour(self, ctx, role: discord.Role, value: discord.Colour):
"""Edits a role's colour
Use double quotes if the role contains spaces.
Colour must be in hexadecimal format.
\"http://www.w3schools.com/colors/colors_picker.asp\"
Examples:
!editrole colour \"The Transistor\" #ff0000
!editrole colour Test #ff9900"""
author = ctx.message.author
try:
await self.bot.edit_role(ctx.message.server, role, color=value)
logger.info("{}({}) changed the colour of role '{}'".format(
author.name, author.id, role.name))
await self.bot.say("Done.")
except discord.Forbidden:
await self.bot.say("I need permissions to manage roles first.")
except Exception as e:
print(e)
await self.bot.say("Something went wrong.")
def edit_role_name(self, ctx, role: discord.Role, name: str):
"""Edits a role's name
Use double quotes if the role or the name contain spaces.
Examples:
!editrole name \"The Transistor\" Test"""
if name == "":
await self.bot.say("Name cannot be empty.")
return
try:
author = ctx.message.author
old_name = role.name # probably not necessary?
await self.bot.edit_role(ctx.message.server, role, name=name)
logger.info("{}({}) changed the name of role '{}' to '{}'".format(
author.name, author.id, old_name, name))
await self.bot.say("Done.")
except discord.Forbidden:
await self.bot.say("I need permissions to manage roles first.")
except Exception as e:
print(e)
await self.bot.say("Something went wrong.")
def admin(self, ctx):
"""Shows the help information for creating self assigned roles
"""
role = "role"
plural = "s"
if "bias" in ctx.invoked_with:
role = "bias"
plural = "es"
msg = []
msg.append("```")
msg.append("To get started, give me permission to manage roles, and delete messages.")
msg.append("I should have been added with these roles, so just check for a `TnyBot` role.")
msg.append("")
msg.append("Next, you need to create a list of {1}{2} members can add.")
msg.append("Use: {0}set{1} Role=Alias, Role2=Alias2")
msg.append("Example: {0}set{1} robots=robits, dogs=doge, lions, tigers, bears=beers")
msg.append("")
msg.append("If you want to enforce 1 {1} per user, then use {0}setmain{1}")
msg.append("The Member will be prompted if they want to swap {1}{2}.")
msg.append("")
msg.append("Hint: {1}{2}, and main{1}{2} can share the same alias.")
msg.append("To make it easier to add roles, you can allow @mentions and just mention each role you want to add")
msg.append("```")
await self.bot.say("\n".join(msg).format(ctx.prefix, role, plural))
def insert(self, role: Role, alias: str = None, is_primary: int = 0):
""" Inserts a new role into the table.
If the alias is not specified, the role name will be used instead
"""
if not role: # pragma: no cover
return
if alias is None:
alias = role.name
server = role.server
if self.sql_type is SQLType.sqlite:
return await self._insert_lite(role, server, alias, is_primary)
else: # pragma: no cover
self.cursor.execute(
self.query(
'''INSERT INTO roles VALUES (%(role)s, %(alias)s, %(server)s, %(primary)s)
ON CONFLICT(role, server_id)
DO UPDATE SET alias = %(alias)s'''),
{"role": role.id, "alias": alias, "server": server.id, "primary": is_primary})
self.connection.commit()
def status(self, ctx):
"""Shows the servers settings for welcomer."""
db = fileIO(self.load, "load")
if ctx.message.server.id not in db:
await self.bot.say(":x: **Welcomer has not been configured for this server, use `welcomer channel` first**")
return
server = ctx.message.server
color = ''.join([choice('0123456789ABCDEF') for x in range(6)])
color = int(color, 16)
e = discord.Embed(colour=discord.Colour(value=color), description="\n\a")
role = discord.utils.get(ctx.message.server.roles, id=db[server.id]["botrole"])
e.set_author(name="Settings for " + server.name, icon_url=server.icon_url)
e.add_field(name="Welcomer Channel:", value="#" + self.bot.get_channel(db[server.id]["Channel"]).name if self.bot.get_channel(db[server.id]["Channel"]) else None, inline=True)
e.add_field(name="Join Toggle:", value=db[server.id]["join"], inline=True)
e.add_field(name="Leave Toggle:", value=db[server.id]["leave"], inline=True)
e.add_field(name="Bot Role:", value=role.name if role else None)
e.add_field(name="Bot Role Toggle:", value=db[server.id]["botroletoggle"])
e.add_field(name="Embed", value=db[server.id]["Embed"], inline=True)
e.add_field(name="Leave Message:", value=db[server.id]["leavemessage"], inline=False)
e.add_field(name="Join Message:", value=db[server.id]["joinmessage"], inline=False)
try:
await self.bot.say(embed=e)
except Exception as e:
await self.bot.say(e)
def blacklist_add(self, ctx, value:str, *, obj:MultiMention):
if isinstance(obj, discord.Server):
kwargs = dict(server_id=int(obj.id))
elif isinstance(obj, discord.Channel):
kwargs = dict(channel_id=int(obj.id))
elif isinstance(obj, discord.Role):
kwargs = dict(role_id=int(obj.id))
elif isinstance(obj, discord.Member):
kwargs = dict(user_id=int(obj.id))
with self.bot.db_scope() as session:
blacklist_obj = session.query(sql.Blacklist).filter_by(**kwargs, data=value).first()
if blacklist_obj is not None:
await self.bot.say(f"{obj.__class__.__name__} **{str(obj)}** has already been blacklisted for `{value}`")
return
else:
blacklist_obj = sql.Blacklist(**kwargs, data=value)
session.add(blacklist_obj)
await self.bot.say(f"Blacklisted {obj.__class__.__name__} **{str(obj)}** for `{value}`")
def blacklist_remove(self, ctx, value:str, *, obj:MultiMention):
if isinstance(obj, discord.Server):
kwargs = dict(server_id=int(obj.id))
elif isinstance(obj, discord.Channel):
kwargs = dict(channel_id=int(obj.id))
elif isinstance(obj, discord.Role):
kwargs = dict(role_id=int(obj.id))
elif isinstance(obj, discord.Member):
kwargs = dict(user_id=int(obj.id))
with self.bot.db_scope() as session:
blacklist_obj = session.query(sql.Blacklist).filter_by(**kwargs, data=value).first()
if blacklist_obj is None:
await self.bot.say(f"{obj.__class__.__name__} **{str(obj)}** is not blacklisted for `{value}`")
return
else:
session.delete(blacklist_obj)
await self.bot.say(f"Removed {obj.__class__.__name__} **{str(obj)}** from blacklist for `{value}`")
def blacklist_search(self, ctx, *, obj:MultiMention):
if isinstance(obj, discord.Server):
kwargs = dict(server_id=int(obj.id))
elif isinstance(obj, discord.Channel):
kwargs = dict(channel_id=int(obj.id))
elif isinstance(obj, discord.Role):
kwargs = dict(role_id=int(obj.id))
elif isinstance(obj, discord.Member):
kwargs = dict(user_id=int(obj.id))
with self.bot.db_scope() as session:
blacklist_objs = session.query(sql.Blacklist).filter_by(**kwargs).all()
if len(blacklist_objs) > 0:
result_text = f"```md\n# {obj.__class__.__name__} {str(obj)} is blacklisted for\n" + "\n".join(f"- {b_obj.data}" for b_obj in blacklist_objs) + "\n```"
else:
result_text = f"```md\n# {obj.__class__.__name__} {str(obj)} is not blacklisted\n```"
await self.bot.say(result_text)
def colour(self, ctx, colour : discord.Colour, *, role : discord.Role):
"""Changes the colour of a role.
The colour must be a hexadecimal value, e.g. FF2AEF. Don't prefix it
with a pound (#) as it won't work. Colour names are also not supported.
To use this command you must have the Manage Roles permission or
have the Bot Admin role. The bot must also have Manage Roles permissions.
This command cannot be used in a private message.
"""
try:
await self.bot.edit_role(ctx.message.server, role, colour=colour)
except discord.Forbidden:
await self.bot.say('The bot must have Manage Roles permissions to use this.')
else:
await self.bot.say('\U0001f44c')
#changes the name of the role
#NOTE: Currently CANNOT change default bot role name (BotName=DafaultRoleName)
def add(self, ctx, *, role: CustomRoleConverter):
"""
Adds a role to the list that can be assigned
"""
if not isinstance(role, discord.Role):
await ctx.send("Could not find role! Creating blank role now :crayon: ")
role = await ctx.guild.create_role(name=role,
colour=Colour.orange(),
mentionable=True,
reason="Role automagically created by GAF Bot for the role list")
if role.position >= ctx.author.top_role.position:
await ctx.send("Unable to add role due to Hierarchy")
else:
guild_config = await self.bot.get_guild_config(ctx.guild.id)
guild_config["roles"][role.id] = role.name
await self.bot.set_guild_config(ctx.guild.id, guild_config)
await ctx.send("Added {} to the role list".format(role.name))
def bouncerset_roles(self, ctx, before_after: str, role: discord.Role=None):
"""For first parameter use before or after. For roles with space with them,
use \"double quotes\"
Before: role assigned to users when they join the server but don't accept
the rules yet, will be stripped after accepting the rules. Can be left empty.
After: Role assigned after accepting the rules
"""
server = ctx.message.server
valid_options = ["before", "after"]
selection = before_after.lower()
if selection not in valid_options:
await send_cmd_help(ctx)
return
if selection == "before":
await self.bot.say("Role assigned at join will be: {}".format(role))
self.settings[server.id]["role_before"] = role.id
elif role is not None:
await self.bot.say("Role assigned after accepting rules will be: {}".format(role))
self.settings[server.id]["role_after"] = role.id
else:
self.bot.say("After role can't be empty")
return
dataIO.save_json('data/bouncer/settings.json', self.settings)
def set(self, ctx, role: discord.Role):
"""Change le rôle de président enregistré."""
channel = ctx.message.channel
author = ctx.message.author
if self.sys["GEP_ROLE"] is None:
self.sys["GEP_ROLE"] = role.name
fileIO("data/extra/sys.json", "save", self.sys)
await self.bot.say("Rôle de président enregistré.")
else:
await self.bot.say(
"Le rôle {} est déja renseigné. Voulez-vous l'enlever ? (O/N)".format(self.sys["GEP_ROLE"]))
rep = await self.bot.wait_for_message(author=author, channel=channel)
rep = rep.content.lower()
if rep == "o":
await self.bot.say("Le rôle à été retiré de ma BDD.")
self.sys["GEP_ROLE"] = None
fileIO("data/extra/sys.json", "save", self.sys)
elif rep == "n":
await self.bot.say("Le rôle est conservé.")
else:
await self.bot.say("Réponse invalide, le rôle est conservé.")
# BOITE A IDEES --------------------
def colour(self, ctx, role: discord.Role, value: discord.Colour):
"""Edits a role's colour
Use double quotes if the role contains spaces.
Colour must be in hexadecimal format.
\"http://www.w3schools.com/colors/colors_picker.asp\"
Examples:
!editrole colour \"The Transistor\" #ff0000
!editrole colour Test #ff9900"""
author = ctx.message.author
try:
await self.bot.edit_role(ctx.message.server, role, color=value)
logger.info("{}({}) changed the colour of role '{}'".format(
author.name, author.id, role.name))
await self.bot.say("Done.")
except discord.Forbidden:
await self.bot.say("I need permissions to manage roles first.")
except Exception as e:
print(e)
await self.bot.say("Something went wrong.")
def edit_role_name(self, ctx, role: discord.Role, name: str):
"""Edits a role's name
Use double quotes if the role or the name contain spaces.
Examples:
!editrole name \"The Transistor\" Test"""
if name == "":
await self.bot.say("Name cannot be empty.")
return
try:
author = ctx.message.author
old_name = role.name # probably not necessary?
await self.bot.edit_role(ctx.message.server, role, name=name)
logger.info("{}({}) changed the name of role '{}' to '{}'".format(
author.name, author.id, old_name, name))
await self.bot.say("Done.")
except discord.Forbidden:
await self.bot.say("I need permissions to manage roles first.")
except Exception as e:
print(e)
await self.bot.say("Something went wrong.")