#!/usr/bin/env python3 import argparse from sqlalchemy import and_ import mo.db as db import mo.users import mo.util parser = argparse.ArgumentParser(description='Sloučí dva uživatele do jednoho') parser.add_argument(dest='src', help='e-mailová adresa zdrojového účtu') parser.add_argument(dest='dest', help='e-mailová adresa cílového účtu') parser.add_argument('-n', '--dry-run', default=False, action='store_true', help='vyzkouší sloučení nanečisto (necommitne)') args = parser.parse_args() mo.util.init_standalone() su = mo.users.user_by_email(args.src) if su is None: mo.util.die(f'Uživatel <{args.src}> nenalezen') du = mo.users.user_by_email(args.dest) if du is None: mo.util.die(f'Uživatel <{args.dest}> nenalezen') if (su.is_org, su.is_admin) != (du.is_org, du.is_admin): mo.util.die('Neumím sloučit účty různého typu') suid = su.user_id duid = du.user_id print(f"Slučuji UID {suid} do UID {duid}") sess = db.get_session() conn = sess.connection() test_round = sess.query(db.Round).filter_by(category='T').one_or_none() if test_round is not None: test_submits = (sess .query(db.Solution) .join(db.Task) .filter(db.Solution.user_id == suid) .filter(db.Task.round == test_round) .filter(db.Round.category == 'T') .all()) if test_submits: mo.util.die("Zdrojový účastník něco odevzdal v testovací soutěži, nutno vyřešit ručně") test_contest = sess.query(db.Contest).filter_by(round=test_round).one_or_none() test_contest_id = test_contest.contest_id if test_contest is not None else None else: test_contest = None test_contest_id = None sess.flush() conn.execute(db.Log.__table__.update().where(db.Log.changed_by == suid).values(changed_by=duid)) conn.execute(db.Participant.__table__.delete().where(db.Participant.user_id == suid)) conn.execute(db.Participation.__table__.delete().where(and_(db.Participation.user_id == suid, db.Participation.contest_id == test_contest_id))) conn.execute(db.Participation.__table__.update().where(db.Participation.user_id == suid).values(user_id=duid)) conn.execute(db.UserRole.__table__.update().where(db.UserRole.user_id == suid).values(user_id=duid)) conn.execute(db.UserRole.__table__.update().where(db.UserRole.assigned_by == suid).values(assigned_by=duid)) conn.execute(db.Paper.__table__.update().where(db.Paper.for_user == suid).values(for_user=duid)) conn.execute(db.Paper.__table__.update().where(db.Paper.uploaded_by == suid).values(uploaded_by=duid)) conn.execute(db.PointsHistory.__table__.update().where(db.PointsHistory.participant_id == suid).values(participant_id=duid)) conn.execute(db.PointsHistory.__table__.update().where(db.PointsHistory.points_by == suid).values(points_by=duid)) conn.execute(db.Solution.__table__.update().where(db.Solution.user_id == suid).values(user_id=duid)) conn.execute(db.Job.__table__.update().where(db.Job.user_id == suid).values(user_id=duid)) conn.execute(db.User.__table__.delete().where(db.User.user_id == suid)) mo.util.log(db.LogType.user, suid, { 'action': 'merge', 'to': duid, }) mo.util.log(db.LogType.user, duid, { 'action': 'merge', 'from': suid, }) if not args.dry_run: sess.commit() else: sess.rollback()