Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • mj/mo-submit
1 result
Select Git revision
Show changes
Commits on Source (6)
- nastavit cestu k cookies
- poznámka u uživatele
- budeme znát roky narození?
- uklidit v logování
- na import by bylo hezké mít testy
- pamatovat si IČO školy (kvůli Excelenci)?
- ostylovat login form
- export: lidská jména stavů
Nasazení:
- kontakt na správce
......
#!/usr/bin/env python3
import argparse
import re
import sys
import mo.db as db
import mo.util
from mo.util import die
parser = argparse.ArgumentParser(description='Přidělí uživateli roli')
parser.add_argument('--email', type=str, help='e-mailová adresa uživatele')
parser.add_argument('--uid', type=int, help='ID uživatele')
parser.add_argument('--role', type=str, help='název role', required=True)
parser.add_argument('--place-id', type=int, help='omezení role na místo s daným ID')
parser.add_argument('--place', type=str, help='omezení role na místo s daným kódem')
parser.add_argument('--cat', type=str, help='omezení role na danou kategorii')
parser.add_argument('--round', type=str, metavar='YY-R', help='omezení role na dané kolo')
parser.add_argument('--year', type=int, help='omezení role na daný ročník')
parser.add_argument('--seq', type=int, help='omezení role na dané pořadí kola')
args = parser.parse_args()
session = db.get_session()
......@@ -29,58 +29,39 @@ else:
parser.error('Je nutné vybrat uživatele pomocí --email nebo --uid')
if not user:
print("Tento uživatel neexistuje", file=sys.stderr)
sys.exit(1)
die("Tento uživatel neexistuje")
if user.is_admin:
print("Tento uživatel je admin, nemá smysl přidělovat mu další práva", file=sys.stderr)
sys.exit(1)
die("Tento uživatel je admin, nemá smysl přidělovat mu další práva")
if not user.is_org:
print("Tento uživatel není organizátor", file=sys.stderr)
sys.exit(1)
die("Tento uživatel není organizátor")
role = getattr(db.RoleType, args.role, None)
if role is None:
print("Tato role neexistuje", file=sys.stderr)
sys.exit(1)
die("Tato role neexistuje")
for_round = None
if args.round:
m = re.fullmatch(r'(\d+)-(\d+)', args.round)
if not m:
parser.error('Chybná syntaxe --round')
if not args.cat:
parser.error('--round vyžaduje zadání kategorie')
round = session.query(db.Round).filter_by(year=int(m[1]), category=args.cat, level=int(m[2])).first()
if not round:
print("Toto kolo neexistuje", file=sys.stderr)
sys.exit(1)
for_round = round.round_id
if args.place_id:
for_place = args.place_id
if args.place:
for_place = db.get_place_by_code(args.place)
if for_place is None:
die("Toto místo neexistuje")
else:
place = session.query(db.Place).filter_by(level=1).first()
assert place
for_place = place.place_id
for_place = db.get_root_place()
assert for_place is not None
ur = db.UserRole(
user_id=user.user_id,
place_id=for_place,
place=for_place,
role=role,
category=args.cat,
round_id=for_round,
year=args.year,
seq=args.seq,
)
session.add(ur)
session.flush()
mo.util.log(db.LogType.user_role, ur.user_role_id, {
'action': 'assigned',
'user_id': ur.user_id,
'place_id': ur.place_id,
'role': role.name,
'category': ur.category,
'round_id': ur.round_id,
'new': db.row2dict(ur),
})
session.commit()
#!/usr/bin/env python3
import argparse
import sys
import mo.db as db
import mo.util
from mo.util import die
parser = argparse.ArgumentParser(description='Založí soutěže pro dané kolo')
parser.add_argument(dest='round_id', type=int, help='ID kola')
parser.add_argument(dest='round', type=str, metavar='YY-C-S', help='ID kola')
parser.add_argument('-n', '--dry-run', default=False, action='store_true', help='pouze ukáže, co by bylo provedeno')
args = parser.parse_args()
sess = db.get_session()
round = sess.query(db.Round).get(args.round_id)
if not round:
print("Kolo s tímto ID neexistuje!", file=sys.stderr)
sys.exit(1)
round_code = mo.util.RoundCode.parse(args.round)
if round_code is None:
die("Chybná syntaxe kódu kola")
round = mo.util.get_round_by_code(round_code)
if round is None:
die("Kolo s tímto kódem neexistuje!")
regions = sess.query(db.Place).filter_by(level=round.level).all()
assert regions, "Neexistují žádná místa dané úrovně"
for r in regions:
print(f"Zakládám pro místo {r.name}")
print(f"Zakládám {round.round_code()} pro místo {r.name}")
if not args.dry_run:
c = db.Contest(round=round, place=r)
sess.add(c)
......
#!/usr/bin/env python3
import argparse
import mo.db as db
import mo.util
parser = argparse.ArgumentParser(description='Založí soutěžní kolo')
parser.add_argument('-y', '--year', type=int, required=True, help='ročník')
parser.add_argument('-c', '--cat', type=str, required=True, help='kategorie')
parser.add_argument('-s', '--seq', type=int, required=True, help='pořadí kola')
parser.add_argument('-l', '--level', type=int, required=True, help='úroveň v hierarchii oblastí')
parser.add_argument('-n', '--name', type=str, required=True, help='název kola')
args = parser.parse_args()
sess = db.get_session()
rnd = db.Round(
year=args.year,
category=args.cat,
seq=args.seq,
level=args.level,
name=args.name,
)
sess.add(rnd)
sess.flush()
mo.util.log(
type=db.LogType.round,
what=rnd.round_id,
details={
'action': 'created',
'new': db.row2dict(rnd),
},
)
sess.commit()
#!/usr/bin/env python3
import mo.db as db
import mo.users
import mo.util
import argparse
......@@ -11,6 +12,7 @@ parser.add_argument(dest='first_name', help='křestní jméno (jedno nebo více)
parser.add_argument(dest='last_name', help='příjmení (jedno nebo více)')
parser.add_argument('--org', default=False, action='store_true', help='přidělí uživateli organizátorská práva')
parser.add_argument('--admin', default=False, action='store_true', help='přidělí uživateli správcovská práva')
parser.add_argument('--passwd', type=str, help='nastaví počáteční heslo')
args = parser.parse_args()
......@@ -32,4 +34,8 @@ mo.util.log(db.LogType.user, user.user_id, {
'is_org': user.is_org,
'is_admin': user.is_admin
})
if args.passwd is not None:
mo.users.set_password(user, args.passwd)
session.commit()
......@@ -30,7 +30,6 @@ def import_schools(path: Path, nuts: str):
with path.open('r') as file:
columns = parse_header(file.readline())
print(columns)
for line in file:
f = line.split('\t')
red_izo = f[columns['Red IZO']]
......
#!/bin/bash
set -e
psql mo_osmo <db/drop-all.sql
psql mo_osmo <db/db.ddl
bin/init-regions
bin/init-schools
bin/create-user mj@ucw.cz Martin Mareš --admin --passwd brum
bin/create-user medved@ucw.cz Baltasis Lokys --org --passwd brum
bin/add-role --email medved@ucw.cz --role garant --cat P
bin/add-role --email medved@ucw.cz --role garant --cat A --place PB
bin/create-round -y 70 -c P -s 1 -n 'Školní kolo' -l 1
bin/create-round -y 70 -c P -s 2 -n 'Krajské kolo' -l 1
bin/create-round -y 70 -c P -s 3 -n 'Ústřední kolo' -l 0
bin/create-round -y 70 -c A -s 1 -n 'Školní kolo (domácí)' -l 1
bin/create-round -y 70 -c A -s 2 -n 'Školní kolo (klauzurní)' -l 1
bin/create-round -y 70 -c A -s 3 -n 'Krajské kolo' -l 1
bin/create-round -y 70 -c A -s 4 -n 'Ústřední kolo' -l 0
bin/create-contests 70-P-2
bin/create-contests 70-A-3
INSERT INTO rounds(year, category, seq, level, name) VALUES
(1, 70, 'A', 1, 'Krajské kolo' , 3 ),
(2, 70, 'A', 0, 'Ústrední kolo' , 4 ),
(3, 70, 'A', 4, 'Školní kolo (domácí)' , 1 ),
(5, 70, 'A', 4, 'Školní kolo (klauzurní)', 2 ),
(6, 70, 'P', 0, 'Školní kolo' , 1 ),
(7, 70, 'P', 1, 'Krajské kolo' , 2 ),
(8, 70, 'P', 0, 'Ústřední kolo' , 3 );
......@@ -279,7 +279,7 @@ class UserRole(Base):
year = Column(Integer)
seq = Column(Integer)
assigned_by = Column(Integer, ForeignKey('users.user_id'))
assigned_at = Column(DateTime(True))
assigned_at = Column(DateTime(True), nullable=False, server_default=text("CURRENT_TIMESTAMP"))
user = relationship('User', primaryjoin='UserRole.user_id == User.user_id')
assigned_by_user = relationship('User', primaryjoin='UserRole.assigned_by == User.user_id')
......
# Různé
from dataclasses import dataclass
import datetime
import email.message
import email.headerregistry
import re
from sqlalchemy.orm import joinedload
import subprocess
from typing import Any, Optional
import sys
from typing import Any, Optional, NoReturn
import textwrap
import mo.db as db
......@@ -64,3 +65,30 @@ def send_password_reset_email(user: db.User, link: str):
if sm.returncode != 0:
raise RuntimeError('Sendmail failed with return code {}'.format(sm.returncode))
def die(msg: str) -> NoReturn:
print(msg, file=sys.stderr)
sys.exit(1)
@dataclass
class RoundCode:
year: int
cat: str
seq: int
def __str__(self):
return f'{self.year}-{self.cat}-{self.seq}'
@staticmethod
def parse(code: str) -> Optional['RoundCode']:
m = re.match(r'(\d+)-([A-Z0-9]+)-(\d+)', code)
if m:
return RoundCode(year=int(m[1]), cat=m[2], seq=int(m[3]))
else:
return None
def get_round_by_code(code: RoundCode) -> Optional[db.Round]:
return db.get_session().query(db.Round).filter_by(year=code.year, category=code.cat, seq=code.seq).one_or_none()