Need to have one view.

This commit is contained in:
2023-12-16 22:20:36 -05:00
parent ee13019a0f
commit 88d8e6178c
3 changed files with 122 additions and 147 deletions
-139
View File
@@ -1,139 +0,0 @@
"""
Contains various views to be used in the clan leader nomination process.
"""
import nextcord
from nextcord.interactions import Interaction
from sqlalchemy import select
from sqlalchemy.orm import Session
from config import DakinyConfig
from database_setup.sql_data_classes import CouncilMembers, engine
from utils import NOMINEE_SPLITTER, decorate_nomination, get_election_cycle_name
class NominateCLModal(nextcord.ui.Modal):
"""
Modal for nominating oneself. User writes a speech and then the callback sends the speech into the correct channel.
"""
def __init__(
self,
config: DakinyConfig,
usr_id: int,
usr_nominated: bool,
speech_content: str,
):
super().__init__(
"Clan Leader Nomination",
timeout=5 * 60, # 5 minutes
)
self.usr_id: int = usr_id
self.config: DakinyConfig = config
self.usr_nominated = usr_nominated
self.speech = nextcord.ui.TextInput(
label="Nomination Speech",
style=nextcord.TextInputStyle.paragraph,
placeholder="Please write your speech here.",
required=True,
max_length=1500,
default_value=speech_content,
)
self.add_item(self.speech)
async def callback(self, interaction: Interaction) -> None:
"""
Sends the nomination speech into the voting channel and enters the user into the voting database.
Args:
interaction (Interaction): Interaction with user.
"""
speech = decorate_nomination(interaction.user.id, self.speech.value)
with Session(engine) as session:
# user already in table
cycle = get_election_cycle_name(self.config)
stmt = (
select(CouncilMembers)
.where(CouncilMembers.ElectionCycle == cycle)
.where(CouncilMembers.MemberId == self.usr_id)
)
council_elect = session.scalar(stmt)
if not self.usr_nominated:
msg = await interaction.channel.send(speech)
council_elect.ClanLeaderSpeechId = msg.id
session.commit()
else:
msg: nextcord.Message = await interaction.channel.fetch_message(
council_elect.ClanLeaderSpeechId
)
await msg.edit(
content=decorate_nomination(interaction.user.id, self.speech.value)
)
class NominateCLView(nextcord.ui.View):
"""
The button to press to start your Clan Leader nomination.
"""
def __init__(self, config: DakinyConfig, guild: nextcord.Guild):
super().__init__(timeout=None)
self.config: DakinyConfig = config
self.guild: nextcord.Guild = guild
@nextcord.ui.button(
label="Nominate for Clan Leader",
style=nextcord.ButtonStyle.primary,
custom_id="nominate-cl",
)
async def nominate(
self, button: nextcord.ui.Button, interaction: nextcord.Interaction
) -> None:
"""
Gathers previous information about the user if they have already nominated themselves, then launches
the nomination modal to get their speech.
Args:
button (nextcord.ui.Button): Unused. idk why its needed in the decorator
interaction (nextcord.Interaction): Interaction of user who pressed the button
"""
# enforce council elect only
if (
self.guild.get_role(self.config.params.clan_council_elect_role_id)
not in interaction.user.roles
):
await interaction.response.send_message(
f"You must have the <@&{self.config.params.clan_council_elect_role_id}> role to vote.",
ephemeral=True,
)
return
cycle = get_election_cycle_name(self.config)
usr_nominated = False
speech_content = ""
with Session(engine) as session:
stmt = (
select(CouncilMembers)
.where(CouncilMembers.ElectionCycle == cycle)
.where(CouncilMembers.MemberId == interaction.user.id)
)
obj = session.scalar(stmt)
# user needs to exist to get here anyways...
if obj.ClanLeaderSpeechId is not None:
usr_nominated = True
msg = await interaction.channel.fetch_message(obj.ClanLeaderSpeechId)
speech_content = msg.content.split(NOMINEE_SPLITTER)[1]
await interaction.response.send_modal(
NominateCLModal(
self.config, interaction.user.id, usr_nominated, speech_content
)
)
@@ -1,5 +1,5 @@
"""
Contains various views to be used in the discord manager nomination process.
Contains various views to be used in the high council nomination process.
"""
import nextcord
@@ -77,9 +77,74 @@ class NominateDMModal(nextcord.ui.Modal):
)
class NominateDMView(nextcord.ui.View):
class NominateCLModal(nextcord.ui.Modal):
"""
The button to press to start your Discord Manager nomination.
Modal for nominating oneself. User writes a speech and then the callback sends the speech into the correct channel.
"""
def __init__(
self,
config: DakinyConfig,
usr_id: int,
usr_nominated: bool,
speech_content: str,
):
super().__init__(
"Clan Leader Nomination",
timeout=5 * 60, # 5 minutes
)
self.usr_id: int = usr_id
self.config: DakinyConfig = config
self.usr_nominated = usr_nominated
self.speech = nextcord.ui.TextInput(
label="Nomination Speech",
style=nextcord.TextInputStyle.paragraph,
placeholder="Please write your speech here.",
required=True,
max_length=1500,
default_value=speech_content,
)
self.add_item(self.speech)
async def callback(self, interaction: Interaction) -> None:
"""
Sends the nomination speech into the voting channel and enters the user into the voting database.
Args:
interaction (Interaction): Interaction with user.
"""
speech = decorate_nomination(interaction.user.id, self.speech.value)
with Session(engine) as session:
# user already in table
cycle = get_election_cycle_name(self.config)
stmt = (
select(CouncilMembers)
.where(CouncilMembers.ElectionCycle == cycle)
.where(CouncilMembers.MemberId == self.usr_id)
)
council_elect = session.scalar(stmt)
if not self.usr_nominated:
msg = await interaction.channel.send(speech)
council_elect.ClanLeaderSpeechId = msg.id
session.commit()
else:
msg: nextcord.Message = await interaction.channel.fetch_message(
council_elect.ClanLeaderSpeechId
)
await msg.edit(
content=decorate_nomination(interaction.user.id, self.speech.value)
)
class NominateHighCouncilView(nextcord.ui.View):
"""
The buttons to press to start your High Council nomination.
"""
def __init__(self, config: DakinyConfig, guild: nextcord.Guild):
@@ -92,7 +157,7 @@ class NominateDMView(nextcord.ui.View):
style=nextcord.ButtonStyle.primary,
custom_id="nominate-dm",
)
async def nominate(
async def nominate_dm(
self, button: nextcord.ui.Button, interaction: nextcord.Interaction
) -> None:
"""
@@ -139,3 +204,54 @@ class NominateDMView(nextcord.ui.View):
self.config, interaction.user.id, usr_nominated, speech_content
)
)
@nextcord.ui.button(
label="Nominate for Clan Leader",
style=nextcord.ButtonStyle.primary,
custom_id="nominate-cl",
)
async def nominate_cl(
self, button: nextcord.ui.Button, interaction: nextcord.Interaction
) -> None:
"""
Gathers previous information about the user if they have already nominated themselves, then launches
the nomination modal to get their speech.
Args:
button (nextcord.ui.Button): Unused. idk why its needed in the decorator
interaction (nextcord.Interaction): Interaction of user who pressed the button
"""
# enforce council elect only
if (
self.guild.get_role(self.config.params.clan_council_elect_role_id)
not in interaction.user.roles
):
await interaction.response.send_message(
f"You must have the <@&{self.config.params.clan_council_elect_role_id}> role to vote.",
ephemeral=True,
)
return
cycle = get_election_cycle_name(self.config)
usr_nominated = False
speech_content = ""
with Session(engine) as session:
stmt = (
select(CouncilMembers)
.where(CouncilMembers.ElectionCycle == cycle)
.where(CouncilMembers.MemberId == interaction.user.id)
)
obj = session.scalar(stmt)
# user needs to exist to get here anyways...
if obj.ClanLeaderSpeechId is not None:
usr_nominated = True
msg = await interaction.channel.fetch_message(obj.ClanLeaderSpeechId)
speech_content = msg.content.split(NOMINEE_SPLITTER)[1]
await interaction.response.send_modal(
NominateCLModal(
self.config, interaction.user.id, usr_nominated, speech_content
)
)
+2 -4
View File
@@ -8,8 +8,7 @@ from hydra.core.config_store import ConfigStore
from nextcord.ext import commands
import database_setup.create_database as create_database
from classes.nominate_cl_views import NominateCLView
from classes.nominate_dm_views import NominateDMView
from classes.nominate_highcouncil_views import NominateHighCouncilView
from classes.nominate_views import NominateView
from classes.voting_views import VoteView
from config import DakinyConfig
@@ -56,8 +55,7 @@ def main(cfg: DakinyConfig):
assert bot.user is not None
create_database # pylint: disable=pointless-statement
bot.add_view(NominateView(cfg, bot.get_guild(cfg.params.guild_id)))
bot.add_view(NominateCLView(cfg, bot.get_guild(cfg.params.guild_id)))
bot.add_view(NominateDMView(cfg, bot.get_guild(cfg.params.guild_id)))
bot.add_view(NominateHighCouncilView(cfg, bot.get_guild(cfg.params.guild_id)))
bot.add_view(VoteView(cfg, bot.get_guild(cfg.params.guild_id)))
print(f"{bot.user.name} has connected to Discord!")