Skip to content
Snippets Groups Projects
Select Git revision
  • 17e102b7fac9dd77e645c8d20383930fdeb4e298
  • devel default
  • master
  • fo
  • jirka/typing
  • fo-base
  • mj/submit-images
  • jk/issue-96
  • jk/issue-196
  • honza/add-contestant
  • honza/mr7
  • honza/mrf
  • honza/mrd
  • honza/mra
  • honza/mr6
  • honza/submit-images
  • honza/kolo-vs-soutez
  • jh-stress-test-wip
  • shorten-schools
19 results

util.py

Blame
  • merge-users 3.28 KiB
    #!/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()