Simplify voting in polls

This commit is contained in:
Tulir Asokan
2019-04-03 15:11:21 +03:00
parent 41b8292f25
commit 46c3bbff3c
2 changed files with 34 additions and 12 deletions
+20 -2
View File
@@ -241,7 +241,7 @@ async def play(evt: CommandEvent) -> Optional[Dict]:
help_text="Vote in a Telegram poll.") help_text="Vote in a Telegram poll.")
async def vote(evt: CommandEvent) -> Optional[Dict]: async def vote(evt: CommandEvent) -> Optional[Dict]:
if len(evt.args) < 2: if len(evt.args) < 2:
return await evt.reply("**Usage:** `$cmdprefix+sp vote <poll ID> <choice ID>`") return await evt.reply("**Usage:** `$cmdprefix+sp vote <poll ID> <choice number>`")
elif not await evt.sender.is_logged_in(): elif not await evt.sender.is_logged_in():
return await evt.reply("You must be logged in with a real account to vote in polls.") return await evt.reply("You must be logged in with a real account to vote in polls.")
elif evt.sender.is_bot: elif evt.sender.is_bot:
@@ -255,7 +255,25 @@ async def vote(evt: CommandEvent) -> Optional[Dict]:
if not isinstance(msg.media, MessageMediaPoll): if not isinstance(msg.media, MessageMediaPoll):
return await evt.reply("Invalid poll ID (message doesn't look like a poll)") return await evt.reply("Invalid poll ID (message doesn't look like a poll)")
options = [base64.b64decode(option + (3 - (len(option) + 3) % 4) * "=") options = []
for option in evt.args[1:]:
try:
if len(option) > 10:
raise ValueError("option index too long")
option_index = int(option) - 1
except ValueError:
option_index = None
if not option_index:
return await evt.reply(f"Invalid option number \"{option}\"",
render_markdown=False, allow_html=False)
elif option_index < 0:
return await evt.reply(f"Invalid option number {option}. "
f"Option numbers must be positive.")
elif option_index >= len(msg.media.poll.answers):
return await evt.reply(f"Invalid option number {option}. "
f"The poll only has {len(msg.media.poll.answers)} options.")
options.append(msg.media.poll.answers[option_index].option)
options = [msg.media.poll.answers[int(option) - 1].option
for option in evt.args[1:]] for option in evt.args[1:]]
try: try:
resp = await evt.sender.client(SendVoteRequest(peer=peer, msg_id=msg.id, options=options)) resp = await evt.sender.client(SendVoteRequest(peer=peer, msg_id=msg.id, options=options))
+14 -10
View File
@@ -1512,20 +1512,24 @@ class Portal:
poll = evt.media.poll # type: Poll poll = evt.media.poll # type: Poll
poll_id = self._encode_msgid(source, evt) poll_id = self._encode_msgid(source, evt)
def enc(answer: PollAnswer) -> str: _n = 0
return base64.b64encode(answer.option).decode("utf-8").rstrip("=")
text = (f"Poll ID {poll_id}: {poll.question}\n" def n() -> int:
+ "\n".join(f"* {enc(answer)}: {answer.text}" for answer in poll.answers) + nonlocal _n
_n += 1
return _n
text = (f"Poll: {poll.question}\n"
+ "\n".join(f"{n()}. {answer.text}" for answer in poll.answers) +
"\n" "\n"
f"Vote with !tg vote <poll ID> <choice ID>") f"Vote with !tg vote {poll_id} <choice number>")
html = (f"<strong>Poll</strong> ID <code>{poll_id}</code>: {poll.question}<br/>\n" html = (f"<strong>Poll</strong>: {poll.question}<br/>\n"
f"<ul>" f"<ol>"
+ "\n".join(f"<li><code>{enc(answer)}</code>: {answer.text}</li>" + "\n".join(f"<li>{answer.text}</li>"
for answer in poll.answers) + for answer in poll.answers) +
"</ul>\n" "</ol>\n"
f"Vote with <code>!tg vote &lt;poll ID&gt; &lt;choice ID&gt;</code>") f"Vote with <code>!tg vote {poll_id} &lt;choice number&gt;</code>")
await intent.set_typing(self.mxid, is_typing=False) await intent.set_typing(self.mxid, is_typing=False)
return await intent.send_text(self.mxid, text, html=html, relates_to=relates_to, return await intent.send_text(self.mxid, text, html=html, relates_to=relates_to,
msgtype="m.text", timestamp=evt.date, msgtype="m.text", timestamp=evt.date,