
Add the following user commands: - list - autopromote List will list all users as a table, useful for debugging things without pulling out the database or the admin page Autopromote will automatically promote and email users off the waitlist until capacity is reached
179 lines
5.2 KiB
Python
179 lines
5.2 KiB
Python
from datetime import datetime
|
|
import click
|
|
from flask import current_app, render_template
|
|
from flask.cli import AppGroup
|
|
from flask_mail import Message
|
|
from werkzeug.security import generate_password_hash
|
|
|
|
from goathacks.registration import bp
|
|
from goathacks import db, mail
|
|
from goathacks.models import User
|
|
|
|
from tabulate import tabulate
|
|
|
|
gr = AppGroup("user")
|
|
|
|
@gr.command('create')
|
|
@click.option("--email", prompt=True, help="User's Email")
|
|
@click.option("--first_name", prompt=True)
|
|
@click.option("--last_name", prompt=True)
|
|
@click.option("--admin/--no-admin", prompt=True, default=False)
|
|
@click.option("--password", prompt=True, hide_input=True,
|
|
confirmation_prompt=True)
|
|
@click.option("--school", prompt=True)
|
|
@click.option("--phone", prompt=True)
|
|
@click.option("--gender", prompt=True)
|
|
def create_user(email, first_name, last_name, password, school, phone, gender,
|
|
admin):
|
|
"""
|
|
Creates a user
|
|
"""
|
|
|
|
if gender not in ['F', 'M', 'NB']:
|
|
click.echo("Invalid gender. Must be one of F, M, NB")
|
|
return
|
|
|
|
num_not_waitlisted = len(User.query.filter_by(waitlisted=False).all())
|
|
waitlisted = False
|
|
if num_not_waitlisted >= current_app.config['MAX_BEFORE_WAITLIST']:
|
|
waitlisted = True
|
|
|
|
user = User(
|
|
email=email,
|
|
password=generate_password_hash(password),
|
|
first_name=first_name,
|
|
last_name=last_name,
|
|
last_login=datetime.now(),
|
|
waitlisted=waitlisted,
|
|
school=school,
|
|
phone=phone,
|
|
gender=gender,
|
|
is_admin=admin
|
|
)
|
|
db.session.add(user)
|
|
db.session.commit()
|
|
|
|
click.echo("Created user")
|
|
|
|
@gr.command("promote")
|
|
@click.option("--email", prompt=True)
|
|
def promote_user(email):
|
|
"""
|
|
Promotes a user to administrator
|
|
"""
|
|
user = User.query.filter_by(email=email).one()
|
|
|
|
user.is_admin = True
|
|
|
|
db.session.commit()
|
|
|
|
click.echo(f"Promoted {user.first_name} to admin")
|
|
|
|
|
|
@gr.command("demote")
|
|
@click.option("--email", prompt=True)
|
|
def demote_user(email):
|
|
"""
|
|
Demotes a user from administrator
|
|
"""
|
|
user = User.query.filter_by(email=email).one()
|
|
|
|
user.is_admin = False
|
|
|
|
db.session.commit()
|
|
|
|
click.echo(f"Demoted {user.first_name} from admin")
|
|
|
|
@gr.command("waitlist")
|
|
@click.option("--email", prompt=True)
|
|
def waitlist_user(email):
|
|
"""
|
|
Toggles the waitlist status of a user
|
|
"""
|
|
user = User.query.filter_by(email=email).one()
|
|
|
|
user.waitlisted = not user.waitlisted
|
|
|
|
db.session.commit()
|
|
|
|
if user.waitlisted:
|
|
click.echo(f"Sent {user.first_name} to the waitlist")
|
|
else:
|
|
msg = Message("Waitlist Promotion")
|
|
msg.add_recipient(user.email)
|
|
msg.body = render_template("emails/waitlist_promotion.txt", user=user)
|
|
mail.send(msg)
|
|
click.echo(f"Promoted {user.first_name} from the waitlist")
|
|
|
|
@gr.command("drop")
|
|
@click.option("--email", prompt=True)
|
|
@click.option("--confirm/--noconfirm", prompt=False, default=True)
|
|
def drop_user(email, confirm):
|
|
"""
|
|
Drops a user's registration
|
|
"""
|
|
user = User.query.filter_by(email=email).one()
|
|
if not confirm:
|
|
pass
|
|
else:
|
|
if click.confirm(f"Are you sure you want to drop {user.first_name} {user.last_name}'s registration? **THIS IS IRREVERSIBLE**"):
|
|
pass
|
|
else:
|
|
return
|
|
db.session.delete(user)
|
|
db.session.commit()
|
|
click.echo(f"Dropped {user.first_name}'s registration")
|
|
|
|
@gr.command("list")
|
|
def list_users():
|
|
"""
|
|
Gets a list of all users
|
|
"""
|
|
users = User.query.all()
|
|
|
|
def make_table_content(user):
|
|
return [user.email, f"{user.first_name} {user.last_name}", user.waitlisted, user.is_admin]
|
|
|
|
table = map(make_table_content, users)
|
|
|
|
print(tabulate(table, headers=["Email", "Name", "Waitlisted", "Admin"]))
|
|
|
|
|
|
@gr.command("autopromote")
|
|
def autopromote_users():
|
|
"""
|
|
Runs through and automatically promotes users up to the waitlist limit
|
|
"""
|
|
WAITLIST_LIMIT = current_app.config['MAX_BEFORE_WAITLIST']
|
|
num_confirmed = db.session.query(User).filter(User.waitlisted == False).count()
|
|
click.echo(f"Got {num_confirmed} confirmed attendees")
|
|
num_waitlisted = db.session.query(User).filter(User.waitlisted == True).count()
|
|
click.echo(f"Got {num_waitlisted} waitlisted attendees")
|
|
|
|
num_to_promote = WAITLIST_LIMIT - num_confirmed
|
|
|
|
if num_to_promote > num_waitlisted:
|
|
num_to_promote = num_waitlisted
|
|
|
|
click.echo(f"About to promote {str(num_to_promote)} attendees from waitlist")
|
|
|
|
users = db.session.query(User).filter(User.waitlisted == True).all()
|
|
|
|
num_promoted = 0
|
|
num_to_promote_orig = num_to_promote
|
|
|
|
for u in users:
|
|
if num_to_promote > 0:
|
|
click.echo(f"Attempting to promote {u.email} ({u.id})")
|
|
u.waitlisted = False
|
|
db.session.commit()
|
|
msg = Message("Waitlist Promotion")
|
|
msg.add_recipient(u.email)
|
|
msg.sender = ("GoatHacks Team", "hack@wpi.edu")
|
|
msg.body = render_template("emails/waitlist_promotion.txt", user=u)
|
|
mail.send(msg)
|
|
num_promoted += 1
|
|
num_to_promote -= 1
|
|
|
|
click.echo(f"Promoted {num_promoted}/{num_to_promote_orig} attendees off the waitlist!")
|
|
|