This commit is contained in:
matnad 2019-02-11 11:13:40 +01:00
parent d94d0b976a
commit 6fcea9fb5b
6 changed files with 65 additions and 41 deletions

View File

@ -35,7 +35,8 @@ class Help:
await self.bot.delete_message(msg) await self.bot.delete_message(msg)
return None return None
else: else:
await self.bot.remove_reaction(res.reaction.message, res.reaction.emoji, res.user) if str(res.reaction.message.channel.type) != 'private':
await self.bot.remove_reaction(res.reaction.message, res.reaction.emoji, res.user)
return res return res
def get_help_embed(self, page, pre): def get_help_embed(self, page, pre):
@ -90,19 +91,19 @@ class Help:
'type the command or type the command followed by the question to skip that first step.' 'type the command or type the command followed by the question to skip that first step.'
'Your Members need the <admin> or <user> role to use these commands. More in 🛠 Configuration.', 'Your Members need the <admin> or <user> role to use these commands. More in 🛠 Configuration.',
inline=False) inline=False)
embed.add_field(name='🔹 **Quick Poll:** `!quick <poll question>` (optional)', embed.add_field(name=f'🔹 **Quick Poll:** `{pre}quick <poll question>` (optional)',
value='If you just need a quick poll, this is the way to go. All you have to specify is the ' value='If you just need a quick poll, this is the way to go. All you have to specify is the '
'question and your answers; the rest will be set to default values.', 'question and your answers; the rest will be set to default values.',
inline=False) inline=False)
embed.add_field(name='🔹 **All Features:** `!new <poll question>` (optional)', embed.add_field(name=f'🔹 **All Features:** `{pre}new <poll question>` (optional)',
value='This command gives you full control over your poll. A step by step wizard will guide ' value='This command gives you full control over your poll. A step by step wizard will guide '
'you through the process and you can specify options such as Multiple Choice, ' 'you through the process and you can specify options such as Multiple Choice, '
'Anonymous Voting, Role Restriction, Role Weights and Deadline.', 'Anonymous Voting, Role Restriction, Role Weights and Deadline.',
inline=False) inline=False)
embed.add_field(name='🔹 **Prepare and Schedule:** `!prepare <poll question>` (optional)', embed.add_field(name=f'🔹 **Prepare and Schedule:** `{pre}prepare <poll question>` (optional)',
value='Similar to `!new`, this gives you all the options. But additionally, the poll will ' value=f'Similar to `{pre}new`, this gives you all the options. But additionally, the poll will '
'be set to \'inactive\'. You can specify if the poll should activate at a certain time ' 'be set to \'inactive\'. You can specify if the poll should activate at a certain time '
'and/or if you would like to manually `!activate` it. ' f'and/or if you would like to manually `{pre}activate` it. '
'Perfect if you are preparing for a team meeting!', 'Perfect if you are preparing for a team meeting!',
inline=False) inline=False)
elif page == '🔍': elif page == '🔍':
@ -110,13 +111,13 @@ class Help:
value='All users can display and list polls, with the exception of prepared polls. ' value='All users can display and list polls, with the exception of prepared polls. '
'Voting is done simply by using the reactions below the poll.', 'Voting is done simply by using the reactions below the poll.',
inline=False) inline=False)
embed.add_field(name='🔹 **Show a Poll:** `!show <poll_label>`', embed.add_field(name=f'🔹 **Show a Poll:** `{pre}show <poll_label>`',
value='This command will refresh and display a poll. The votes in the message will always ' value='This command will refresh and display a poll. The votes in the message will always '
'be up to date and accurate. The number of reactions can be different for a number ' 'be up to date and accurate. The number of reactions can be different for a number '
'of reasons and you can safely disregard them.', 'of reasons and you can safely disregard them.',
inline=False) inline=False)
embed.add_field(name='🔹 **List Polls:** `!show <> | open | closed | prepared`', embed.add_field(name=f'🔹 **List Polls:** `{pre}show <> | open | closed | prepared`',
value='If you just type `!show` without an argument it will default to `!show open`.' value=f'If you just type `{pre}show` without an argument it will default to `{pre}show open`.'
'These commands will print a list of open, closed or prepared polls that exist on ' 'These commands will print a list of open, closed or prepared polls that exist on '
'the server. The first word in bold is the label of the poll and after the colon, ' 'the server. The first word in bold is the label of the poll and after the colon, '
'you can read the question. These lists are paginated and you can use the arrow ' 'you can read the question. These lists are paginated and you can use the arrow '
@ -127,24 +128,24 @@ class Help:
value='All these commands can only be used by an <admin> or by the author of the poll. ' value='All these commands can only be used by an <admin> or by the author of the poll. '
'Go to 🛠 Configuration for more info on the permissions.', 'Go to 🛠 Configuration for more info on the permissions.',
inline=False) inline=False)
embed.add_field(name='🔹 **Close** `!close <poll_label>`', embed.add_field(name=f'🔹 **Close** `{pre}close <poll_label>`',
value='Polls will close automatically when their deadline is reached. But you can always ' value='Polls will close automatically when their deadline is reached. But you can always '
'close them manually by using this command. A closed poll will lock in the votes so ' 'close them manually by using this command. A closed poll will lock in the votes so '
'users can no longer change, add or remove votes. Once closed, you can export a poll.', 'users can no longer change, add or remove votes. Once closed, you can export a poll.',
inline=False) inline=False)
embed.add_field(name='🔹 **Delete** `!delete <poll_label>`', embed.add_field(name=f'🔹 **Delete** `{pre}delete <poll_label>`',
value='This will *permanently and irreversibly* delete a poll from the database. ' value='This will *permanently and irreversibly* delete a poll from the database. '
'Once done, the label is freed up and can be assigned again.', 'Once done, the label is freed up and can be assigned again.',
inline=False) inline=False)
embed.add_field(name='🔹 **Export** `!export <poll_label>`', embed.add_field(name=f'🔹 **Export** `{pre}export <poll_label>`',
value='You can use this command or react with 📎 to a closed poll to generate a report. ' value='You can use this command or react with 📎 to a closed poll to generate a report. '
'The report will then be sent to you in discord via the bot. This utf8-textfile ' 'The report will then be sent to you in discord via the bot. This utf8-textfile '
'(make sure to open it in an utf8-ready editor) will contain all the infos about the ' '(make sure to open it in an utf8-ready editor) will contain all the infos about the '
'poll, including a detailed list of participants and their votes (just a list of names ' 'poll, including a detailed list of participants and their votes (just a list of names '
'for anonymous polls).', 'for anonymous polls).',
inline=False) inline=False)
embed.add_field(name='🔹 **Activate** `!activate <poll_label>`', embed.add_field(name=f'🔹 **Activate** `{pre}activate <poll_label>`',
value='To see how you can prepare inactive polls read the `!prepare` command under Making ' value=f'To see how you can prepare inactive polls read the `{pre}prepare` command under Making '
'New Polls. This command is used to manually activate a prepared poll.', 'New Polls. This command is used to manually activate a prepared poll.',
inline=False) inline=False)
@ -152,17 +153,17 @@ class Help:
embed.add_field(name='🛠 Configuration', embed.add_field(name='🛠 Configuration',
value='To run any of these commands you need the **\"Manage Server\"** permisson.', value='To run any of these commands you need the **\"Manage Server\"** permisson.',
inline=False) inline=False)
embed.add_field(name='🔹 **Poll Admins** `!adminrole <role name> (optional)`', embed.add_field(name=f'🔹 **Poll Admins** `{pre}adminrole <role name> (optional)`',
value='This gives the rights to create polls and to control ALL polls on the server. ' value='This gives the rights to create polls and to control ALL polls on the server. '
'To see the current role for poll admin, run the command without an argument: `!adminrole`\n' f'To see the current role for poll admin, run the command without an argument: `{pre}adminrole`\n'
'If you want to change the admin role to any other role, use the name of the new role ' 'If you want to change the admin role to any other role, use the name of the new role '
'as the argument: !adminrole moderators', f'as the argument: `{pre}adminrole moderators`',
inline=False) inline=False)
embed.add_field(name='🔹 **Poll Users** `!userrole <role name> (optional)`', embed.add_field(name=f'🔹 **Poll Users** `{pre}userrole <role name> (optional)`',
value='Everything here is identical to the admin role, except that Poll Users can only ' value='Everything here is identical to the admin role, except that Poll Users can only '
'control the polls which were created by themselves.', 'control the polls which were created by themselves.',
inline=False) inline=False)
embed.add_field(name='🔹 **Change Prefix** `!prefix <new_prefix>`', embed.add_field(name=f'🔹 **Change Prefix** `{pre}prefix <new_prefix>`',
value='This will change the bot prefix for your server. If you want to use a trailing ' value='This will change the bot prefix for your server. If you want to use a trailing '
'whitespace, use "\w" instead of " " (discord deletes trailing whitespaces).', 'whitespace, use "\w" instead of " " (discord deletes trailing whitespaces).',
inline=False) inline=False)

