Skip to content
Snippets Groups Projects
Commit ec80534a authored by Martin Mareš's avatar Martin Mareš
Browse files

Orgovská homepage už ukazuje i soutěžní místa pro dozor a opravovatele

Změnil jsem uspořádání, protože různé kategorie mají různá kola
lišící se i úrovní míst.

Dozoru a opravovatelům schovávám soutěže ve stavech, kdy k nim
stejně nemají přístup.

Statistiky jsou u soutěžních mist zatím rozbité, ještě dořeším.
parent 5ad4c5fd
No related branches found
No related tags found
No related merge requests found
from dataclasses import dataclass, field
from flask import render_template, redirect, url_for, request, flash, g
from sqlalchemy import and_, or_, tuple_
from sqlalchemy import and_, or_, tuple_, not_
from sqlalchemy.orm import aliased, joinedload
from typing import List, Set, Optional, Dict, Tuple
......@@ -46,25 +46,49 @@ def org_index():
except ValueError:
flash('ID uživatele musí být číslo', 'danger')
# Soutěže, ke kterým máme nějakou roli
sess = db.get_session()
rcu = (sess.query(db.Round, db.Contest, db.UserRole)
rcu_base = (sess.query(db.Round, db.Contest, db.UserRole)
.select_from(db.UserRole)
.join(db.Place)
.options(joinedload(db.UserRole.place))
.join(db.Round, and_(db.UserRole.user_id == g.user.user_id,
or_(db.UserRole.category == None,
db.UserRole.category == db.Round.category,
and_(db.UserRole.category == 'Z', db.Round.category.like('Z%')),
and_(db.UserRole.category == 'S', db.Round.category.in_(('A', 'B', 'C')))),
or_(db.UserRole.year == None, db.UserRole.year == db.Round.year),
or_(db.UserRole.seq == None, db.UserRole.seq == db.Round.seq),
db.Place.level <= db.Round.level))
or_(db.UserRole.seq == None, db.UserRole.seq == db.Round.seq)))
.filter(db.Round.year == config.CURRENT_YEAR))
rcu = (rcu_base
.filter(db.Place.level <= db.Round.level)
.outerjoin(db.Contest, and_(db.Contest.round_id == db.Round.round_id, db.Contest.place_id == db.UserRole.place_id))
.filter(db.Round.year == config.CURRENT_YEAR)
.options(joinedload(db.UserRole.place))
.order_by(db.Round.level, db.Round.category, db.Round.seq, db.Round.part,
db.Contest.place_id, db.Contest.contest_id)
.all())
# Soutěžní místa, ke kterým máme roli dozoru nebo opravovatele
contest_place = aliased(db.Place)
place_rcu = (rcu_base
.filter(not_(db.Round.state.in_([db.RoundState.preparing, db.RoundState.closed]))) # for performance
.filter(db.Place.level == 4)
.filter(db.Place.level > db.Round.level)
.join(db.RegionDescendant, db.RegionDescendant.descendant == db.Place.place_id)
.join(contest_place, db.RegionDescendant.region == contest_place.place_id)
.filter(contest_place.level == db.Round.level)
.join(db.Contest, and_(db.Contest.round_id == db.Round.round_id, db.Contest.place_id == contest_place.place_id))
.filter(sess.query(db.Participation)
.filter(and_(db.Participation.contest_id == db.Contest.contest_id,
db.Participation.place_id == db.Place.place_id))
.exists())
.all())
def key_func(item: Tuple[db.Round, db.Contest, db.UserRole]):
r, ct, ur = item
return (r.category, r.seq, r.part, ur.place.level, ur.place_id, ct.contest_id if ct else -1)
rcu.extend(place_rcu)
rcu.sort(key=key_func)
overview: List[OrgOverview] = []
for r, ct, ur in rcu:
if ct is None and ur.place.level == r.level:
......@@ -79,6 +103,7 @@ def org_index():
o.role_list = sorted(o.role_set, key=lambda r: mo.rights.role_order_by_type[r])
get_stats(overview)
overview = filter_overview(overview)
return render_template('org_index.html', overview=overview, role_type_names=db.role_type_names)
......@@ -120,6 +145,28 @@ def get_stats(overview: List[OrgOverview]) -> None:
o.num_unconfirmed_pants += rps.count
def filter_overview(overview: List[OrgOverview]) -> List[OrgOverview]:
out = []
for o in overview:
want = False
if o.role_set <= {db.RoleType.dozor, db.RoleType.opravovatel}:
# Dozor vidí jen běžící soutěže, opravovatelé všechny aktivní
if db.RoleType.dozor in o.role_set:
if not (o.contest_states <= {db.RoundState.preparing, db.RoundState.closed}):
want = True
else:
if db.RoundState.running in o.contest_states:
want = True
else:
# Ostatní role (garanti a pozorovatelé) vidí všechny soutěže
want = True
if want:
out.append(o)
return out
school_export_columns = (
Column(key='code', name='kod'),
Column(key='name', name='nazev'),
......
......@@ -6,24 +6,28 @@
<h3>Moje soutěže</h3>
<table class="table table-bordered table-condensed greyhead">
{% set curr = namespace(level=-1) %}
{% set curr = namespace(category="") %}
{% for o in overview %}
{% if curr.level != o.round.level %}
{% if curr.category != o.round.category %}
<thead><tr>
<th>ID
<th>Kategorie
<th>Kolo
<th>{{ o.round.get_level().name|capitalize }}
<th>Místo
<th>Stav
<th class='has-tip' title='S=soutěže, U=soutěžící účastníci, P=přihlášky čekající na potvrzení'>Statistiky
<th>Moje role
<th>Odkazy
</thead>
{% set curr.level = o.round.level %}
{% set curr.category = o.round.category %}
{% endif %}
{% if o.contest %}
{% if o.place == o.contest.place %}
{% set detail_url = url_for('org_contest', ct_id=o.contest.contest_id) %}
{% else %}
{% set detail_url = url_for('org_contest', ct_id=o.contest.contest_id, site_id=o.place.place_id) %}
{% endif %}
{% elif o.place.level == 0 %}
{% set detail_url = url_for('org_round', round_id=o.round.round_id) %}
{% else %}
......@@ -35,10 +39,14 @@
<td class="text-center"><b>{{ o.round.category }}</b>
<td>{{ o.round.name }}
{% if o.contest %}
{% if o.place == o.contest.place %}
<td>{{ o.place.name }}
{% else %}
<td><i>{{ o.place.name_locative() }}</i>
{% endif %}
{% else %}
<td><i>{{ o.place.name_locative() }}</i>
{% endif %}
<td>{% for s in o.contest_states %}{% if not loop.first %}<br>{% endif %}<span class="rstate-{{s.name}}">{{ s.friendly_name() }}</span>{% endfor %}
<td>{% if not o.contest %}{{ o.num_contests }}S / {% endif %}
{{- o.num_active_pants }}U
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment