98 lines
3.8 KiB
Python
98 lines
3.8 KiB
Python
import json
|
|
import os
|
|
from typing import List, Optional
|
|
|
|
from modules.projects.project import Project
|
|
|
|
|
|
class ProjectHandler:
|
|
def __init__(self, base_dir: str = None):
|
|
# Par défaut, stocker sous Data/projects
|
|
self.base_dir = base_dir or os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), 'Data', 'projects')
|
|
os.makedirs(self.base_dir, exist_ok=True)
|
|
|
|
def _client_dir(self, client_id: str) -> str:
|
|
path = os.path.join(self.base_dir, client_id)
|
|
os.makedirs(path, exist_ok=True)
|
|
return path
|
|
|
|
def _project_path(self, client_id: str, project_id: str) -> str:
|
|
return os.path.join(self._client_dir(client_id), f"{project_id}.json")
|
|
|
|
def list_projects(self, client_id: str) -> List[Project]:
|
|
projects: List[Project] = []
|
|
directory = self._client_dir(client_id)
|
|
if not os.path.isdir(directory):
|
|
return projects
|
|
for filename in os.listdir(directory):
|
|
if filename.endswith('.json'):
|
|
try:
|
|
with open(os.path.join(directory, filename), 'r', encoding='utf-8') as f:
|
|
data = json.load(f)
|
|
projects.append(Project.from_dict(data))
|
|
except Exception:
|
|
# Ignorer fichiers corrompus
|
|
continue
|
|
# Tri par date de mise à jour décroissante
|
|
projects.sort(key=lambda p: p.updated_at or "", reverse=True)
|
|
return projects
|
|
|
|
def get_project(self, client_id: str, project_id: str) -> Optional[Project]:
|
|
path = self._project_path(client_id, project_id)
|
|
if not os.path.exists(path):
|
|
return None
|
|
with open(path, 'r', encoding='utf-8') as f:
|
|
data = json.load(f)
|
|
return Project.from_dict(data)
|
|
|
|
def add_project(self, project: Project) -> str:
|
|
path = self._project_path(project.client_id, project.id)
|
|
with open(path, 'w', encoding='utf-8') as f:
|
|
json.dump(project.to_dict(), f, ensure_ascii=False, indent=2)
|
|
return project.id
|
|
|
|
def update_project(self, project: Project) -> bool:
|
|
path = self._project_path(project.client_id, project.id)
|
|
if not os.path.exists(path):
|
|
return False
|
|
# mettre à jour updated_at
|
|
from datetime import datetime
|
|
project.updated_at = datetime.utcnow().isoformat()
|
|
with open(path, 'w', encoding='utf-8') as f:
|
|
json.dump(project.to_dict(), f, ensure_ascii=False, indent=2)
|
|
return True
|
|
|
|
def delete_project(self, client_id: str, project_id: str) -> bool:
|
|
path = self._project_path(client_id, project_id)
|
|
if os.path.exists(path):
|
|
try:
|
|
os.remove(path)
|
|
return True
|
|
except Exception:
|
|
return False
|
|
return False
|
|
|
|
def add_task_for_project(self, project_id: str, title: str, due_date: str, description: str = "", priority: str = "normale", metadata: dict = None):
|
|
"""
|
|
Crée une tâche liée à un projet.
|
|
:param project_id: ID du projet
|
|
:param title: Titre de la tâche
|
|
:param due_date: Date d'échéance au format ISO (YYYY-MM-DD)
|
|
:param description: Description optionnelle
|
|
:param priority: 'basse' | 'normale' | 'haute'
|
|
:param metadata: métadonnées optionnelles
|
|
:return: ID de la tâche créée
|
|
"""
|
|
from modules.tasks.task import Task
|
|
from modules.tasks.task_handler import TaskHandler
|
|
|
|
task = Task(
|
|
title=title,
|
|
due_date=due_date,
|
|
description=description,
|
|
entity_type="project",
|
|
entity_id=project_id,
|
|
priority=priority,
|
|
metadata=metadata or {},
|
|
)
|
|
return TaskHandler().add_task(task)
|