diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py index 70ef811743d3cdc011b357c4aed2c3d2f89ea00c..c82f585b8e1e13d2d85a898fba45218476f2c3ed 100644 --- a/mo/web/org_contest.py +++ b/mo/web/org_contest.py @@ -5,7 +5,7 @@ import locale import os import secrets from sqlalchemy.orm import joinedload -from typing import List, Tuple, Optional +from typing import List, Tuple, Optional, Sequence import werkzeug.exceptions import wtforms @@ -75,7 +75,19 @@ def org_round(id: int): @app.route('/org/contest/r/<int:id>/list') def org_round_list(id: int): - return render_template('not_implemented.html') + round, rr = get_round_rr(id, mo.rights.Right.manage_contest) + format = request.args.get('format', "") + + table = make_contestant_table(round, None) + + if format == "": + return render_template( + 'org_round_list.html', + round=round, + table=table, + ) + else: + return table.send_as(format) @app.route('/org/contest/r/<int:id>/import', methods=('GET', 'POST')) @@ -193,6 +205,23 @@ def org_contest_import_template(): return resp +@app.route('/org/contest/c/<int:id>/ucastnici') +def org_contest_list(id: int): + contest, rr = get_contest_rr(id, mo.rights.Right.manage_contest) + format = request.args.get('format', "") + + table = make_contestant_table(contest.round, contest) + + if format == "": + return render_template( + 'org_contest_list.html', + contest=contest, + table=table, + ) + else: + return table.send_as(format) + + contest_list_columns = ( Column(key='first_name', name='krestni', title='Křestní jméno'), Column(key='last_name', name='prijmeni', title='Příjmení'), @@ -206,24 +235,26 @@ contest_list_columns = ( ) -@app.route('/org/contest/c/<int:id>/ucastnici') -def org_contest_list(id: int): - contest, rr = get_contest_rr(id, mo.rights.Right.manage_contest) - format = request.args.get('format', "") +def make_contestant_table(round: db.Round, contest: Optional[db.Contest]) -> Table: + query = (db.get_session() + .query(db.Participation, db.Participant, db.Contest) + .select_from(db.Participation) + .join(db.Participant, db.Participant.user_id == db.Participation.user_id) + .filter(db.Participant.year == round.year)) + if contest: + query = query.join(db.Contest, db.Contest.contest_id == contest.contest_id) + else: + query = query.filter(db.Contest.round == round) + query = query.options(joinedload(db.Contest.place)) + query = query.filter(db.Participation.contest_id == db.Contest.contest_id) + query = query.options(joinedload(db.Participation.user), + joinedload(db.Participation.place), + joinedload(db.Participant.school_place)) - ctants = (db.get_session() - .query(db.Participation, db.Participant) - .select_from(db.Participation) - .join(db.Participant, db.Participant.user_id == db.Participation.user_id) - .options(joinedload(db.Participation.user), - joinedload(db.Participation.place), - joinedload(db.Participant.school_place)) - .filter(db.Participation.contest == contest) - .filter(db.Participant.year == contest.round.year) - .all()) + ctants = query.all() rows: List[dict] = [] - for pion, pant in ctants: + for pion, pant, ct in ctants: rows.append({ 'first_name': pion.user.first_name, 'last_name': pion.user.last_name, @@ -232,23 +263,19 @@ def org_contest_list(id: int): 'school_code': cell_place_link(pant.school_place, pant.school_place.get_code()), 'grade': pant.grade, 'born_year': pant.birth_year, + 'region_code': ct.place.get_code(), 'place_code': pion.place.get_code(), 'status': pion.state.name, }) rows.sort(key=lambda r: (locale.strxfrm(r['last_name']), locale.strxfrm(r['first_name']))) - table = Table( - columns=contest_list_columns, + cols: Sequence[Column] = contest_list_columns + if not contest: + cols = list(cols) + [Column(key='region_code', name='kod_oblasti', title='Oblast')] + + return Table( + columns=cols, rows=rows, filename='ucastnici', ) - - if format == "": - return render_template( - 'org_contest_list.html', - contest=contest, - table=table, - ) - else: - return table.send_as(format)