View File

@ -662,8 +662,7 @@ class Poll:
if dt.tzinfo is None or dt.tzinfo.utcoffset(dt) is None: if dt.tzinfo is None or dt.tzinfo.utcoffset(dt) is None:
dt = dt.astimezone(pytz.utc) dt = dt.astimezone(pytz.utc)
now = datetime.datetime.utcnow().astimezone(pytz.utc) now = datetime.datetime.utcnow().replace(tzinfo=pytz.utc)
if dt < now: if dt < now:
raise DateOutOfRange(dt) raise DateOutOfRange(dt)
return dt return dt

View File

@ -20,6 +20,8 @@ class PollControls:
member = server.get_member(ctx.message.author.id) member = server.get_member(ctx.message.author.id)
if member.id == owner_id: if member.id == owner_id:
return True return True
elif member.server_permissions.manage_server:
return True
else: else:
result = await self.bot.db.config.find_one({'_id': str(server.id)}) result = await self.bot.db.config.find_one({'_id': str(server.id)})
if result and result.get('admin_role') in [r.name for r in member.roles]: if result and result.get('admin_role') in [r.name for r in member.roles]:
@ -315,12 +317,17 @@ class PollControls:
# Permission Check # Permission Check
member = server.get_member(ctx.message.author.id) member = server.get_member(ctx.message.author.id)
result = await self.bot.db.config.find_one({'_id': str(server.id)}) if not member.server_permissions.manage_server:
if result and result.get('admin_role') not in [r.name for r in member.roles] and result.get( result = await self.bot.db.config.find_one({'_id': str(server.id)})
'user_role') not in [r.name for r in member.roles]: if result and result.get('admin_role') not in [r.name for r in member.roles] and result.get(
await self.bot.send_message(ctx.message.author, 'user_role') not in [r.name for r in member.roles]:
'You don\'t have sufficient rights to start new polls on this server. Please talk to the server admin.') pre = await get_server_pre(self.bot, server)
return await self.bot.send_message(ctx.message.author,
'You don\'t have sufficient rights to start new polls on this server. '
'A server administrator has to assign the user or admin role to you. '
f'To view and set the permissions, an admin can use `{pre}userrole` and '
f'`{pre}adminrole`')
return
## Create object ## Create object
poll = Poll(self.bot, ctx, server, channel) poll = Poll(self.bot, ctx, server, channel)
@ -339,9 +346,11 @@ class PollControls:
# BOT EVENTS (@bot.event) # BOT EVENTS (@bot.event)
async def on_reaction_add(self, reaction, user): async def on_reaction_add(self, reaction, user):
if user != self.bot.user: if user != self.bot.user:
try:
if reaction.emoji.startswith(('', '')): if reaction.emoji.startswith(('', '')):
return return
except:
print("fail emoji",reaction.emoji)
# only look at our polls # only look at our polls
try: try:

