Skip to content
This repository has been archived by the owner on Feb 13, 2024. It is now read-only.

Commit

Permalink
Changed voting method to reactions
Browse files Browse the repository at this point in the history
  • Loading branch information
TomCasavant committed Dec 14, 2019
1 parent 5da505c commit 2b26bdd
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 28 deletions.
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@ A plugin for [maubot](https://github.com/maubot/maubot) that creates a poll in a
## Usage
'!poll new "Question" "Choice1" "Choice2" "Choice3"' - Creates a new poll with given (at least 1) choices

'!poll vote choice' - Has user vote for given choice (int). Users can only vote once per poll

'!poll results' - Displays the results from the poll

'!poll close' - Ends the poll

Users vote by adding the matching emoji to the poll (i.e. if the first choice has a :thumbsup: then in order to pick that choice the user has to react with :thumbsup:)

## Version 2.0
- Changed voting format to reactions (instead of '!poll vote')

## Wish List
## Wish List
- Add user configuration to only allow certain users to create polls
- Add auto-timing ability
- Add ability to run multiple polls at once
- Make emojis configurable
- Add placeholder emojis on each poll (to let users just click one)
2 changes: 1 addition & 1 deletion maubot.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ maubot: 0.1.0
id: casavant.tom.poll

# A PEP 440 compliant version string.
version: 1.0.1
version: 2.0.0

# The SPDX license identifier for the plugin. https://spdx.org/licenses/
# Optional, assumes all rights reserved if omitted.
Expand Down
43 changes: 19 additions & 24 deletions poll.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
import re
import random
from typing import List, Tuple
from mautrix.util.config import BaseProxyConfig, ConfigUpdateHelper
from mautrix.types import (EventType, ReactionEvent)
from maubot import Plugin, MessageEvent
from maubot.handlers import command


QUOTES_REGEX = r"\"?\s*?\"" # Regex to split string between quotes

# [Thumbs Up, Thumbs Down, Grinning, Ghost, Robot, Okay Hand, Clapping Hands, Hundred]
REACTIONS = ["\U0001F44D", "\U0001F44E", "\U0001F600", "\U0001F47B", "\U0001F916", "\U0001F44C", "\U0001F44F", "\U0001F4AF"]

class Poll:
def __init__(self, question, choices):
Expand All @@ -17,9 +20,11 @@ def __init__(self, question, choices):
self.active = True # Begins the poll
self.total = 0

self.emojis = random.sample(REACTIONS, len(choices)) # Select a random assortment of emojis

def vote(self, choice, user_id):
# Adds a vote to the given choice
self.votes[choice - 1] += 1
self.votes[choice] += 1
# Adds user to list of users who have already voted
self.voters.append(user_id)
self.total += 1
Expand Down Expand Up @@ -64,6 +69,7 @@ async def poll(self) -> None:
pass_raw=True,
required=True
)

async def handler(self, evt: MessageEvent, poll_setup: str) -> None:
await evt.mark_read()
r = re.compile(QUOTES_REGEX) # Compiles regex for quotes
Expand All @@ -78,30 +84,10 @@ async def handler(self, evt: MessageEvent, poll_setup: str) -> None:
self.currentPoll = Poll(question, choices)
# Show users active poll
choice_list = "<br />".join(
[f"{i+1}. {choice}" for i, choice in enumerate(choices)]
[f"{self.currentPoll.emojis[i]} - {choice}" for i, choice in enumerate(choices)]
)
response = f"{question}<br />{choice_list}"

await evt.reply(response, allow_html=True)

@poll.subcommand("vote", help="Votes for an option")
@command.argument(
"choice", pass_raw=True, required=True
)
async def handler(self, evt: MessageEvent, choice: int) -> None:
await evt.mark_read()
# Verify the user is able to vote
if self.currentPoll.hasVoted(evt.sender):
await evt.reply("You've already voted in this poll")
elif not self.currentPoll.isActive():
await evt.reply("I'm sorry this poll has already ended")
else:
# Checks if user entered a valid vote
if self.currentPoll.isAvailable(int(choice)):
# Makes the vote
self.currentPoll.vote(int(choice), evt.sender)
else:
await evt.reply("You must enter a valid choice")
self.currentPoll.event_id = await evt.reply(response, allow_html=True)

@poll.subcommand("results", help="Prints out the current results of the poll")
async def handler(self, evt: MessageEvent) -> None:
Expand All @@ -113,3 +99,12 @@ async def handler(self, evt: MessageEvent) -> None:
await evt.mark_read()
self.currentPoll.close_poll()
await evt.reply("This poll is now over. Type !poll results to see the results.")

@command.passive(regex=r"(?:("+'|'.join(REACTIONS) + r")[\U0001F3FB-\U0001F3FF]?)",
field=lambda evt: evt.content.relates_to.key,
event_type=EventType.REACTION, msgtypes=None)
async def get_react_vote(self, evt: ReactionEvent, _: Tuple[str]) -> None:
if (evt.content.relates_to.event_id == self.currentPoll.event_id): # Is this on the correct message?
if not self.currentPoll.hasVoted(evt.sender): # has the user already voted?
if (evt.content.relates_to.key in self.currentPoll.emojis): # Is this a possible choice?
self.currentPoll.vote(self.currentPoll.emojis.index(evt.content.relates_to.key), evt.sender) # Add vote/sender to poll

0 comments on commit 2b26bdd

Please sign in to comment.