Skip to content

Commit ccb66ec

Browse files
committed
try
1 parent af50efd commit ccb66ec

File tree

1 file changed

+90
-71
lines changed

1 file changed

+90
-71
lines changed

draft_vote.py

Lines changed: 90 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,18 @@
22
import time
33
import os
44
from typing import Optional, List
5-
from datetime import datetime
5+
from datetime import datetime, timedelta
6+
import logging
67

78
import discord
89
from discord.ext import commands
910
from discord import ButtonStyle
1011

1112
from draft_database import DraftDatabase
1213

14+
# Set up logger
15+
logger = logging.getLogger(__name__)
16+
1317

1418
def log_vote(message: str) -> None:
1519
"""Log vote events to a file."""
@@ -21,9 +25,28 @@ def log_vote(message: str) -> None:
2125
file.write(f"[{timestamp}] {message}\n")
2226

2327

24-
class VoteView(discord.ui.View):
25-
"""A view containing the voting buttons and result handling."""
28+
class ReviewModal(discord.Modal):
29+
def __init__(self, is_approval: bool) -> None:
30+
title = "Draft Review" if is_approval else "Draft Rejection"
31+
super().__init__(title=title)
32+
33+
self.input = discord.TextInput(
34+
label="Categories" if is_approval else "Rejection Reason",
35+
placeholder=("Enter categories separated by commas" if is_approval
36+
else "Enter reason for rejection"),
37+
style=discord.TextStyle.paragraph,
38+
required=True,
39+
row=0
40+
)
41+
self.add_item(self.input)
42+
self.result = None
2643

