Add helper functions for Project
This commit is contained in:
parent
5b201e1370
commit
808de0bdd8
116
helpers/project_helpers.py
Normal file
116
helpers/project_helpers.py
Normal 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
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user