update endpoint of downloading examination schedule in pdf format for coordinator view and fix font issues for polish characters
This commit is contained in:
parent
2e3a7b24f0
commit
8dcb7528f9
@ -1,12 +1,12 @@
|
|||||||
import datetime
|
import datetime
|
||||||
|
|
||||||
from apiflask import APIBlueprint
|
from apiflask import APIBlueprint
|
||||||
from flask import abort, Response, make_response
|
from flask import abort, Response, make_response, current_app
|
||||||
|
|
||||||
from ...base.utils import paginate_models
|
from ...base.utils import paginate_models
|
||||||
from ...base.mode import ModeGroups
|
from ...base.mode import ModeGroups
|
||||||
from ...dependencies import db
|
from ...dependencies import db
|
||||||
from ...examination_schedule.models import ExaminationSchedule
|
from ...examination_schedule.models import ExaminationSchedule, TermOfDefence
|
||||||
from ...students.models import Group, YearGroup
|
from ...students.models import Group, YearGroup
|
||||||
from ...project_supervisor.models import ProjectSupervisor
|
from ...project_supervisor.models import ProjectSupervisor
|
||||||
from ..schemas import ExaminationScheduleSchema, ExaminationScheduleUpdateSchema, MessageSchema, \
|
from ..schemas import ExaminationScheduleSchema, ExaminationScheduleUpdateSchema, MessageSchema, \
|
||||||
@ -104,19 +104,22 @@ def download_examination_schedule(examination_schedule_id: int) -> Response:
|
|||||||
if examination_schedule is None:
|
if examination_schedule is None:
|
||||||
abort(404, "Examination schedule doesn't exist!")
|
abort(404, "Examination schedule doesn't exist!")
|
||||||
|
|
||||||
distinct_dates = db.session.query(db.func.Date(Enrollment.start_date)).distinct().all()
|
distinct_dates = db.session.query(db.func.Date(TermOfDefence.start_date)).distinct().all()
|
||||||
# print(distinct_dates)
|
|
||||||
nested_enrollments = []
|
nested_term_of_defences = []
|
||||||
for d in distinct_dates:
|
for d in distinct_dates:
|
||||||
date_tmp = datetime.datetime.strptime(d[0], "%Y-%m-%d").date()
|
date_tmp = datetime.datetime.strptime(d[0], "%Y-%m-%d").date()
|
||||||
enrollment = db.session.query(Enrollment).join(ExaminationSchedule, isouter=True). \
|
term_of_defences = db.session.query(TermOfDefence). \
|
||||||
join(Group, isouter=True).join(ProjectSupervisor, isouter=True). \
|
join(Group, isouter=True).join(ProjectSupervisor, isouter=True). \
|
||||||
filter(ExaminationSchedule.id == examination_schedule_id).filter(
|
filter(TermOfDefence.examination_schedule_id == examination_schedule_id). \
|
||||||
db.func.Date(Enrollment.start_date) == date_tmp).all()
|
filter(TermOfDefence.group_id.isnot(None)). \
|
||||||
nested_enrollments.append(enrollment)
|
filter(db.func.Date(TermOfDefence.start_date) == date_tmp). \
|
||||||
|
all()
|
||||||
# print(nested_enrollments)
|
if len(term_of_defences) > 0:
|
||||||
pdf = generate_examination_schedule_pdf_file(examination_schedule.title, nested_enrollments)
|
nested_term_of_defences.append(term_of_defences)
|
||||||
|
# print(nested_term_of_defences)
|
||||||
|
base_dir = current_app.config.get('BASE_DIR')
|
||||||
|
pdf = generate_examination_schedule_pdf_file(examination_schedule.title, nested_term_of_defences, base_dir)
|
||||||
title = examination_schedule.title.replace("-", "_").split()
|
title = examination_schedule.title.replace("-", "_").split()
|
||||||
filename = "_".join(title)
|
filename = "_".join(title)
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
import copy
|
import copy
|
||||||
from datetime import datetime, timedelta
|
|
||||||
from collections import defaultdict
|
from collections import defaultdict
|
||||||
|
from datetime import datetime, timedelta
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
from itertools import chain
|
|
||||||
from typing import Generator, Union, Any, List, Tuple
|
from typing import Generator, Union, Any, List, Tuple
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
from reportlab.lib import colors
|
from reportlab.lib import colors
|
||||||
@ -11,10 +11,13 @@ from reportlab.lib.enums import TA_CENTER
|
|||||||
from reportlab.lib.styles import getSampleStyleSheet
|
from reportlab.lib.styles import getSampleStyleSheet
|
||||||
from reportlab.lib.units import mm, inch
|
from reportlab.lib.units import mm, inch
|
||||||
from reportlab.platypus import SimpleDocTemplate, Paragraph, PageBreak, Table
|
from reportlab.platypus import SimpleDocTemplate, Paragraph, PageBreak, Table
|
||||||
|
from reportlab.pdfbase import pdfmetrics
|
||||||
|
from reportlab.pdfbase.ttfonts import TTFont
|
||||||
from werkzeug.datastructures import FileStorage
|
from werkzeug.datastructures import FileStorage
|
||||||
|
|
||||||
from .exceptions import InvalidNameOrTypeHeaderException
|
from .exceptions import InvalidNameOrTypeHeaderException
|
||||||
from ..students.models import Student, Group
|
from ..students.models import Student, Group
|
||||||
|
from ..examination_schedule.models import TermOfDefence
|
||||||
|
|
||||||
|
|
||||||
def check_columns(df: pd.DataFrame) -> bool:
|
def check_columns(df: pd.DataFrame) -> bool:
|
||||||
@ -78,7 +81,8 @@ def generate_range_dates(start_date: datetime, end_date: datetime, step_in_minut
|
|||||||
current_date = copy.copy(next_date)
|
current_date = copy.copy(next_date)
|
||||||
|
|
||||||
|
|
||||||
def generate_examination_schedule_pdf_file(title: str, nested_enrollments: List[List[object]]) -> bytes:
|
def generate_examination_schedule_pdf_file(title: str, nested_term_of_defences: List[List[TermOfDefence]],
|
||||||
|
base_dir: Path) -> bytes:
|
||||||
pagesize = (297 * mm, 210 * mm)
|
pagesize = (297 * mm, 210 * mm)
|
||||||
headers = ["lp.", "Godzina", "Nazwa projektu", "Opiekun", "Zespol", "Komisja"]
|
headers = ["lp.", "Godzina", "Nazwa projektu", "Opiekun", "Zespol", "Komisja"]
|
||||||
pdf_buffer = BytesIO()
|
pdf_buffer = BytesIO()
|
||||||
@ -92,44 +96,42 @@ def generate_examination_schedule_pdf_file(title: str, nested_enrollments: List[
|
|||||||
title=title
|
title=title
|
||||||
)
|
)
|
||||||
|
|
||||||
|
pdfmetrics.registerFont(TTFont('Lato', base_dir / 'fonts' / 'Lato.ttf'))
|
||||||
style = getSampleStyleSheet()
|
style = getSampleStyleSheet()
|
||||||
bodyText = style['BodyText']
|
bodyText = style['BodyText']
|
||||||
bodyText.fontName = 'Helvetica'
|
bodyText.fontName = 'Lato'
|
||||||
normal = style["Heading1"]
|
normal = style["Heading1"]
|
||||||
normal.alignment = TA_CENTER
|
normal.alignment = TA_CENTER
|
||||||
flowables = []
|
flowables = []
|
||||||
|
|
||||||
# print(nested_enrollments)
|
# print(nested_enrollments)
|
||||||
for enrollments in nested_enrollments:
|
for term_of_defences in nested_term_of_defences:
|
||||||
if len(enrollments) == 0:
|
if len(term_of_defences) == 0:
|
||||||
continue
|
continue
|
||||||
date = datetime.datetime.strftime(enrollments[0].start_date, '%d/%m/%Y')
|
date = datetime.strftime(term_of_defences[0].start_date.date(), '%d.%m.%Y')
|
||||||
paragraph_1 = Paragraph(f"{title} ~ {date}", normal)
|
paragraph_1 = Paragraph(f"{title} ~ {date}", normal)
|
||||||
flowables.append(paragraph_1)
|
flowables.append(paragraph_1)
|
||||||
data = [headers]
|
data = [headers]
|
||||||
|
|
||||||
for idx, e in enumerate(enrollments, start=1):
|
for idx, td in enumerate(term_of_defences, start=1):
|
||||||
new_date = e.start_date + datetime.timedelta(hours=2)
|
new_date = td.start_date + timedelta(hours=2)
|
||||||
group_name = e.group.name if e.group is not None else ""
|
group_name = td.group.name if td.group is not None else ""
|
||||||
if group_name != '':
|
if group_name != '':
|
||||||
ps = e.group.project_supervisor
|
ps = td.group.project_supervisor
|
||||||
project_supervisor_fullname = f"{ps.first_name[0]}. {ps.last_name}"
|
project_supervisor_fullname = f"{ps.first_name[0]}. {ps.last_name}"
|
||||||
students = e.group.students
|
students = td.group.students
|
||||||
# print(students)
|
# print(students)
|
||||||
team = ", ".join([f"{s.first_name} {s.last_name}" for s in students])
|
team = ", ".join([f"{s.first_name} {s.last_name}" for s in students])
|
||||||
else:
|
else:
|
||||||
project_supervisor_fullname = ""
|
project_supervisor_fullname = ""
|
||||||
team = ""
|
team = ""
|
||||||
|
|
||||||
members = e.committee.members
|
members = td.members_of_committee
|
||||||
# print(members)
|
# print(members)
|
||||||
if len(members) == 0:
|
if len(members) == 0:
|
||||||
committee = ''
|
committee = ''
|
||||||
else:
|
else:
|
||||||
members_iter = (f"{m.first_name[0]} {m.last_name}" for m in members)
|
members_iter = (f"{m.first_name[0]} {m.last_name}" for m in members)
|
||||||
if project_supervisor_fullname != '':
|
|
||||||
members_iter = chain(members_iter, [project_supervisor_fullname])
|
|
||||||
|
|
||||||
committee = ", ".join(members_iter)
|
committee = ", ".join(members_iter)
|
||||||
|
|
||||||
data.append([str(idx), new_date.strftime("%H:%M"),
|
data.append([str(idx), new_date.strftime("%H:%M"),
|
||||||
|
BIN
backend/fonts/Lato.ttf
Normal file
BIN
backend/fonts/Lato.ttf
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user