diff --git a/backend/app/coordinator/routes/students.py b/backend/app/coordinator/routes/students.py index 92f0e23..74c19fc 100644 --- a/backend/app/coordinator/routes/students.py +++ b/backend/app/coordinator/routes/students.py @@ -1,16 +1,18 @@ from random import randint from itertools import islice +from typing import List -from flask import abort +from flask import Response, abort from apiflask import APIBlueprint from sqlalchemy.exc import IntegrityError from flask_sqlalchemy import get_debug_queries -from ...students.models import Student +from ...students.models import Student, Group +from ...project_supervisor.models import ProjectSupervisor from ..schemas import StudentSchema, StudentEditSchema, StudentsPaginationSchema, \ StudentCreateSchema, MessageSchema, FileSchema, StudentQuerySchema from ...dependencies import db -from ..utils import parse_csv +from ..utils import parse_csv, generate_csv from ..exceptions import InvalidNameOrTypeHeaderException from ...base.utils import paginate_models, is_allowed_extensions @@ -123,3 +125,14 @@ def upload_students(file: dict) -> dict: abort(400, "Invalid extension of file") return {"message": "Students was created by uploading csv file!"} + + +@bp.route("/download/", methods=["POST"]) +def download_students() -> Response: + students = db.session.query(Student).join(Group).join(ProjectSupervisor).all() + if len(students) == 0: + abort(404, "Not found students, which are assigned to group!") + csv_file = generate_csv(students) + response = Response(csv_file, mimetype='text/csv') + response.headers.set("Content-Disposition", "attachment", filename="students_list.csv") + return response diff --git a/backend/app/coordinator/utils.py b/backend/app/coordinator/utils.py index 2496cdd..86ced4a 100644 --- a/backend/app/coordinator/utils.py +++ b/backend/app/coordinator/utils.py @@ -1,5 +1,5 @@ -from typing import Generator, Any -from random import randint +from typing import Generator, Any, List +from collections import defaultdict import pandas as pd @@ -28,15 +28,30 @@ def check_columns(df: pd.DataFrame) -> bool: def parse_csv(file, mode) -> Generator[Student, Any, None]: df = pd.read_csv(file) - # if not check_columns(df): - # raise InvalidNameOrTypeHeaderException + if not check_columns(df): + raise InvalidNameOrTypeHeaderException students = (Student(last_name=dict(item.items())['NAZWISKO'], first_name=dict(item.items())['IMIE'], index=dict(item.items())['INDEKS'], - pesel=str(int(dict(item.items())['PESEL'])) if not pd.isna(dict(item.items())['PESEL']) else None, + pesel=str(int(dict(item.items())['PESEL'])) if not pd.isna( + dict(item.items())['PESEL']) else None, email=dict(item.items())['EMAIL'], mode=mode) for _, item in df.iterrows()) return students + + +def generate_csv(students: List[Student]) -> str: + headers = ['PESEL', 'INDEKS', 'IMIE', 'NAZWISKO', 'EMAIL', 'CDYD_KOD', 'PRZ_KOD', 'TZAJ_KOD', 'GR_NR', 'PRG_KOD'] + data = [(student.pesel, student.index, student.first_name, student.last_name, student.email, + student.group.cdyd_kod, student.group.prz_kod, student.group.tzaj_kod, student.group.project_supervisor_id, + None) for student in students] + dataframe = defaultdict(list) + for row in data: + for idx, item in enumerate(row): + dataframe[headers[idx]].append(item) + + df = pd.DataFrame(dataframe) + return df.to_csv(index=False)