From 5d91dc48f2fcafd158dabaf1227feb6d50285969 Mon Sep 17 00:00:00 2001
From: dnns01 <mail@dnns01.de>
Date: Tue, 25 Aug 2020 14:20:31 +0200
Subject: [PATCH] Added !poll command to start a poll in a channel.

---
 fernuni-bot.py | 20 +++++++++++++
 poll.py        | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 100 insertions(+)
 create mode 100644 poll.py

diff --git a/fernuni-bot.py b/fernuni-bot.py
index 550e37f..c9d7585 100644
--- a/fernuni-bot.py
+++ b/fernuni-bot.py
@@ -5,6 +5,8 @@ import discord
 from discord.ext import commands
 from dotenv import load_dotenv
 
+from poll import Poll
+
 # .env file is necessary in the same directory, that contains several strings.
 load_dotenv()
 TOKEN = os.getenv('DISCORD_TOKEN')
@@ -158,6 +160,11 @@ async def cmd_add_role(ctx, key, role):
         await send_dm(ctx.author, f"Fehler beim Hinzufügen der Rolle {role}")
 
 
+@bot.command(name="poll")
+async def cmd_poll(ctx, question, *answers):
+    await Poll(bot, question, answers, ctx.author.id).send_poll(ctx)
+
+
 def load_roles():
     global assignable_roles
     roles_file = open(ROLES_FILE, mode='r')
@@ -251,10 +258,23 @@ async def on_ready():
 
 @bot.event
 async def on_raw_reaction_add(payload):
+    if payload.user_id == bot.user.id:
+        return
+
     if payload.emoji.name == PIN_EMOJI:
         channel = await bot.fetch_channel(payload.channel_id)
         message = await channel.fetch_message(payload.message_id)
         await pin_message(message)
+    elif payload.emoji.name in ["🗑️", "🛑"]:
+        channel = await bot.fetch_channel(payload.channel_id)
+        message = await channel.fetch_message(payload.message_id)
+        if len(message.embeds) > 0 and message.embeds[0].title == "Umfrage":
+            poll = Poll(bot, message=message)
+            if str(payload.user_id) == poll.author:
+                if payload.emoji.name == "🗑️":
+                    await poll.delete_poll()
+                else:
+                    await poll.close_poll()
 
 
 @bot.event
diff --git a/poll.py b/poll.py
new file mode 100644
index 0000000..bf9bbba
--- /dev/null
+++ b/poll.py
@@ -0,0 +1,80 @@
+import discord
+
+OPTIONS = ["\u0031\u20E3", "\u0032\u20E3", "\u0033\u20E3", "\u0034\u20E3", "\u0035\u20E3", "\u0036\u20E3",
+           "\u0037\u20E3", "\u0038\u20E3", "\u0039\u20E3", "\u0040\u20E3"]
+
+
+class Poll:
+
+    def __init__(self, bot, question=None, answers=None, author=None, message=None):
+        self.bot = bot
+        self.question = question
+        self.answers = answers
+        self.author = author
+
+        if message:
+            self.message = message
+            self.answers = []
+            embed = message.embeds[0]
+            self.author = embed.fields[0].value[3:-1]
+            self.question = embed.description
+            for i in range(2, len(embed.fields)):
+                self.answers.append(embed.fields[i].value)
+
+    async def send_poll(self, channel, result=False):
+        option_ctr = 0
+        title = "Umfrage"
+
+        if result:
+            title += " Ergebnis"
+
+        if len(self.answers) > 10:
+            channel.send("Fehler beim Erstellen der Umfrage! Es werden derzeit nicht mehr als 10 Optionen unterstützt!")
+            return
+
+        embed = discord.Embed(title=title, description=self.question)
+        embed.add_field(name="Erstellt von", value=f'<@!{self.author}>', inline=False)
+        embed.add_field(name="\u200b", value="\u200b", inline=False)
+
+        for i in range(0, len(self.answers)):
+            name = f'{OPTIONS[i]}'
+            value = f'{self.answers[i]}'
+
+            if result:
+                reaction = self.get_reaction(OPTIONS[i])
+                if reaction:
+                    name += f' : {reaction.count - 1}'
+                    value += f'\nStimmen: '
+
+                    async for user in reaction.users():
+                        if self.bot.user == user:
+                            continue
+
+                        value += f'<@!{str(user.id)}> '
+
+            embed.add_field(name=name, value=value, inline=False)
+            option_ctr += 1
+
+        message = await channel.send("", embed=embed)
+
+        if not result:
+            for i in range(0, len(self.answers)):
+                await message.add_reaction(OPTIONS[i])
+
+            await message.add_reaction("🗑️")
+            await message.add_reaction("🛑")
+
+    async def close_poll(self):
+        await self.send_poll(self.message.channel, result=True)
+        await self.delete_poll()
+
+    async def delete_poll(self):
+        await self.message.delete()
+
+    def get_reaction(self, reaction):
+        if self.message:
+            reactions = self.message.reactions
+
+            for react in reactions:
+                if react.emoji == reaction:
+                    return react
-- 
GitLab