forked from kemonomimi/nyabot
main+data_manager: Started work on marriage system
This commit adds a data_manager submodule that handles reading/writing data. For now it's backed by a single json file, but in the future we should move to a sqlite3 database The marriage system uses Discord Interactions and views, and works for basic things TODO: - Poly marriage support - Listing marriages through a command
This commit is contained in:
parent
406d3b5c8f
commit
95139026e5
3 changed files with 175 additions and 1 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1 +1,2 @@
|
|||
token
|
||||
data.json
|
||||
|
|
51
data_manager.py
Normal file
51
data_manager.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
# TODO: If you need to grow this class, consider moving to a sqlite3 database!
|
||||
|
||||
import io
|
||||
import json
|
||||
|
||||
DATA_PATH = "data.json"
|
||||
|
||||
|
||||
def __load_json_or_make_empty_object(fp: io.TextIOWrapper):
|
||||
data = {}
|
||||
fp.seek(0)
|
||||
try:
|
||||
data = json.load(fp)
|
||||
except ValueError as exception:
|
||||
print(exception, DATA_PATH, "wasn't a JSON file, making it one...")
|
||||
# fp doesn't point to a file with valid json, replacing the content with "{}"
|
||||
fp.seek(0)
|
||||
fp.write("{}")
|
||||
fp.truncate()
|
||||
fp.flush()
|
||||
return {}
|
||||
return data
|
||||
|
||||
|
||||
def get_data() -> dict:
|
||||
with open(DATA_PATH, 'a+') as fp:
|
||||
return __load_json_or_make_empty_object(fp)
|
||||
|
||||
|
||||
# Helper class for writing to the data file in a sage way
|
||||
class DataWriter:
|
||||
def __init__(self) -> None:
|
||||
self.__data_fp: io.TextIOWrapper | None = None
|
||||
|
||||
def __enter__(self):
|
||||
self.__data_fp = open(DATA_PATH, 'w+')
|
||||
return self
|
||||
|
||||
def __exit__(self, *_):
|
||||
if self.__data_fp is not None:
|
||||
self.__data_fp.close()
|
||||
|
||||
# Set a new value to the data
|
||||
def set_data(self, json_data: dict):
|
||||
if self.__data_fp is None:
|
||||
return
|
||||
|
||||
self.__data_fp.seek(0)
|
||||
json.dump(json_data, self.__data_fp)
|
||||
self.__data_fp.truncate()
|
||||
self.__data_fp.flush()
|
122
main.py
122
main.py
|
@ -4,6 +4,8 @@ import discord
|
|||
import json
|
||||
import random
|
||||
|
||||
import data_manager
|
||||
|
||||
intents = discord.Intents.default()
|
||||
intents.message_content = True
|
||||
|
||||
|
@ -35,12 +37,132 @@ boop - Boops target user
|
|||
Slash commands:
|
||||
```
|
||||
/help - Shows this message
|
||||
/marry - Marries someone
|
||||
```
|
||||
"""
|
||||
|
||||
|
||||
def __find_mariage_for_member_id(member_id: int) -> list[int]:
|
||||
data = data_manager.get_data()
|
||||
if "marriages" not in data:
|
||||
data["marriages"] = []
|
||||
with data_manager.DataWriter() as writer:
|
||||
writer.set_data(data)
|
||||
return []
|
||||
|
||||
for marriage in data["marriages"]:
|
||||
if member_id in marriage:
|
||||
return marriage
|
||||
|
||||
return []
|
||||
|
||||
# Interraction views
|
||||
|
||||
|
||||
class MariageConfirmationView(discord.ui.View):
|
||||
def __init__(self, target: discord.Member):
|
||||
super().__init__()
|
||||
self.timeout = None
|
||||
self.marriage_accepted: bool | None = None
|
||||
self.target = target
|
||||
|
||||
@discord.ui.button(label="Accept", style=discord.ButtonStyle.green, row=1)
|
||||
async def accept(self, _: discord.ui.Button, interaction: discord.Interaction):
|
||||
if interaction.user != self.target:
|
||||
print(interaction.user, self.target)
|
||||
await interaction.response.send_message(
|
||||
"ur not the one getting married, silly :3"
|
||||
)
|
||||
return
|
||||
|
||||
user_who_replied = interaction.user
|
||||
mention = user_who_replied.mention \
|
||||
if user_who_replied is not None else "<something went wrong :‹>"
|
||||
await interaction.response.send_message(
|
||||
f"{mention} accepted the proposal :3 lovely"
|
||||
)
|
||||
|
||||
self.marriage_accepted = True
|
||||
self.stop()
|
||||
|
||||
@discord.ui.button(label="Deny", style=discord.ButtonStyle.red, row=1)
|
||||
async def deny(self, _: discord.ui.Button, interaction: discord.Interaction):
|
||||
if interaction.user != self.target:
|
||||
await interaction.response.send_message(
|
||||
"ur not the one getting married, silly :3"
|
||||
)
|
||||
return
|
||||
|
||||
user_who_replied = interaction.user
|
||||
mention = user_who_replied.mention \
|
||||
if user_who_replied is not None else "<something went wrong :‹>"
|
||||
|
||||
await interaction.response.send_message(
|
||||
f"{mention} didn't wanna get married yet..."
|
||||
)
|
||||
|
||||
self.marriage_accepted = False
|
||||
self.stop()
|
||||
|
||||
# Slash commands
|
||||
|
||||
|
||||
@bot.slash_command()
|
||||
@discord.guild_only()
|
||||
@discord.option(
|
||||
"target", type=discord.Member,
|
||||
description="Which user to marry",
|
||||
required=False,
|
||||
)
|
||||
async def marry(
|
||||
context: discord.ApplicationContext, member_to_marry: discord.Member
|
||||
):
|
||||
# Check if the person asked in mariage is interested
|
||||
marriage_asker = context.author
|
||||
if marriage_asker is None:
|
||||
await context.respond("ow :/ something went wonky wonky, try again!")
|
||||
return
|
||||
|
||||
marriage_confirmation = MariageConfirmationView(member_to_marry)
|
||||
await context.respond(
|
||||
f"{member_to_marry.mention}, would you like to marry"
|
||||
+ f" {marriage_asker.mention}?", view=marriage_confirmation)
|
||||
|
||||
await marriage_confirmation.wait()
|
||||
if marriage_confirmation.marriage_accepted is None:
|
||||
await context.respond("silly little bug going on :3 try again l8er :3")
|
||||
return
|
||||
|
||||
if marriage_confirmation.marriage_accepted == False:
|
||||
await context.respond(
|
||||
"no consent == no marriage! consent is key to a happy life :3"
|
||||
)
|
||||
|
||||
# Marriage was accepted, yay :3!
|
||||
askers_marriage = __find_mariage_for_member_id(marriage_asker.id)
|
||||
askees_marriage = __find_mariage_for_member_id(member_to_marry.id)
|
||||
|
||||
# Now check for polycules
|
||||
if len(askees_marriage) == 0 and len(askers_marriage) == 0:
|
||||
# No polycules, just update the records to marry the two :3
|
||||
data = data_manager.get_data()
|
||||
data["marriages"].append([marriage_asker.id, member_to_marry.id])
|
||||
with data_manager.DataWriter() as writer:
|
||||
writer.set_data(data)
|
||||
|
||||
await context.respond(
|
||||
f"{marriage_asker.mention} married {member_to_marry.mention}"
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
await context.respond(
|
||||
"ooh looks like you're trying to do a ploly marriage..." +
|
||||
" unfortunately, that's still a work in progress," +
|
||||
" come back later to register it :3"
|
||||
)
|
||||
|
||||
|
||||
@bot.slash_command()
|
||||
async def help(ctx: discord.ApplicationContext):
|
||||
await ctx.respond(HELP_MESSAGE)
|
||||
|
|
Loading…
Reference in a new issue