diff --git a/mo/web/org_contest.py b/mo/web/org_contest.py index c82f585b8e1e13d2d85a898fba45218476f2c3ed..508c63d5d3887a5af352613514d3cebf62831e94 100644 --- a/mo/web/org_contest.py +++ b/mo/web/org_contest.py @@ -16,7 +16,7 @@ import mo.imports import mo.rights import mo.util from mo.web import app -from mo.web.table import Table, Column, cell_place_link, cell_user_link +from mo.web.table import Table, Column, cell_place_link, cell_user_link, cell_email_link import wtforms.validators as validators @@ -255,20 +255,22 @@ def make_contestant_table(round: db.Round, contest: Optional[db.Contest]) -> Tab rows: List[dict] = [] for pion, pant, ct in ctants: + u = pion.user rows.append({ - 'first_name': pion.user.first_name, - 'last_name': pion.user.last_name, - 'email': cell_user_link(pion.user, pion.user.email), + 'sort_key': (locale.strxfrm(u.last_name), locale.strxfrm(u.first_name), u.user_id), + 'first_name': cell_user_link(u, u.first_name), + 'last_name': cell_user_link(u, u.last_name), + 'email': cell_email_link(u), 'school': pant.school_place.name, '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(), + 'region_code': cell_place_link(ct.place, ct.place.get_code()), + 'place_code': cell_place_link(pion.place, pion.place.get_code()), 'status': pion.state.name, }) - rows.sort(key=lambda r: (locale.strxfrm(r['last_name']), locale.strxfrm(r['first_name']))) + rows.sort(key=lambda r: r['sort_key']) cols: Sequence[Column] = contest_list_columns if not contest: diff --git a/mo/web/table.py b/mo/web/table.py index c1e6a8f8053e967218b3d117813521ea1530d8a4..4121226a843470cb037c850efe093c68accbe6b7 100644 --- a/mo/web/table.py +++ b/mo/web/table.py @@ -5,6 +5,7 @@ from html import escape import io from markupsafe import Markup from typing import Sequence, Optional, Iterable +import urllib.parse import werkzeug.exceptions import mo.csv @@ -40,13 +41,18 @@ class Cell: class CellLink(Cell): url: str + hint: Optional[str] - def __init__(self, text: str, url: str): + def __init__(self, text: str, url: str, hint: Optional[str] = None): Cell.__init__(self, text) self.url = url + self.hint = hint def to_html(self) -> str: - return '<a href="' + escape(self.url) + '">' + escape(self.text) + '</a>' + a = '<a href="' + escape(self.url) + '"' + if self.hint: + a += ' title="' + escape(self.hint) + '"' + return a + '>' + escape(self.text) + '</a>' class Table: @@ -138,9 +144,13 @@ class Table: # Pomocné funkce na generování různých typů odkazů +def cell_email_link(user: db.User) -> CellLink: + return CellLink(user.email, 'mailto:' + urllib.parse.quote(user.email, safe='@')) + + def cell_user_link(user: db.User, text: str) -> CellLink: - return CellLink(text, '/FIXME') + return CellLink(text, url_for('org_user', id=user.user_id)) def cell_place_link(place: db.Place, text: str) -> CellLink: - return CellLink(text, url_for('org_place', id=place.place_id)) + return CellLink(text, url_for('org_place', id=place.place_id), hint=place.name)