diff --git a/etc/config.py.example b/etc/config.py.example index d214b75aa9c195f23f7d8428f64c082564212248..2d14749df02c79a6e27ca37d4b5e8e29463faffb 100644 --- a/etc/config.py.example +++ b/etc/config.py.example @@ -47,3 +47,7 @@ JOB_GC_PERIOD = 60 # Za jak dlouho expiruje dokončená dávka [min] JOB_EXPIRATION = 5 + +# Automatické přihlašování účastníků do testovací soutěže +# (kolo aktuální_ročník-T-1, celostátní soutěž) +AUTO_REGISTER_TEST = True diff --git a/mo/web/user.py b/mo/web/user.py index e54667f5e6b7cfc28ac7022658cafa175ef0e269..d4c70451c82986e50568152161d2d9a1efdf413e 100644 --- a/mo/web/user.py +++ b/mo/web/user.py @@ -3,9 +3,11 @@ from flask_wtf import FlaskForm import flask_wtf.file from sqlalchemy import and_ from sqlalchemy.orm import joinedload +from typing import List, Tuple import werkzeug.exceptions import wtforms +import mo import mo.config as config import mo.db as db import mo.submit @@ -18,21 +20,56 @@ import mo.web.util @app.route('/user') def user_index(): - sess = db.get_session() - - pions = (sess.query(db.Participation, db.Contest, db.Round) - .select_from(db.Participation) - .join(db.Contest, db.Contest.master_contest_id == db.Participation.contest_id) - .join(db.Round) - .filter(db.Participation.user == g.user) - .options(joinedload(db.Contest.place)) - .order_by(db.Round.year.desc(), db.Round.category, db.Round.seq, db.Round.part) - .all()) + pcrs = load_pcrs() + if getattr(config, 'AUTO_REGISTER_TEST', False) and not any(round.category == 'T' for pion, contest, round in pcrs): + if register_to_test(): + pcrs = load_pcrs() return render_template( 'user_index.html', - pions=pions, + pions=pcrs, + ) + + +def load_pcrs() -> List[Tuple[db.Participation, db.Contest, db.Round]]: + return (db.get_session().query(db.Participation, db.Contest, db.Round) + .select_from(db.Participation) + .join(db.Contest, db.Contest.master_contest_id == db.Participation.contest_id) + .join(db.Round) + .filter(db.Participation.user == g.user) + .options(joinedload(db.Contest.place)) + .order_by(db.Round.year.desc(), db.Round.category, db.Round.seq, db.Round.part) + .all()) + + +def register_to_test() -> bool: + sess = db.get_session() + round = sess.query(db.Round).filter_by(year=mo.current_year, category='T', seq=1, part=0).one_or_none() + if not round: + app.logger.error(f'Nemohu najít kolo {mo.current_year}-T-1') + return False + + if round.level != 0: + app.logger.error(f'Kolo {round.round_code_short()} není na celostátní úrovni') + return False + + contest = sess.query(db.Contest).filter_by(round=round).limit(1).one_or_none() + if not contest: + app.logger.error(f'Kolo {round.round_code_short()} nemá soutěž') + return False + + pion = db.Participation(user=g.user, contest=contest, place=contest.place, state=db.PartState.registered) + sess.add(pion) + sess.flush() + mo.util.log( + type=db.LogType.participant, + what=g.user.user_id, + details={'action': 'add-to-contest', 'new': db.row2dict(pion)}, ) + sess.commit() + + app.logger.info(f'Účastník #{g.user.user_id} automaticky registrován do soutěže #{contest.contest_id}') + return True def get_contest(id: int) -> db.Contest: