|
1 | 1 | import re |
2 | 2 | from typing import Iterable, cast |
3 | 3 |
|
| 4 | +import emoji |
4 | 5 | from discord import Message |
5 | 6 | from discord.ext.commands import Bot, Cog, Context, command |
6 | 7 |
|
7 | 8 | DEFAULT_VOTE_EMOJIS = ("👍", "👎") |
8 | | - |
9 | | -EMOJIS_PATTERN = re.compile( |
10 | | - "[" |
11 | | - "\U0001F1E0-\U0001F1FF" |
12 | | - "\U0001F300-\U0001F5FF" |
13 | | - "\U0001F600-\U0001F64F" |
14 | | - "\U0001F680-\U0001F6FF" |
15 | | - "\U0001F700-\U0001F77F" |
16 | | - "\U0001F780-\U0001F7FF" |
17 | | - "\U0001F800-\U0001F8FF" |
18 | | - "\U0001F900-\U0001F9FF" |
19 | | - "\U0001FA00-\U0001FA6F" |
20 | | - "\U0001FA70-\U0001FAFF" |
21 | | - "\U00002702-\U000027B0" |
22 | | - "\U000024C2-\U0001F251" |
23 | | - "\U0000200d" |
24 | | - "]+|" |
25 | | - r"\<\:\w+\:\d+\>" |
26 | | - "", |
27 | | - flags=re.UNICODE, |
28 | | -) |
| 9 | +CUSTOM_EMOJI_PATTERN = re.compile(r"\<\:\w+\:\d+\>") |
29 | 10 |
|
30 | 11 |
|
31 | 12 | class VoteCog(Cog, name="commanderbot_ext.ext.vote"): |
32 | 13 | def __init__(self, bot: Bot): |
33 | 14 | self.bot: Bot = bot |
34 | 15 |
|
35 | 16 | @staticmethod |
36 | | - def get_vote_emojis(message: Message) -> Iterable[str]: |
37 | | - # If the message has content, look for emojis within it. |
38 | | - if message.clean_content: |
39 | | - # If any emojis were found, use them instead of the defaults. |
40 | | - if found_emojis := EMOJIS_PATTERN.findall(str(message.clean_content)): |
41 | | - return found_emojis |
42 | | - # If nothing else was returned, use the default vote emojis. |
43 | | - return DEFAULT_VOTE_EMOJIS |
| 17 | + def get_emojis(message: Message) -> Iterable[str]: |
| 18 | + # Get message content and cast it to a string |
| 19 | + message_content: str = str(message.clean_content) |
| 20 | + |
| 21 | + # Find unicode and custom emojis in the message |
| 22 | + found_emojis: list[dict] = emoji.emoji_lis(message_content) |
| 23 | + for custom_emoji in CUSTOM_EMOJI_PATTERN.finditer(message_content): |
| 24 | + found_emojis.append( |
| 25 | + {"location": custom_emoji.start(), "emoji": custom_emoji.group()} |
| 26 | + ) |
| 27 | + |
| 28 | + # Return early with the default emojis if no emojis were found |
| 29 | + if not found_emojis: |
| 30 | + return DEFAULT_VOTE_EMOJIS |
| 31 | + |
| 32 | + # Create a list of unique emojis that are sorted in the order they appeared |
| 33 | + emojis: list[str] = [] |
| 34 | + for e in sorted(found_emojis, key=lambda i: i["location"]): |
| 35 | + emoji_char: str = str(e["emoji"]) |
| 36 | + if emoji_char not in emojis: |
| 37 | + emojis.append(emoji_char) |
| 38 | + |
| 39 | + return emojis |
44 | 40 |
|
45 | 41 | @command(name="vote") |
46 | 42 | async def cmd_vote(self, ctx: Context): |
47 | 43 | # Determine which emoji reactions to seed the message with, silently ignoring |
48 | 44 | # errors raised by any individual emoji. |
49 | | - for emoji in self.get_vote_emojis(cast(Message, ctx.message)): |
| 45 | + for emoji in self.get_emojis(cast(Message, ctx.message)): |
50 | 46 | try: |
51 | 47 | await ctx.message.add_reaction(emoji) |
52 | 48 | except: |
|
0 commit comments