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
|
import random
from json import loads
from pathlib import Path
import discord
from discord.ext import commands
from pydis_core.utils.logging import get_logger
from bot.bot import Bot
from bot.constants import Channels, Colours, Month, PYTHON_PREFIX, Roles
from bot.utils.decorators import in_month
from bot.utils.exceptions import MovedCommandError
log = get_logger(__name__)
HEART_EMOJIS = [":heart:", ":gift_heart:", ":revolving_hearts:", ":sparkling_heart:", ":two_hearts:"]
MOVED_COMMAND = f"{PYTHON_PREFIX}subscribe"
class BeMyValentine(commands.Cog):
"""A cog that sends Valentines to other users!"""
def __init__(self, bot: 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/holidays/valentines/bemyvalentine_valentines.json")
return loads(p.read_text("utf8"))
@in_month(Month.FEBRUARY)
@commands.command(name="lovefest", help=f"NOTE: This command has been moved to {MOVED_COMMAND}")
async def lovefest_role(self, ctx: commands.Context) -> None:
"""
Deprecated lovefest role command.
This command has been moved to bot, and will be removed in the future.
"""
raise MovedCommandError(MOVED_COMMAND)
@commands.cooldown(1, 1800, commands.BucketType.user)
@commands.group(name="bemyvalentine", invoke_without_command=True)
async def send_valentine(
self, ctx: commands.Context, user: discord.Member, *, valentine_type: str | None = None
) -> None:
"""
Send a valentine to a specified user with the lovefest role.
syntax: .bemyvalentine [user] [p/poem/c/compliment/or you can type your own valentine message]
(optional)
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
raise commands.UserInputError("You are supposed to use this command in the server.")
if Roles.lovefest not in [role.id for role in user.roles]:
raise commands.UserInputError(
f"You cannot send a valentine to {user} as they do not have the lovefest role!"
)
if user == ctx.author:
# Well a user can't valentine himself/herself.
raise commands.UserInputError("Come on, you can't send a valentine to yourself :expressionless:")
emoji_1, emoji_2 = self.random_emoji()
channel = self.bot.get_channel(Channels.sir_lancebot_playground)
valentine, title = self.valentine_check(valentine_type)
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, commands.BucketType.user)
@send_valentine.command(name="secret")
async def anonymous(
self, ctx: commands.Context, user: discord.Member, *, valentine_type: str | None = None
) -> None:
"""
Send an anonymous Valentine via DM to to a specified user with the lovefest role.
syntax : .bemyvalentine secret [user] [p/poem/c/compliment/or you can type your own valentine message]
(optional)
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 Roles.lovefest not in [role.id for role in user.roles]:
await ctx.message.delete()
raise commands.UserInputError(
f"You cannot send a valentine to {user} as they do not have the lovefest role!"
)
if user == ctx.author:
# Well a user cant valentine himself/herself.
raise commands.UserInputError("Come on, you can't send a valentine to yourself :expressionless:")
emoji_1, emoji_2 = self.random_emoji()
valentine, title = self.valentine_check(valentine_type)
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
)
await ctx.message.delete()
try:
await user.send(embed=embed)
except discord.Forbidden:
raise commands.UserInputError(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:
return self.random_valentine()
if valentine_type.lower() in ["p", "poem"]:
return self.valentine_poem(), "A poem dedicated to"
if valentine_type.lower() in ["c", "compliment"]:
return self.valentine_compliment(), "A compliment for"
# in this case, the user decides to type his own valentine.
return valentine_type, "A message for"
@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])
title = "A poem dedicated to" if random_valentine == valentine_poem else "A compliment for "
return random_valentine, title
def valentine_poem(self) -> str:
"""Grabs a random poem."""
return random.choice(self.valentines["valentine_poems"])
def valentine_compliment(self) -> str:
"""Grabs a random compliment."""
return random.choice(self.valentines["valentine_compliments"])
async def setup(bot: Bot) -> None:
"""Load the Be my Valentine Cog."""
await bot.add_cog(BeMyValentine(bot))
|