Add helper functions for Project

This commit is contained in:
Backend IM Bot 2025-03-27 17:57:27 +00:00
parent 5b201e1370
commit 808de0bdd8

116
helpers/project_helpers.py Normal file
View File

@ -0,0 +1,116 @@
from typing import Dict, Optional, List, Union
from datetime import datetime
from sqlalchemy.orm import Session
import re
from models.project import Project
from schemas.project import ProjectCreate, ProjectUpdate
def validate_github_link(github_link: str) -> bool:
"""
Validate GitHub repository URL format.
Args:
github_link: GitHub URL to validate
Returns:
bool: True if URL format is valid, False otherwise
"""
pattern = r'^https?:\/\/github\.com\/[\w-]+\/[\w-]+(?:\.git)?$'
return bool(re.match(pattern, github_link))
def validate_project_data(project_data: ProjectCreate) -> Dict[str, str]:
"""
Validate project data before creation.
Args:
project_data: Project data to validate
Returns:
Dict containing validation errors if any
"""
errors = {}
if len(project_data.title) > 255:
errors["title"] = "Title must not exceed 255 characters"
if not project_data.description:
errors["description"] = "Description is required"
if project_data.year < 2000 or project_data.year > datetime.now().year:
errors["year"] = "Invalid year"
if project_data.github_link and not validate_github_link(project_data.github_link):
errors["github_link"] = "Invalid GitHub repository URL"
return errors
def get_projects_by_technology(db: Session, technology: str) -> List[Project]:
"""
Get all projects that use a specific technology.
Args:
db: Database session
technology: Technology to search for
Returns:
List of projects using the specified technology
"""
return db.query(Project).filter(Project.technologies_used.ilike(f'%{technology}%')).all()
def get_department_statistics(db: Session) -> Dict[str, Dict[str, Union[int, float]]]:
"""
Get project statistics by department.
Args:
db: Database session
Returns:
Dictionary containing department statistics
"""
departments = db.query(Project.department).distinct().all()
stats = {}
for dept in departments:
dept_name = dept[0]
dept_projects = db.query(Project).filter(Project.department == dept_name).all()
published_count = sum(1 for p in dept_projects if p.is_published)
avg_grade = sum(float(p.grade) for p in dept_projects if p.grade) / len(dept_projects) if dept_projects else 0
stats[dept_name] = {
"total_projects": len(dept_projects),
"published_projects": published_count,
"average_grade": round(avg_grade, 2)
}
return stats
def format_project_response(project: Project) -> Dict[str, Any]:
"""
Format project data for API response.
Args:
project: Project object to format
Returns:
Formatted project data dictionary
"""
technologies = project.technologies_used.split(',') if project.technologies_used else []
return {
"id": project.id,
"title": project.title,
"description": project.description,
"student_name": project.student_name,
"supervisor_name": project.supervisor_name,
"department": project.department,
"year": project.year,
"status": project.status,
"technologies": technologies,
"github_link": project.github_link,
"documentation_link": project.documentation_link,
"grade": project.grade,
"is_published": project.is_published,
"created_at": project.created_at.isoformat() if project.created_at else None,
"updated_at": project.updated_at.isoformat() if project.updated_at else None
}