View File

@ -7,7 +7,7 @@ async def get_pre(bot, message):
if str(message.channel.type) == 'private': if str(message.channel.type) == 'private':
shared_server_list = await get_servers(bot, message) shared_server_list = await get_servers(bot, message)
if shared_server_list.__len__() == 0: if shared_server_list.__len__() == 0:
return '!' return 'pm!!'
elif shared_server_list.__len__() == 1: elif shared_server_list.__len__() == 1:
return await get_server_pre(bot, shared_server_list[0]) return await get_server_pre(bot, shared_server_list[0])
else: else:
@ -22,9 +22,9 @@ async def get_server_pre(bot, server):
try: try:
result = await bot.db.config.find_one({'_id': str(server.id)}) result = await bot.db.config.find_one({'_id': str(server.id)})
except AttributeError: except AttributeError:
return '!' return 'pm!'
if not result or not result.get('prefix'): if not result or not result.get('prefix'):
return '!' return 'pm!!'
return result.get('prefix') return result.get('prefix')

View File

@ -6,9 +6,9 @@ from essentials.secrets import SECRETS
class Settings: class Settings:
def __init__(self): def __init__(self):
self.color = discord.Colour(int('7289da', 16)) self.color = discord.Colour(int('7289da', 16))
self.title_icon = "http://mnadler.ch/img/donat-chart-32.png" self.title_icon = "http://mnadler.ch/img/tag.png"
self.author_icon = "http://mnadler.ch/img/donat-chart-32.png" self.author_icon = "http://mnadler.ch/img/tag.jpg"
self.report_icon = "http://mnadler.ch/img/poll-topic-64.png" self.report_icon = "http://mnadler.ch/img/report.png"
self.owner_id = 117687652278468610 self.owner_id = 117687652278468610
self.msg_errors = False self.msg_errors = False
self.log_errors = True self.log_errors = True

