diff --git a/dolly/commands.py b/dolly/commands.py index 20bcf2c..501a08e 100644 --- a/dolly/commands.py +++ b/dolly/commands.py @@ -1,6 +1,10 @@ import discord from discord import app_commands -from .database import add_project, add_task +from .database import add_project, get_project_id, add_task_to_project +from datetime import datetime +import logging + +logger = logging.getLogger('Dolly') class ProjectCommands(app_commands.Group): def __init__(self): @@ -8,8 +12,12 @@ class ProjectCommands(app_commands.Group): @app_commands.command(name="create", description="Create a new project.") async def create_project(self, interaction: discord.Interaction, name: str, description: str): - await add_project(name, description) - await interaction.response.send_message(f"Project '{name}' created successfully.") + 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}") class TaskCommands(app_commands.Group): def __init__(self): @@ -17,12 +25,25 @@ class TaskCommands(app_commands.Group): @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): - await add_task(project_name, description, assignee, deadline, status, priority) - await interaction.response.send_message(f"Task '{description}' added to project '{project_name}'.") + 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}") 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(TaskCommands()) \ No newline at end of file diff --git a/dolly/database.py b/dolly/database.py index 605f6e8..10dbb24 100644 --- a/dolly/database.py +++ b/dolly/database.py @@ -7,13 +7,13 @@ async def init_db(): async with aiosqlite.connect(DATABASE) as db: await db.execute( '''CREATE TABLE IF NOT EXISTS projects( - id INTEGER PRIMARY KEY, + id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT UNIQUE, description TEXT)''' ) await db.execute( '''CREATE TABLE IF NOT EXISTS tasks( - id INTEGER PRIMARY KEY, + id INTEGER PRIMARY KEY AUTOINCREMENT, project_id INTEGER, description TEXT, assignee TEXT, @@ -26,11 +26,28 @@ async def init_db(): async def add_project(name, description): async with aiosqlite.connect(DATABASE) as db: - await db.execute("INSERT INTO projects(name, description) VALUES(?, ?)", (name, description)) + cursor = await db.execute("INSERT INTO projects(name, description) VALUES(?, ?)", (name, description)) + await db.commit() + return cursor.lastrowid # Returns the ID of the newly created project + +async def get_project_id(name): + async with aiosqlite.connect(DATABASE) as db: + cursor = await db.execute("SELECT id FROM projects WHERE name = ?", (name,)) + result = await cursor.fetchone() + return result[0] if result else None + +async def add_task_to_project(project_id, description, assignee, deadline, status, priority): + async with aiosqlite.connect(DATABASE) as db: + # Change the date format to MM/DD/YYYY + deadline_date = datetime.strptime(deadline, "%m/%d/%Y").date() + await db.execute("INSERT INTO tasks(project_id, description, assignee, deadline, status, priority) VALUES(?, ?, ?, ?, ?, ?)", + (project_id, description, assignee, deadline_date, status, priority)) await db.commit() -async def add_task(project_id, description, assignee, deadline, status, priority): +async def update_task(task_id, description, assignee, deadline, status, priority): async with aiosqlite.connect(DATABASE) as db: - deadline_date = datetime.strptime(deadline, "%Y-%m-%d").date() - await db.execute("INSERT INTO tasks(project_id, description, assignee, deadline, status, priority) VALUES(?, ?, ?, ?, ?, ?)", (project_id, description, assignee, deadline_date, status, priority)) + # Change the date format to MM/DD/YYYY + deadline_date = datetime.strptime(deadline, "%m/%d/%Y").date() + await db.execute("UPDATE tasks SET description=?, assignee=?, deadline=?, status=?, priority=? WHERE id=?", + (description, assignee, deadline_date, status, priority, task_id)) await db.commit() \ No newline at end of file diff --git a/dolly/logger.py b/dolly/logger.py new file mode 100644 index 0000000..5b4dd2b --- /dev/null +++ b/dolly/logger.py @@ -0,0 +1,17 @@ +import logging +from logging.handlers import RotatingFileHandler + +# Configure basic logger +logging.basicConfig(level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s', + datefmt='%Y-%m-%d %H:%M:%S') + +# Create a rotating file handler which logs even debug messages +log_file = 'dolly.log' +handler = RotatingFileHandler(log_file, maxBytes=100000, backupCount=3) +formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s') +handler.setFormatter(formatter) + +logger = logging.getLogger('Dolly') +logger.addHandler(handler) +logger.setLevel(logging.INFO) \ No newline at end of file