1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
|
import logging
import random
from json import load
from pathlib import Path
from typing import Optional, Tuple
import discord
from discord.ext import commands
from discord.ext.commands.cooldowns import BucketType
from bot.constants import Channels, Client, Colours, Lovefest, Month
from bot.utils.decorators import in_month
log = logging.getLogger(__name__)
HEART_EMOJIS = [":heart:", ":gift_heart:", ":revolving_hearts:", ":sparkling_heart:", ":two_hearts:"]
class BeMyValentine(commands.Cog):
"""A cog that sends Valentines to other users!"""
def __init__(self, bot: commands.Bot):
self.bot = bot
self.valentines = self.load_json()
@staticmethod
def load_json() -> dict:
"""Load Valentines messages from the static resources."""
p = Path("bot/resources/valentines/bemyvalentine_valentines.json")
with p.open(encoding="utf8") as json_data:
valentines = load(json_data)
return valentines
@in_month(Month.FEBRUARY)
@commands.group(name="lovefest")
async def lovefest_role(self, ctx: commands.Context) -> None:
"""
Subscribe or unsubscribe from the lovefest role.
The lovefest role makes you eligible to receive anonymous valentines from other users.
1) use the command \".lovefest sub\" to get the lovefest role.
2) use the command \".lovefest unsub\" to get rid of the lovefest role.
"""
if not ctx.invoked_subcommand:
await ctx.send_help(ctx.command)
@lovefest_role.command(name="sub")
async def add_role(self, ctx: commands.Context) -> None:
"""Adds the lovefest role."""
user = ctx.author
role = discord.utils.get(ctx.guild.roles, id=Lovefest.role_id)
if Lovefest.role_id not in [role.id for role in ctx.message.author.roles]:
await user.add_roles(role)
await ctx.send("The Lovefest role has been added !")
else:
await ctx.send("You already have the role !")
@lovefest_role.command(name="unsub")
async def remove_role(self, ctx: commands.Context) -> None:
"""Removes the lovefest role."""
user = ctx.author
role = discord.utils.get(ctx.guild.roles, id=Lovefest.role_id)
if Lovefest.role_id not in [role.id for role in ctx.message.author.roles]:
await ctx.send("You dont have the lovefest role.")
else:
await user.remove_roles(role)
await ctx.send("The lovefest role has been successfully removed !")
@commands.cooldown(1, 1800, BucketType.user)
@commands.group(name='bemyvalentine', invoke_without_command=True)
async def send_valentine(
self, ctx: commands.Context, user: Optional[discord.Member] = None, *, valentine_type: str = None
) -> None:
"""
Send a valentine to user, if specified, or to a random user with the lovefest role.
syntax: .bemyvalentine [user](optional) [p/poem/c/compliment/or you can type your own valentine message]
(optional)
example: .bemyvalentine (sends valentine as a poem or a compliment to a random user)
example: .bemyvalentine Iceman#6508 p (sends a poem to Iceman)
example: .bemyvalentine Iceman Hey I love you, wanna hang around ? (sends the custom message to Iceman)
NOTE : AVOID TAGGING THE USER MOST OF THE TIMES.JUST TRIM THE '@' when using this command.
"""
if ctx.guild is None:
# This command should only be used in the server
msg = "You are supposed to use this command in the server."
return await ctx.send(msg)
if user:
if Lovefest.role_id not in [role.id for role in user.roles]:
message = f"You cannot send a valentine to {user} as he/she does not have the lovefest role!"
return await ctx.send(message)
if user == ctx.author:
# Well a user can't valentine himself/herself.
return await ctx.send("Come on dude, you can't send a valentine to yourself :expressionless:")
emoji_1, emoji_2 = self.random_emoji()
lovefest_role = discord.utils.get(ctx.guild.roles, id=Lovefest.role_id)
channel = self.bot.get_channel(Channels.community_bot_commands)
valentine, title = self.valentine_check(valentine_type)
if user is None:
author = ctx.author
user = self.random_user(author, lovefest_role.members)
if user is None:
return await ctx.send("There are no users avilable to whome your valentine can be sent.")
embed = discord.Embed(
title=f'{emoji_1} {title} {user.display_name} {emoji_2}',
description=f'{valentine} \n **{emoji_2}From {ctx.author}{emoji_1}**',
color=Colours.pink
)
await channel.send(user.mention, embed=embed)
@commands.cooldown(1, 1800, BucketType.user)
@send_valentine.command(name='secret')
async def anonymous(
self, ctx: commands.Context, user: Optional[discord.Member] = None, *, valentine_type: str = None
) -> None:
"""
Send an anonymous Valentine via DM to to a user, if specified, or to a random with the lovefest role.
**This command should be DMed to the bot.**
syntax : .bemyvalentine secret [user](optional) [p/poem/c/compliment/or you can type your own valentine message]
(optional)
example : .bemyvalentine secret (sends valentine as a poem or a compliment to a random user in DM making you
anonymous)
example : .bemyvalentine secret Iceman#6508 p (sends a poem to Iceman in DM making you anonymous)
example : .bemyvalentine secret Iceman#6508 Hey I love you, wanna hang around ? (sends the custom message to
Iceman in DM making you anonymous)
"""
if ctx.guild is not None:
# This command is only DM specific
msg = "You are not supposed to use this command in the server, DM the command to the bot."
return await ctx.send(msg)
if user:
if Lovefest.role_id not in [role.id for role in user.roles]:
message = f"You cannot send a valentine to {user} as he/she does not have the lovefest role!"
return await ctx.send(message)
if user == ctx.author:
# Well a user cant valentine himself/herself.
return await ctx.send('Come on dude, you cant send a valentine to yourself :expressionless:')
guild = self.bot.get_guild(id=Client.guild)
emoji_1, emoji_2 = self.random_emoji()
lovefest_role = discord.utils.get(guild.roles, id=Lovefest.role_id)
valentine, title = self.valentine_check(valentine_type)
if user is None:
author = ctx.author
user = self.random_user(author, lovefest_role.members)
if user is None:
return await ctx.send("There are no users avilable to whome your valentine can be sent.")
embed = discord.Embed(
title=f'{emoji_1}{title} {user.display_name}{emoji_2}',
description=f'{valentine} \n **{emoji_2}From anonymous{emoji_1}**',
color=Colours.pink
)
try:
await user.send(embed=embed)
except discord.Forbidden:
await ctx.author.send(f"{user} has DMs disabled, so I couldn't send the message. Sorry!")
else:
await ctx.author.send(f"Your message has been sent to {user}")
def valentine_check(self, valentine_type: str) -> Tuple[str, str]:
"""Return the appropriate Valentine type & title based on the invoking user's input."""
if valentine_type is None:
valentine, title = self.random_valentine()
elif valentine_type.lower() in ['p', 'poem']:
valentine = self.valentine_poem()
title = 'A poem dedicated to'
elif valentine_type.lower() in ['c', 'compliment']:
valentine = self.valentine_compliment()
title = 'A compliment for'
else:
# in this case, the user decides to type his own valentine.
valentine = valentine_type
title = 'A message for'
return valentine, title
@staticmethod
def random_user(author: discord.Member, members: discord.Member) -> None:
"""
Picks a random member from the list provided in `members`.
The invoking author is ignored.
"""
if author in members:
members.remove(author)
return random.choice(members) if members else None
@staticmethod
def random_emoji() -> Tuple[str, str]:
"""Return two random emoji from the module-defined constants."""
emoji_1 = random.choice(HEART_EMOJIS)
emoji_2 = random.choice(HEART_EMOJIS)
return emoji_1, emoji_2
def random_valentine(self) -> Tuple[str, str]:
"""Grabs a random poem or a compliment (any message)."""
valentine_poem = random.choice(self.valentines['valentine_poems'])
valentine_compliment = random.choice(self.valentines['valentine_compliments'])
random_valentine = random.choice([valentine_compliment, valentine_poem])
if random_valentine == valentine_poem:
title = 'A poem dedicated to'
else:
title = 'A compliment for '
return random_valentine, title
def valentine_poem(self) -> str:
"""Grabs a random poem."""
valentine_poem = random.choice(self.valentines['valentine_poems'])
return valentine_poem
def valentine_compliment(self) -> str:
"""Grabs a random compliment."""
valentine_compliment = random.choice(self.valentines['valentine_compliments'])
return valentine_compliment
def setup(bot: commands.Bot) -> None:
"""Be my Valentine Cog load."""
bot.add_cog(BeMyValentine(bot))
|