View File

@ -45,6 +45,7 @@ extensions = ['cogs.config','cogs.poll_controls', 'cogs.help', 'cogs.db_api']
for ext in extensions: for ext in extensions:
bot.load_extension(ext) bot.load_extension(ext)
@bot.event @bot.event
async def on_ready(): async def on_ready():
bot.owner = await bot.get_user_info(str(SETTINGS.owner_id)) bot.owner = await bot.get_user_info(str(SETTINGS.owner_id))
@ -55,6 +56,16 @@ async def on_ready():
print(bot.db) print(bot.db)
await bot.change_presence(game=discord.Game(name=f'pm!help')) await bot.change_presence(game=discord.Game(name=f'pm!help'))
# check discord server configs
db_server_ids = [entry['_id'] async for entry in bot.db.config.find({}, {})]
for server in bot.servers:
if server.id not in db_server_ids:
await bot.db.config.update_one(
{'_id': str(server.id)},
{'$set': {'prefix': 'pm!', 'admin_role': 'polladmin', 'user_role': 'polluser'}},
upsert=True
)
@bot.event @bot.event
async def on_command_error(e, ctx): async def on_command_error(e, ctx):
@ -86,14 +97,18 @@ async def on_command_error(e, ctx):
f"\n\tAuthor: <@{ctx.message.author.id}>", f"\n\tAuthor: <@{ctx.message.author.id}>",
timestamp=ctx.message.timestamp timestamp=ctx.message.timestamp
) )
await bot.send_message(bot.owner,embed=e) await bot.send_message(bot.owner, embed=e)
@bot.event @bot.event
async def on_server_join(server): async def on_server_join(server):
result = await bot.db.config.find_one({'_id': str(server.id)}) result = await bot.db.config.find_one({'_id': str(server.id)})
if result is None: if result is None:
await bot.db.config.update_one({'_id': str(server.id)}, await bot.db.config.update_one(
{'$set': {'prefix': 'pm!', 'admin_role': 'polladmin', 'user_role': 'polluser'}}, {'_id': str(server.id)},
upsert=True) {'$set': {'prefix': 'pm!', 'admin_role': 'polladmin', 'user_role': 'polluser'}},
upsert=True
)
bot.run(SETTINGS.bot_token)
bot.run(SETTINGS.bot_token, reconnect=True)