131 lines
7.8 KiB
Python
131 lines
7.8 KiB
Python
import discord
|
|
from discord import app_commands
|
|
from .database import add_project, get_project_id, get_project_name, add_task_to_project, update_task, list_projects, list_tasks_for_project, remove_task, remove_project
|
|
from .consent import check_user_consent, store_user_consent, revoke_user_consent
|
|
from datetime import datetime
|
|
import logging
|
|
|
|
logger = logging.getLogger('Dolly')
|
|
|
|
class ProjectCommands(app_commands.Group):
|
|
def __init__(self):
|
|
super().__init__(name="project", description="Manage projects.")
|
|
|
|
@app_commands.command(name="create", description="Create a new project.")
|
|
async def create_project(self, interaction: discord.Interaction, name: str, description: str):
|
|
try:
|
|
project_id = await add_project(name, description)
|
|
await interaction.response.send_message(f"Project '{name}' created successfully with ID: {project_id}.")
|
|
except Exception as e:
|
|
await interaction.response.send_message("An error occurred while creating the project.", ephemeral=True)
|
|
logger.error(f"Error in create_project: {e}")
|
|
|
|
@app_commands.command(name="list", description="List all projects.")
|
|
async def list_projects(self, interaction: discord.Interaction):
|
|
try:
|
|
projects = await list_projects()
|
|
if projects:
|
|
message = "\n".join([f"ID: {id}, Name: {name}, Description: {description}" for id, name, description in projects])
|
|
await interaction.response.send_message(f"Projects:\n{message}")
|
|
else:
|
|
await interaction.response.send_message("No projects found.")
|
|
except Exception as e:
|
|
await interaction.response.send_message("Failed to retrieve projects.", ephemeral=True)
|
|
logger.error(f"Error in list_projects: {e}")
|
|
|
|
@app_commands.command(name="remove", description="Remove a specific project and all its tasks.")
|
|
async def remove_project_command(self, interaction: discord.Interaction, project_id: int):
|
|
try:
|
|
await remove_project(project_id)
|
|
await interaction.response.send_message(f"Project ID {project_id} and all associated tasks have been successfully removed.")
|
|
logger.info(f"Project ID {project_id} and all associated tasks removed successfully.")
|
|
except Exception as e:
|
|
await interaction.response.send_message("Failed to remove the project.", ephemeral=True)
|
|
logger.error(f"Error in remove_project_command: {e}")
|
|
|
|
class TaskCommands(app_commands.Group):
|
|
def __init__(self):
|
|
super().__init__(name="task", description="Manage tasks.")
|
|
|
|
@app_commands.command(name="add", description="Add a new task to a project.")
|
|
async def add_task(self, interaction: discord.Interaction, project_name: str, description: str, assignee: str, deadline: str, status: str, priority: str):
|
|
try:
|
|
datetime.strptime(deadline, "%m/%d/%Y") # Validate date format
|
|
project_id = await get_project_id(project_name)
|
|
if project_id:
|
|
await add_task_to_project(project_id, description, assignee, deadline, status, priority)
|
|
await interaction.response.send_message(f"Task '{description}' added to project '{project_name}'.")
|
|
logger.info(f"Task added to project {project_name}: {description}")
|
|
else:
|
|
await interaction.response.send_message(f"Project '{project_name}' not found.", ephemeral=True)
|
|
logger.warning(f"Attempted to add task to non-existent project: {project_name}")
|
|
except ValueError:
|
|
await interaction.response.send_message("Invalid date format. Please use MM/DD/YYYY format.", ephemeral=True)
|
|
logger.error(f"Invalid date format provided by user: {deadline}")
|
|
except Exception as e:
|
|
await interaction.response.send_message("An error occurred while adding the task.", ephemeral=True)
|
|
logger.error(f"Unexpected error in add_task: {e}")
|
|
|
|
@app_commands.command(name="update", description="Update an existing task.")
|
|
async def update_task_command(self, interaction: discord.Interaction, task_id: int, description: str, assignee: str, deadline: str, status: str, priority: str):
|
|
try:
|
|
datetime.strptime(deadline, "%m/%d/%Y") # Validate date format
|
|
await update_task(task_id, description, assignee, deadline, status, priority)
|
|
await interaction.response.send_message(f"Task ID {task_id} updated successfully.")
|
|
logger.info(f"Task ID {task_id} updated: {description}")
|
|
except ValueError:
|
|
await interaction.response.send_message("Invalid date format. Please use MM/DD/YYYY format.", ephemeral=True)
|
|
logger.error(f"Invalid date format provided by user for task update: {deadline}")
|
|
except Exception as e:
|
|
await interaction.response.send_message("An error occurred while updating the task.", ephemeral=True)
|
|
logger.error(f"Unexpected error in update_task_command: {e}")
|
|
|
|
@app_commands.command(name="list", description="List tasks for a project.")
|
|
async def list_tasks(self, interaction: discord.Interaction, project_id: int):
|
|
try:
|
|
project_name = await get_project_name(project_id)
|
|
if not project_name:
|
|
await interaction.response.send_message(f"No project found with ID {project_id}.", ephemeral=True)
|
|
return
|
|
|
|
tasks = await list_tasks_for_project(project_id)
|
|
if tasks:
|
|
message = "\n".join([f"ID: {id}, Description: {description}, Assignee: {assignee}, Deadline: {deadline}, Status: {status}, Priority: {priority}"
|
|
for id, description, assignee, deadline, status, priority in tasks])
|
|
await interaction.response.send_message(f"Tasks for Project '{project_name}':\n{message}")
|
|
else:
|
|
await interaction.response.send_message(f"No tasks found for project '{project_name}'.")
|
|
except Exception as e:
|
|
await interaction.response.send_message(f"Failed to retrieve tasks for project ID {project_id}.", ephemeral=True)
|
|
logger.error(f"Error in list_tasks: {e}")
|
|
|
|
@app_commands.command(name="remove", description="Remove a specific task.")
|
|
async def remove_task_command(self, interaction: discord.Interaction, task_id: int):
|
|
try:
|
|
await remove_task(task_id)
|
|
await interaction.response.send_message(f"Task ID {task_id} has been successfully removed.")
|
|
logger.info(f"Task ID {task_id} removed successfully.")
|
|
except Exception as e:
|
|
await interaction.response.send_message("Failed to remove the task.", ephemeral=True)
|
|
logger.error(f"Error in remove_task_command: {e}")
|
|
|
|
class ConsentCommands(app_commands.Group):
|
|
def __init__(self):
|
|
super().__init__(name="consent", description="Manage data consent settings.")
|
|
|
|
@app_commands.command(name="opt-in", description="Opt-in to data storage and use the bot.")
|
|
async def opt_in(self, interaction: discord.Interaction):
|
|
await store_user_consent(interaction.user.id)
|
|
await interaction.response.send_message("You have opted in to data storage. You can now use the bot.", ephemeral=True)
|
|
|
|
@app_commands.command(name="opt-out", description="Opt-out of data storage and stop using the bot.")
|
|
async def opt_out(self, interaction: discord.Interaction):
|
|
await revoke_user_consent(interaction.user.id)
|
|
await interaction.response.send_message("You have opted out of data storage. You will no longer be able to use the bot.", ephemeral=True)
|
|
|
|
class DollyTracker(app_commands.Group, name="dolly", description="Dolly the Project Tracker."):
|
|
def __init__(self):
|
|
super().__init__()
|
|
self.add_command(ProjectCommands())
|
|
self.add_command(TaskCommands())
|
|
self.add_command(ConsentCommands()) |