feat(commands|Polls>propose): start dev for proposal
This commit is contained in:
parent
c3660aab8a
commit
30cc3ecad2
9 changed files with 243 additions and 3 deletions
59
tuxbot/cogs/Polls/functions/converters.py
Normal file
59
tuxbot/cogs/Polls/functions/converters.py
Normal file
|
@ -0,0 +1,59 @@
|
||||||
|
from discord.ext import commands
|
||||||
|
from tuxbot.cogs.Polls.functions.exceptions import (
|
||||||
|
TooLongProposition,
|
||||||
|
InvalidChannel,
|
||||||
|
BadPoll,
|
||||||
|
)
|
||||||
|
from tuxbot.cogs.Polls.models import Poll
|
||||||
|
|
||||||
|
_ = lambda x: x
|
||||||
|
|
||||||
|
|
||||||
|
class PollConverter(commands.Converter):
|
||||||
|
async def convert(self, ctx, argument):
|
||||||
|
try:
|
||||||
|
poll = await commands.MessageConverter().convert(ctx, argument)
|
||||||
|
|
||||||
|
if poll.channel.id != ctx.channel.id:
|
||||||
|
raise InvalidChannel(
|
||||||
|
_("Please provide a message in this channel")
|
||||||
|
)
|
||||||
|
|
||||||
|
if (
|
||||||
|
poll.author.id != ctx.bot.user.id
|
||||||
|
or len(poll.embeds) != 1
|
||||||
|
or poll.embeds[0].to_dict().get("footer", {}).get("text", None)
|
||||||
|
is None
|
||||||
|
):
|
||||||
|
raise BadPoll(_("Unable to find this poll"))
|
||||||
|
|
||||||
|
poll_id = poll.embeds[0].to_dict().get("footer").get("text")
|
||||||
|
poll_id = poll_id.replace("ID: #", "")
|
||||||
|
|
||||||
|
if not poll_id.isdigit():
|
||||||
|
raise BadPoll(_("Unable to find this poll"))
|
||||||
|
except commands.BadArgument:
|
||||||
|
poll_id = str(argument).replace("ID:", "").replace("#", "")
|
||||||
|
|
||||||
|
if not poll_id.isdigit():
|
||||||
|
raise BadPoll(_("Unable to find this poll"))
|
||||||
|
|
||||||
|
poll = await Poll.get_or_none(id=int(poll_id))
|
||||||
|
|
||||||
|
if poll.channel_id != ctx.channel.id:
|
||||||
|
raise InvalidChannel(_("Please provide a message in this channel"))
|
||||||
|
|
||||||
|
if poll is None:
|
||||||
|
raise BadPoll(_("Unable to find this poll"))
|
||||||
|
|
||||||
|
return poll
|
||||||
|
|
||||||
|
|
||||||
|
class NewPropositionConvertor(commands.Converter):
|
||||||
|
async def convert(self, ctx, argument):
|
||||||
|
if len(argument) > 30:
|
||||||
|
raise TooLongProposition(
|
||||||
|
_("Your proposal must be smaller than 30")
|
||||||
|
)
|
||||||
|
|
||||||
|
return argument
|
10
tuxbot/cogs/Polls/functions/emotes.py
Normal file
10
tuxbot/cogs/Polls/functions/emotes.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
emotes = [chr(0x1F1E6 + i) for i in range(26)]
|
||||||
|
check = [chr(0x2714), chr(0x2716)]
|
||||||
|
|
||||||
|
|
||||||
|
def get(count):
|
||||||
|
return emotes[:count]
|
||||||
|
|
||||||
|
|
||||||
|
def get_index(emote):
|
||||||
|
return emotes.index(emote)
|
13
tuxbot/cogs/Polls/functions/exceptions.py
Normal file
13
tuxbot/cogs/Polls/functions/exceptions.py
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
from discord.ext import commands
|
||||||
|
|
||||||
|
|
||||||
|
class BadPoll(commands.BadArgument):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class InvalidChannel(commands.BadArgument):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class TooLongProposition(commands.BadArgument):
|
||||||
|
pass
|
|
@ -1,4 +1,5 @@
|
||||||
# English translations for Tuxbot-bot package.
|
# French translations for Tuxbot-bot package
|
||||||
|
# Traductions françaises du paquet Tuxbot-bot.
|
||||||
# Copyright (C) 2020 THE Tuxbot-bot'S COPYRIGHT HOLDER
|
# Copyright (C) 2020 THE Tuxbot-bot'S COPYRIGHT HOLDER
|
||||||
# This file is distributed under the same license as the Tuxbot-bot package.
|
# This file is distributed under the same license as the Tuxbot-bot package.
|
||||||
# Automatically generated, 2020.
|
# Automatically generated, 2020.
|
||||||
|
@ -16,3 +17,33 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/polls.py:92
|
||||||
|
msgid "**Preparation**"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/polls.py:221
|
||||||
|
#, python-brace-format
|
||||||
|
msgid "Proposed addition for survey #{id}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/polls.py:226
|
||||||
|
#, python-brace-format
|
||||||
|
msgid "Requested by {author}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:20
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:45
|
||||||
|
msgid "Please provide a message in this channel"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:29
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:35
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:40
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:48
|
||||||
|
msgid "Unable to find this poll"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:57
|
||||||
|
msgid "Your proposal must be smaller than 30"
|
||||||
|
msgstr ""
|
|
@ -17,3 +17,33 @@ msgstr ""
|
||||||
"Content-Type: text/plain; charset=UTF-8\n"
|
"Content-Type: text/plain; charset=UTF-8\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/polls.py:92
|
||||||
|
msgid "**Preparation**"
|
||||||
|
msgstr "**Préparation**"
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/polls.py:221
|
||||||
|
#, python-brace-format
|
||||||
|
msgid "Proposed addition for poll #{id}"
|
||||||
|
msgstr "Proposition d'ajout pour le sondage #{id}"
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/polls.py:226
|
||||||
|
#, python-brace-format
|
||||||
|
msgid "Requested by {author}"
|
||||||
|
msgstr "Demandé par {author}"
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:20
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:45
|
||||||
|
msgid "Please provide a message in this channel"
|
||||||
|
msgstr "Veuillez fournir un message dans ce salon"
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:29
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:35
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:40
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:48
|
||||||
|
msgid "Unable to find this poll"
|
||||||
|
msgstr "Impossible de trouver ce sondage"
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:57
|
||||||
|
msgid "Your proposal must be smaller than 30"
|
||||||
|
msgstr "Votre proposition doit être inférieure à 30"
|
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: Tuxbot-bot\n"
|
"Project-Id-Version: Tuxbot-bot\n"
|
||||||
"Report-Msgid-Bugs-To: rick@gnous.eu\n"
|
"Report-Msgid-Bugs-To: rick@gnous.eu\n"
|
||||||
"POT-Creation-Date: 2020-10-21 01:15+0200\n"
|
"POT-Creation-Date: 2021-01-20 17:24+0100\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -16,3 +16,33 @@ msgstr ""
|
||||||
"MIME-Version: 1.0\n"
|
"MIME-Version: 1.0\n"
|
||||||
"Content-Type: text/plain; charset=CHARSET\n"
|
"Content-Type: text/plain; charset=CHARSET\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/polls.py:92
|
||||||
|
msgid "**Preparation**"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/polls.py:221
|
||||||
|
#, python-brace-format
|
||||||
|
msgid "Proposed addition for poll #{id}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/polls.py:226
|
||||||
|
#, python-brace-format
|
||||||
|
msgid "Requested by {author}"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:20
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:45
|
||||||
|
msgid "Please provide a message in this channel"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:29
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:35
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:40
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:48
|
||||||
|
msgid "Unable to find this poll"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: tuxbot/cogs/Polls/functions/converters.py:57
|
||||||
|
msgid "Your proposal must be smaller than 30"
|
||||||
|
msgstr ""
|
||||||
|
|
|
@ -1,2 +1,3 @@
|
||||||
from .polls import *
|
from .polls import *
|
||||||
from .responses import *
|
from .responses import *
|
||||||
|
from .suggests import *
|
||||||
|
|
22
tuxbot/cogs/Polls/models/suggests.py
Normal file
22
tuxbot/cogs/Polls/models/suggests.py
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import tortoise
|
||||||
|
from tortoise import fields
|
||||||
|
|
||||||
|
|
||||||
|
class Suggest(tortoise.Model):
|
||||||
|
suggest_id = fields.BigIntField(pk=True)
|
||||||
|
poll = fields.ForeignKeyField("models.Poll")
|
||||||
|
user_id = fields.BigIntField()
|
||||||
|
|
||||||
|
proposition = fields.CharField(max_length=30)
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
table = "suggests"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return (
|
||||||
|
f"<suggest_id poll={self.poll} "
|
||||||
|
f"user_id={self.user_id} "
|
||||||
|
f"proposition={self.proposition}>"
|
||||||
|
)
|
||||||
|
|
||||||
|
__repr__ = __str__
|
|
@ -12,7 +12,10 @@ from tuxbot.core.i18n import (
|
||||||
Translator,
|
Translator,
|
||||||
)
|
)
|
||||||
from .functions import emotes as utils_emotes
|
from .functions import emotes as utils_emotes
|
||||||
|
from .functions.converters import NewPropositionConvertor, PollConverter
|
||||||
|
from .functions.exceptions import InvalidChannel, BadPoll, TooLongProposition
|
||||||
from .models import Poll, Response
|
from .models import Poll, Response
|
||||||
|
from .models.suggests import Suggest
|
||||||
|
|
||||||
log = logging.getLogger("tuxbot.cogs.Polls")
|
log = logging.getLogger("tuxbot.cogs.Polls")
|
||||||
_ = Translator("Polls", __file__)
|
_ = Translator("Polls", __file__)
|
||||||
|
@ -22,6 +25,10 @@ class Polls(commands.Cog, name="Polls"):
|
||||||
def __init__(self, bot: Tux):
|
def __init__(self, bot: Tux):
|
||||||
self.bot = bot
|
self.bot = bot
|
||||||
|
|
||||||
|
async def cog_command_error(self, ctx, error):
|
||||||
|
if isinstance(error, (InvalidChannel, BadPoll, TooLongProposition)):
|
||||||
|
await ctx.send(_(str(error), ctx, self.bot.config))
|
||||||
|
|
||||||
@commands.Cog.listener()
|
@commands.Cog.listener()
|
||||||
async def on_raw_reaction_add(self, pld: discord.RawReactionActionEvent):
|
async def on_raw_reaction_add(self, pld: discord.RawReactionActionEvent):
|
||||||
poll = await self.get_poll(pld)
|
poll = await self.get_poll(pld)
|
||||||
|
@ -200,6 +207,33 @@ class Polls(commands.Cog, name="Polls"):
|
||||||
|
|
||||||
await message.remove_reaction(pld.emoji.name, user)
|
await message.remove_reaction(pld.emoji.name, user)
|
||||||
|
|
||||||
|
async def propose_new(
|
||||||
|
self, ctx: ContextPlus, poll: PollConverter, new: str
|
||||||
|
):
|
||||||
|
await Suggest.create(poll=poll, user_id=ctx.author.id, proposition=new)
|
||||||
|
|
||||||
|
if isinstance(poll, Poll):
|
||||||
|
# pylint: disable=pointless-string-statement
|
||||||
|
"""Just to change type for PyCharm"""
|
||||||
|
|
||||||
|
e = discord.Embed(
|
||||||
|
title=_(
|
||||||
|
"Proposed addition for poll #{id}", ctx, self.bot.config
|
||||||
|
).format(id=poll.id),
|
||||||
|
description=new,
|
||||||
|
)
|
||||||
|
e.set_footer(
|
||||||
|
text=_("Requested by {author}", ctx, self.bot.config).format(
|
||||||
|
author=ctx.author.name
|
||||||
|
),
|
||||||
|
icon_url=ctx.author.avatar_url_as(format="png"),
|
||||||
|
)
|
||||||
|
|
||||||
|
message = await ctx.send(embed=e)
|
||||||
|
|
||||||
|
for emote in utils_emotes.check:
|
||||||
|
await message.add_reaction(emote)
|
||||||
|
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
# =========================================================================
|
# =========================================================================
|
||||||
|
|
||||||
|
@ -208,7 +242,7 @@ class Polls(commands.Cog, name="Polls"):
|
||||||
if ctx.invoked_subcommand is None:
|
if ctx.invoked_subcommand is None:
|
||||||
await ctx.send_help("poll")
|
await ctx.send_help("poll")
|
||||||
|
|
||||||
@_poll.group(name="create", aliases=["new", "nouveau"])
|
@_poll.command(name="create", aliases=["new", "nouveau"])
|
||||||
async def _poll_create(self, ctx: ContextPlus, *, poll: str):
|
async def _poll_create(self, ctx: ContextPlus, *, poll: str):
|
||||||
args: list = poll.lower().split()
|
args: list = poll.lower().split()
|
||||||
is_anonymous = False
|
is_anonymous = False
|
||||||
|
@ -235,3 +269,13 @@ class Polls(commands.Cog, name="Polls"):
|
||||||
answers.append(" ".join(args[start:end]).capitalize())
|
answers.append(" ".join(args[start:end]).capitalize())
|
||||||
|
|
||||||
await self.create_poll(ctx, question, answers, anonymous=is_anonymous)
|
await self.create_poll(ctx, question, answers, anonymous=is_anonymous)
|
||||||
|
|
||||||
|
@_poll.command(name="propose", aliases=["suggest", "ajout"])
|
||||||
|
async def _poll_propose(
|
||||||
|
self,
|
||||||
|
ctx: ContextPlus,
|
||||||
|
poll: PollConverter,
|
||||||
|
*,
|
||||||
|
new: NewPropositionConvertor,
|
||||||
|
):
|
||||||
|
await self.propose_new(ctx, poll, str(new))
|
||||||
|
|
Loading…
Reference in a new issue