44+
async def callback(self, interaction: discord.Interaction):
45+
self.result = self.input.value
46+
await interaction.response.defer()
47+
48+
49+
class VoteView(discord.ui.View):
2750
def __init__(self,
2851
author: str,
2952
draft_name: str,
@@ -33,15 +56,33 @@ def __init__(self,
3356
self.author = author
3457
self.draft_name = draft_name
3558
self.required_votes = required_votes
36-
self.approve_votes: List[int] = [] # Store user IDs
59+
self.approve_votes: List[int] = []
3760
self.reject_votes: List[int] = []
38-
self.result: Optional[bool] = None # True for approve, False for reject
61+
self.result: Optional[bool] = None
62+
self.end_time = int((datetime.now() + timedelta(seconds=timeout)).timestamp())
63+
self.message = None
3964

40-
@discord.ui.button(label="Approve (0)", style=ButtonStyle.green, emoji="✅")
65+
def _create_status_embed(self) -> discord.Embed:
66+
"""Create an embed showing the current voting status."""
67+
embed = discord.Embed(
68+
title=f"Vote: {self.draft_name}",
69+
description=(
70+
f"Draft by {self.author}\n\n"
71+
f"Required votes: {self.required_votes}\n"
72+
f"Ends: <t:{self.end_time}:R>\n\n"
73+
f"Current status:\n"
74+
f"✅ Approve: {len(self.approve_votes)}\n"
75+
f"❌ Reject: {len(self.reject_votes)}"
76+
),
77+
color=discord.Color.blue()
78+
)
79+
return embed
80+
81+
@discord.ui.button(label="Approve (0)", style=discord.ButtonStyle.green, emoji="✅")
4182
async def approve(self, button: discord.ui.Button, interaction: discord.Interaction):
4283
await self._handle_vote(interaction, True)
4384

44-
@discord.ui.button(label="Reject (0)", style=ButtonStyle.red, emoji="❌")
85+
@discord.ui.button(label="Reject (0)", style=discord.ButtonStyle.red, emoji="❌")
4586
async def reject(self, button: discord.ui.Button, interaction: discord.Interaction):
4687
await self._handle_vote(interaction, False)
4788

@@ -77,46 +118,18 @@ async def _handle_vote(self, interaction: discord.Interaction, is_approve: bool)
77118
embed = self._create_status_embed()
78119
await interaction.response.edit_message(embed=embed, view=self)
79120

80-
def _create_status_embed(self) -> discord.Embed:
81-
"""Create an embed showing the current voting status."""
82-
embed = discord.Embed(
83-
title=f"Vote: {self.draft_name}",
84-
description=f"Draft by {self.author}\n\n"
85-
f"Required votes: {self.required_votes}\n"
86-
f"Current status:\n"
87-
f"✅ Approve: {len(self.approve_votes)}\n"
88-
f"❌ Reject: {len(self.reject_votes)}",
89-
color=discord.Color.blue()
90-
)
91-
return embed
92-
93-
94-
class ReviewModal(discord.ui.Modal):
95-
"""Modal for entering review comments."""
96-
97-
def __init__(self, is_approval: bool) -> None:
98-
title = "Draft Review" if is_approval else "Draft Rejection"
99-
super().__init__(title=title)
100-
101-
self.input = discord.ui.TextInput(
102-
label="Categories" if is_approval else "Rejection Reason",
103-
placeholder=("Enter categories separated by commas" if is_approval
104-
else "Enter reason for rejection"),
105-
style=discord.TextStyle.paragraph,
106-
required=True
107-
)
108-
self.add_item(self.input)
109-
self.result = None
110-
111-
async def callback(self, interaction: discord.Interaction):
112-
self.result = self.input.value
113-
await interaction.response.defer()
121+
async def on_timeout(self) -> None:
122+
"""Handle view timeout"""
123+
for item in self.children:
124+
item.disabled = True
125+
if self.message:
126+
await self.message.edit(view=self)
114127

115128

116129
class DraftVote(commands.Cog):
117130
def __init__(self, bot: commands.Bot):
118131
self.bot = bot
119-
db_path = os.getenv('DATABASE_PATH', 'drafts.db')
132+
db_path = os.getenv('DRAFT_DB_PATH', 'drafts.db')
120133
self.db = DraftDatabase(db_path)
121134

122135
@discord.slash_command(
@@ -147,12 +160,13 @@ async def vote(
147160
Duration of vote in hours (default: 24)
148161
"""
149162
await ctx.defer()
163+
150164
try:
151165
# Verify draft exists
152166
draft_title = f"User:{author}/Drafts/{draft_name}"
153167
draft = self.db.get_draft(draft_title)
154168
if not draft:
155-
await ctx.respond(
169+
await ctx.followup.send(
156170
f"Error: Draft '{draft_name}' by {author} not found.",
157171
ephemeral=True
158172
)
@@ -168,44 +182,49 @@ async def vote(
168182

169183
embed = view._create_status_embed()
170184
message = await ctx.followup.send(embed=embed, view=view)
185+
view.message = message
171186

172187
log_vote(f"Vote started for {draft_name} by {author}")
173188

174-
# Wait for voting to complete
175189
try:
176190
await view.wait()
191+
192+
if view.result is None: # Timeout
193+
await ctx.followup.send("Vote has timed out.")
194+
return
195+
196+
# Handle vote result
197+
modal = ReviewModal(is_approval=view.result)
198+
await ctx.interaction.response.send_modal(modal)
199+
await modal.wait()
200+
201+
if view.result: # Approved
202+
await self.bot.get_cog('DraftBot').approve(author, draft_name, modal.result)
203+
result_embed = discord.Embed(
204+
title="Draft Approved",
205+
description=f"{draft_name} by {author} has been approved.",
206+
color=discord.Color.green()
207+
)
208+
else: # Rejected
209+
await self.bot.get_cog('DraftBot').reject(author, draft_name, modal.result)
210+
result_embed = discord.Embed(
211+
title="Draft Rejected",
212+
description=f"{draft_name} by {author} has been rejected.",
213+
color=discord.Color.red()
214+
)
215+
216+
await ctx.followup.send(embed=result_embed)
217+
log_vote(f"Vote completed for {draft_name} by {author}: {'Approved' if view.result else 'Rejected'}")
218+
177219
except asyncio.TimeoutError:
178220
log_vote(f"Vote timed out for {draft_name} by {author}")
179221
await message.edit(content="Vote has timed out.", view=None)
180222
return
181223

182-
# Handle vote result
183-
modal = ReviewModal(is_approval=view.result)
184-
await ctx.interaction.response.send_modal(modal)
185-
await modal.wait()
186-
187-
if view.result: # Approved
188-
await self.bot.get_cog('DraftBot').approve(author, draft_name, modal.result)
189-
result_embed = discord.Embed(
190-
title="Draft Approved",
191-
description=f"{draft_name} by {author} has been approved.",
192-
color=discord.Color.green()
193-
)
194-
else: # Rejected
195-
await self.bot.get_cog('DraftBot').reject(author, draft_name, modal.result)
196-
result_embed = discord.Embed(
197-
title="Draft Rejected",
198-
description=f"{draft_name} by {author} has been rejected.",
199-
color=discord.Color.red()
200-
)
201-
202-
await ctx.send(embed=result_embed)
203-
log_vote(f"Vote completed for {draft_name} by {author}: {'Approved' if view.result else 'Rejected'}")
204-
205224
except Exception as e:
206-
await ctx.followup.send(f"An error occurred: {str(e)}", ephemeral=True)
207225
logger.error(f"Error in vote command: {str(e)}", exc_info=True)
226+
await ctx.followup.send(f"An error occurred: {str(e)}", ephemeral=True)
227+
208228

209-
def setup(bot):
210-
print("Setting up DraftVote cog") # Debug print
211-
bot.add_cog(DraftVote(bot))
229+
def setup(bot: commands.Bot):
230+
bot.add_cog(DraftVote(bot))

0 commit comments

Comments
 (0)