Project 'mj/mo-submit' was moved to 'mo-p/osmo'. Please update any links and bookmarks that may still have the old path.
Select Git revision

Martin Mareš authored
Hierarchický odkaz se objeví jen tehdy, je-li úroveň kola ostře mělčí než úroveň práva.
org.py 4.48 KiB
from dataclasses import dataclass, field
from flask import render_template, redirect, url_for, request, flash, g
from sqlalchemy import and_, or_
from sqlalchemy.orm import aliased, joinedload
from typing import List, Set, Optional
import mo.config as config
import mo.db as db
import mo.rights
import mo.users
from mo.web import app
from mo.web.jinja import user_url
from mo.web.table import Table, Row, Column
@dataclass
class OrgOverview:
round: db.Round
place: db.Place
contest: Optional[db.Contest]
role_set: Set[db.RoleType] = field(default_factory=set)
role_list: List[db.RoleType] = field(default_factory=list)
@app.route('/org/')
def org_index():
if 'place' in request.args:
code = request.args['place']
place = db.get_place_by_code(code)
if place is not None:
return redirect(url_for('org_place', id=place.place_id))
else:
flash(f'Místo s kódem {code} neexistuje', 'danger')
if 'uid' in request.args:
try:
uid = int(request.args['uid'])
user = mo.users.user_by_uid(uid)
if user is not None:
return redirect(user_url(user))
flash(f'Uživatel s ID {uid} neexistuje', 'danger')
except ValueError:
flash('ID uživatele musí být číslo', 'danger')
sess = db.get_session()
rcu = (sess.query(db.Round, db.Contest, db.UserRole)
.select_from(db.UserRole)
.join(db.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))
.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())
overview: List[OrgOverview] = []
for r, ct, ur in rcu:
if ct is None and ur.place.level == r.level:
continue
o = overview[-1] if overview else None
if not (o and o.round == r and o.place == ur.place):
o = OrgOverview(round=r, place=ur.place, contest=ct)
overview.append(o)
o.role_set.add(ur.role)
for o in overview:
o.role_list = sorted(o.role_set, key=lambda r: mo.rights.role_order_by_type[r])
return render_template('org_index.html', overview=overview, role_type_names=db.role_type_names)
school_export_columns = (
Column(key='code', name='kod'),
Column(key='name', name='nazev'),
Column(key='town_code', name='kod_obce'),
Column(key='town', name='obec'),
Column(key='red_izo', name='red_izo'),
Column(key='ico', name='ico'),
Column(key='official_name', name='ofic_nazev'),
Column(key='address', name='adresa'),
Column(key='is_zs', name='typ_zs'),
Column(key='is_ss', name='typ_ss'),
)
@app.route('/org/export/schools')
def org_export_schools():
sess = db.get_session()
format = request.args.get('format', 'en_csv')
def gen_rows():
town = aliased(db.Place)
for p, s, t in (
sess.query(db.Place, db.School, town)
.filter(db.Place.type == db.PlaceType.school)
.filter(db.Place.place_id == db.School.place_id)
.filter(db.Place.parent == town.place_id)
.yield_per(100)):
yield Row(keys={
'code': p.get_code(),
'name': p.name,
'red_izo': s.red_izo,
'ico': s.ico,
'official_name': s.official_name,
'address': s.address,
'is_zs': int(s.is_zs),
'is_ss': int(s.is_ss),
'town_code': t.get_code(),
'town': t.name,
})
table = Table(school_export_columns, gen_rows(), 'skoly')
return table.send_as(format, streaming=True)