Skip to content

Commit

Permalink
Merge branch 'master' into bahar
Browse files Browse the repository at this point in the history
  • Loading branch information
Bahar-bn committed Jul 4, 2024
2 parents de53f09 + 8139668 commit 16e3112
Show file tree
Hide file tree
Showing 33 changed files with 1,986 additions and 123 deletions.
5 changes: 5 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ RUN apt-get update && \
apt-get install -y --no-install-recommends fonts-dejavu gcc libc-dev git gpg libmagic1 libpq-dev postgresql-client xz-utils && \
pip install -U pip setuptools --no-cache-dir && \
rm -rf /root/.cache /var/cache/*

# Check and downgrade pip if necessary
RUN pip --version && \
pip install --upgrade "pip<24.1" && \
pip --version

# install python requirements and do cleanup
COPY requirements.txt requirements.txt
Expand Down
21 changes: 19 additions & 2 deletions src/spz/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ class CustomFlask(Flask):
"""
jinja_options = dict(Flask.jinja_options, trim_blocks=True, lstrip_blocks=True, auto_reload=False)


app = CustomFlask(__name__, instance_relative_config=True)

# Configuration loading
Expand Down Expand Up @@ -84,6 +83,7 @@ def rlrc_comment():
# add Jinja helpers
app.jinja_env.globals['include_raw'] = lambda filename: Markup(app.jinja_loader.get_source(app.jinja_env, filename)[0])
app.jinja_env.globals['rlrc_comment'] = rlrc_comment
app.jinja_env.globals.update(zip=zip)

# Assets handling; keep the spz.assets module in sync with the static directory
assets_env = Environment(app)
Expand Down Expand Up @@ -129,9 +129,9 @@ def rlrc_comment():
# Rich Text Editor setup
ckeditor = CKEditor(app)


# Register all views here
from spz import views, errorhandlers, pdf # NOQA
from spz.administration import admin_views

routes = [
('/', views.index, ['GET', 'POST']),
Expand Down Expand Up @@ -191,6 +191,23 @@ def rlrc_comment():
('/internal/login', views.login, ['GET', 'POST']),
('/internal/logout', views.logout, ['GET', 'POST']),
('/internal/auth/reset_password/<string:reset_token>', views.reset_password, ['GET', 'POST']),

('/internal/administration/teacher', admin_views.administration_teacher, ['GET', 'POST']),
('/internal/administration/teacher/<int:id>', admin_views.administration_teacher_lang, ['GET', 'POST']),
('/internal/administration/teacher/<int:id>/add', admin_views.add_teacher, ['GET', 'POST']),
('/internal/administration/teacher/edit/<int:id>', admin_views.edit_teacher, ['GET', 'POST']),
('/internal/administration/teacher/void', admin_views.teacher_void, ['GET']),
('/internal/teacher', admin_views.teacher, ['GET', 'POST']),
('/internal/grades/<int:course_id>', admin_views.grade, ['GET', 'POST']),
('/internal/grades/<int:course_id>/edit', admin_views.edit_grade, ['GET', 'POST']),
('/internal/grades/<int:course_id>/edit_view', admin_views.edit_grade_view, ['GET', 'POST']),
('/internal/teacher/<int:id>/attendance/<int:course_id>', admin_views.attendances, ['GET', 'POST']),
('/internal/teacher/<int:id>/attendance/<int:course_id>/edit/<int:class_id>', admin_views.edit_attendances, ['GET', 'POST']),

('/api/campus_portal/export/<string:export_token>', views.campus_portal_grades, ['GET']),
('/internal/campus_portal/export', views.campus_export_language, ['GET', 'POST']),
('/internal/campus_portal/export/<int:id>', views.campus_export_course, ['GET', 'POST']),

]

for rule, view_func, methods in routes:
Expand Down
77 changes: 77 additions & 0 deletions src/spz/administration/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# -*- coding: utf-8 -*-
"""static functions related to administration tasks
This module contains methods for:
- teacher management
- course management
"""

from flask import flash
from spz import models, db
from spz.mail import generate_status_mail

from flask_babel import gettext as _


def get_course_ids():
course_ids_tuple = db.session.query(models.Role.course_id).filter(
models.Role.course_id.isnot(None)) \
.filter(models.Role.role == models.Role.COURSE_TEACHER) \
.distinct().all()
# transform query tuples into right integer format
"""flash('Vergebene Kurse sind:')
for course_id in course_ids_tuple:
course = models.Course.query.get(course_id[0])
flash(f'{course.full_name}: {course_id[0]}')"""
return [course_id[0] for course_id in course_ids_tuple]


class TeacherManagement:
@staticmethod
def remove_course(teacher, course, user_id):
role_to_remove = models.Role.query. \
join(models.User.roles). \
filter(models.Role.user_id == user_id). \
filter(models.Role.course_id == course.id). \
first()
if role_to_remove:
# remove complete table row from role table
db.session.delete(role_to_remove)
else:
raise ValueError(_('Folgender Kurs "{}" war kein Kurs des/der Lehrbeauftragten.'
' Wurde der richtige Kurs ausgewählt?'.format(course.full_name)))

return course

@staticmethod
def add_course(teacher, course):
own_courses_id = [course.id for course in teacher.teacher_courses]
if course.id in own_courses_id:
raise ValueError(
_('Der/die Lehrbeauftragte hat diesen Kurs schon zugewiesen. Doppelzuweisung nicht möglich!'))
TeacherManagement.check_availability(course)
teacher.roles.append(models.Role(course=course, role=models.Role.COURSE_TEACHER))

@staticmethod
def check_availability(course):
teachers = db.session.query(models.User) \
.join(models.Role, models.User.roles) \
.filter(models.Role.role == models.Role.COURSE_TEACHER).all()
course_ids = get_course_ids()
if course.id in course_ids:
for teacher in teachers:
if teacher.is_course_teacher(course):
#flash(f'{course.full_name} ({course.id}) is already assigned to {teacher.full_name}')
raise ValueError('{0} ist schon vergeben an {1}.'.format(course.full_name, teacher.full_name))

@staticmethod
def unassigned_courses(language_id):
# courses with assigned teachers only
unassigned_courses = db.session.query(models.Course) \
.outerjoin(models.Role,
(models.Role.course_id == models.Course.id) & (models.Role.role == models.Role.COURSE_TEACHER)) \
.join(models.Language) \
.filter(models.Language.id == language_id) \
.filter(models.Role.id == None)

return unassigned_courses
Loading

0 comments on commit 16e3112

Please sign in to comment.