Spaces:
Sleeping
Sleeping
File size: 7,399 Bytes
b93a6a5 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 | """
Task service for business logic related to task operations.
This module provides:
- Get user tasks with filtering
- Create new tasks
- Update existing tasks
- Delete tasks
- User isolation enforcement
"""
from typing import List, Optional
from sqlmodel import Session, select
from ..models.task import Task
def get_user_tasks(session: Session, user_id: int) -> List[Task]:
"""
Get all tasks for a specific user.
Args:
session: Database session
user_id: ID of the user whose tasks to retrieve
Returns:
List of Task objects belonging to the user, ordered by creation date (newest first)
Example:
>>> tasks = get_user_tasks(session, user_id=1)
>>> print(len(tasks))
5
"""
statement = select(Task).where(Task.user_id == user_id).order_by(Task.created_at.desc())
tasks = session.exec(statement).all()
return list(tasks)
def get_task_by_id(session: Session, task_id: int, user_id: int) -> Optional[Task]:
"""
Get a specific task by ID, ensuring it belongs to the user.
Args:
session: Database session
task_id: ID of the task to retrieve
user_id: ID of the user (for ownership verification)
Returns:
Task object if found and belongs to user, None otherwise
Example:
>>> task = get_task_by_id(session, task_id=1, user_id=1)
>>> if task:
... print(task.title)
"""
statement = select(Task).where(Task.id == task_id, Task.user_id == user_id)
task = session.exec(statement).first()
return task
def create_task(
session: Session,
user_id: int,
title: str,
description: Optional[str] = None,
category: Optional[str] = None,
due_date: Optional[str] = None,
priority: Optional[str] = "medium",
is_recurring: bool = False,
recurrence_type: Optional[str] = None,
recurrence_interval: Optional[int] = 1,
recurrence_end_date: Optional[str] = None
) -> Task:
"""
Create a new task for a user.
Args:
session: Database session
user_id: ID of the user creating the task
title: Task title
description: Optional task description
category: Optional task category/tag
due_date: Optional due date in ISO format
priority: Task priority (low, medium, high)
is_recurring: Whether task is recurring
recurrence_type: Type of recurrence (daily, weekly, monthly, yearly)
recurrence_interval: Interval for recurrence (e.g., every 2 days)
recurrence_end_date: End date for recurrence in ISO format
Returns:
Created Task object
Example:
>>> task = create_task(session, user_id=1, title="Buy groceries", description="Milk, eggs, bread", category="Personal")
>>> print(task.id)
1
"""
from datetime import datetime
# Parse due_date if provided
due_date_obj = None
if due_date:
try:
due_date_obj = datetime.fromisoformat(due_date.replace('Z', '+00:00'))
except (ValueError, AttributeError):
pass
# Parse recurrence_end_date if provided
recurrence_end_date_obj = None
if recurrence_end_date:
try:
recurrence_end_date_obj = datetime.fromisoformat(recurrence_end_date.replace('Z', '+00:00'))
except (ValueError, AttributeError):
pass
new_task = Task(
user_id=user_id,
title=title,
description=description,
completed=False,
category=category,
due_date=due_date_obj,
priority=priority or "medium",
is_recurring=is_recurring,
recurrence_type=recurrence_type if is_recurring else None,
recurrence_interval=recurrence_interval if is_recurring else None,
recurrence_end_date=recurrence_end_date_obj if is_recurring else None
)
session.add(new_task)
session.commit()
session.refresh(new_task)
return new_task
def update_task(
session: Session,
task_id: int,
user_id: int,
title: Optional[str] = None,
description: Optional[str] = None,
completed: Optional[bool] = None,
category: Optional[str] = None,
due_date: Optional[str] = None,
priority: Optional[str] = None,
is_recurring: Optional[bool] = None,
recurrence_type: Optional[str] = None,
recurrence_interval: Optional[int] = None,
recurrence_end_date: Optional[str] = None
) -> Optional[Task]:
"""
Update an existing task.
Args:
session: Database session
task_id: ID of the task to update
user_id: ID of the user (for ownership verification)
title: New title (optional)
description: New description (optional)
completed: New completion status (optional)
category: New category/tag (optional)
due_date: New due date in ISO format (optional)
priority: New priority (optional)
is_recurring: Whether task is recurring (optional)
recurrence_type: Type of recurrence (optional)
recurrence_interval: Interval for recurrence (optional)
recurrence_end_date: End date for recurrence (optional)
Returns:
Updated Task object if found and belongs to user, None otherwise
Example:
>>> task = update_task(session, task_id=1, user_id=1, completed=True)
>>> if task:
... print(task.completed)
True
"""
from datetime import datetime
# Get task with ownership verification
task = get_task_by_id(session, task_id, user_id)
if not task:
return None
# Update fields if provided
if title is not None:
task.title = title
if description is not None:
task.description = description
if completed is not None:
task.completed = completed
if category is not None:
task.category = category
if due_date is not None:
try:
task.due_date = datetime.fromisoformat(due_date.replace('Z', '+00:00'))
except (ValueError, AttributeError):
pass
if priority is not None:
task.priority = priority
if is_recurring is not None:
task.is_recurring = is_recurring
if recurrence_type is not None:
task.recurrence_type = recurrence_type
if recurrence_interval is not None:
task.recurrence_interval = recurrence_interval
if recurrence_end_date is not None:
try:
task.recurrence_end_date = datetime.fromisoformat(recurrence_end_date.replace('Z', '+00:00'))
except (ValueError, AttributeError):
pass
task.updated_at = datetime.utcnow()
session.add(task)
session.commit()
session.refresh(task)
return task
def delete_task(session: Session, task_id: int, user_id: int) -> bool:
"""
Delete a task.
Args:
session: Database session
task_id: ID of the task to delete
user_id: ID of the user (for ownership verification)
Returns:
True if task was deleted, False if not found or doesn't belong to user
Example:
>>> success = delete_task(session, task_id=1, user_id=1)
>>> print(success)
True
"""
# Get task with ownership verification
task = get_task_by_id(session, task_id, user_id)
if not task:
return False
session.delete(task)
session.commit()
return True
|