Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ ENV/
# JetBrains
.idea/

# vscode
.vscode

# Configurations
config.py

Expand All @@ -128,3 +131,5 @@ packet/static/safari-pinned-tab.svg
packet/static/site.webmanifest
faviconData.json

# csvs
*.csv
1 change: 1 addition & 0 deletions packet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@

if app.config['REALM'] == 'csh':
from .routes import upperclassmen
from .routes import admin
else:
from .routes import freshmen

Expand Down
36 changes: 2 additions & 34 deletions packet/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
from .ldap import ldap_get_eboard_role, ldap_get_active_rtps, ldap_get_3das, ldap_get_webmasters, \
ldap_get_drink_admins, ldap_get_constitutional_maintainers, ldap_is_intromember, ldap_get_active_members, \
ldap_is_on_coop
from .utils import sync_freshman


@app.cli.command('create-secret')
Expand Down Expand Up @@ -66,40 +67,7 @@ def sync_freshmen(freshmen_csv):
freshmen_in_csv = parse_csv(freshmen_csv)

print('Syncing contents with the DB...')
freshmen_in_db = {freshman.rit_username: freshman for freshman in Freshman.query.all()}

for csv_freshman in freshmen_in_csv.values():
if csv_freshman.rit_username not in freshmen_in_db:
# This is a new freshman so add them to the DB
freshmen_in_db[csv_freshman.rit_username] = Freshman(rit_username=csv_freshman.rit_username,
name=csv_freshman.name, onfloor=csv_freshman.onfloor)
db.session.add(freshmen_in_db[csv_freshman.rit_username])
else:
# This freshman is already in the DB so just update them
freshmen_in_db[csv_freshman.rit_username].onfloor = csv_freshman.onfloor
freshmen_in_db[csv_freshman.rit_username].name = csv_freshman.name

# Update all freshmen entries that represent people who are no longer freshmen
for freshman in filter(lambda freshman: freshman.rit_username not in freshmen_in_csv, freshmen_in_db.values()):
freshman.onfloor = False

# Update the freshmen signatures of each open or future packet
for packet in Packet.query.filter(Packet.end > datetime.now()).all():
# Handle the freshmen that are no longer onfloor
for fresh_sig in filter(lambda fresh_sig: not fresh_sig.freshman.onfloor, packet.fresh_signatures):
FreshSignature.query.filter_by(packet_id=fresh_sig.packet_id,
freshman_username=fresh_sig.freshman_username).delete()

# Add any new onfloor freshmen
# pylint: disable=cell-var-from-loop
current_fresh_sigs = set(map(lambda fresh_sig: fresh_sig.freshman_username, packet.fresh_signatures))
for csv_freshman in filter(lambda csv_freshman: csv_freshman.rit_username not in current_fresh_sigs and
csv_freshman.onfloor and
csv_freshman.rit_username != packet.freshman_username,
freshmen_in_csv.values()):
db.session.add(FreshSignature(packet=packet, freshman=freshmen_in_db[csv_freshman.rit_username]))

db.session.commit()
sync_freshman(freshmen_in_csv)
print('Done!')


Expand Down
4 changes: 2 additions & 2 deletions packet/context_processors.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ def get_roles(sig):


# pylint: disable=bare-except
@lru_cache(maxsize=128)
@lru_cache(maxsize=256)
def get_rit_name(username):
try:
freshman = Freshman.query.filter_by(rit_username=username).first()
Expand All @@ -53,7 +53,7 @@ def get_rit_name(username):


# pylint: disable=bare-except
@lru_cache(maxsize=128)
@lru_cache(maxsize=256)
def get_rit_image(username):
if username:
addresses = [username + '@rit.edu', username + '@g.rit.edu']
Expand Down
10 changes: 9 additions & 1 deletion packet/ldap.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,15 +149,23 @@ def ldap_get_eboard_role(member):

return return_val

# Status checkers

# Status checkers
def ldap_is_eboard(member):
"""
:param member: A CSHMember instance
"""
return _ldap_is_member_of_group(member, 'eboard')


def ldap_is_evals(member):
return _ldap_is_member_of_group(member, 'eboard-evaluations')


def ldap_is_rtp(member):
return _ldap_is_member_of_group(member, 'rtp')


def ldap_is_intromember(member):
"""
:param member: A CSHMember instance
Expand Down
7 changes: 7 additions & 0 deletions packet/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,13 @@ def by_username(cls, username: str):
"""
return cls.query.filter_by(rit_username=username).first()

@classmethod
def get_all(cls):
"""
Helper method to get all freshmen easily
"""
return cls.query.all()


class Packet(db.Model):
__tablename__ = 'packet'
Expand Down
43 changes: 43 additions & 0 deletions packet/routes/admin.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
from flask import render_template

from packet import app
from packet.models import Packet, Freshman
from packet.routes.shared import packet_sort_key
from packet.utils import before_request, packet_auth, admin_auth
from packet.log_utils import log_cache, log_time


@app.route('/admin/packets')
@log_cache
@packet_auth
@admin_auth
@before_request
@log_time
def admin_packets(info=None):
open_packets = Packet.open_packets()

# Pre-calculate and store the return values of did_sign(), signatures_received(), and signatures_required()
for packet in open_packets:
packet.did_sign_result = packet.did_sign(info['uid'], app.config['REALM'] == 'csh')
packet.signatures_received_result = packet.signatures_received()
packet.signatures_required_result = packet.signatures_required()

open_packets.sort(key=packet_sort_key, reverse=True)

return render_template('admin_packets.html',
open_packets=open_packets,
info=info)


@app.route('/admin/freshmen')
@log_cache
@packet_auth
@admin_auth
@before_request
@log_time
def admin_freshmen(info=None):
all_freshmen = Freshman.get_all()

return render_template('admin_freshmen.html',
all_freshmen=all_freshmen,
info=info)
77 changes: 27 additions & 50 deletions packet/routes/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,22 @@
from packet.ldap import ldap_get_eboard_role, ldap_get_active_rtps, ldap_get_3das, ldap_get_webmasters, \
ldap_get_drink_admins, ldap_get_constitutional_maintainers, ldap_is_intromember, ldap_get_active_members, \
ldap_is_on_coop, _ldap_is_member_of_group, ldap_get_member
from packet.log_utils import log_time
from packet.mail import send_report_mail, send_start_packet_mail
from packet.utils import before_request, packet_auth, notify_slack
from packet.utils import before_request, packet_auth, notify_slack, sync_freshman as sync_freshman_list
from packet.models import Packet, MiscSignature, NotificationSubscription, Freshman, FreshSignature, UpperSignature
from packet.notifications import packet_signed_notification, packet_100_percent_notification, \
packet_starting_notification, packets_starting_notification
packet_starting_notification, packets_starting_notification
import packet.stats as stats


class POSTFreshman:
def __init__(self, freshman):
self.name = freshman['name'].strip()
self.rit_username = freshman['rit_username'].strip()
self.onfloor = freshman['onfloor'].strip() == 'TRUE'


@app.route('/api/v1/freshmen', methods=['POST'])
@packet_auth
def sync_freshman():
Expand All @@ -40,47 +48,14 @@ def sync_freshman():
if not _ldap_is_member_of_group(ldap_get_member(username), 'eboard-evaluations'):
return 'Forbidden: not Evaluations Director', 403

freshmen = request.json
results = list()

packets = Packet.query.filter(Packet.end > datetime.now()).all()

for freshman in freshmen:
rit_username = freshman['rit_username']
name = freshman['name']
onfloor = freshman['onfloor']

frosh = Freshman.query.filter_by(rit_username=rit_username).first()
if frosh:
if onfloor and not frosh.onfloor:
# Add new onfloor signature
for packet in packets:
db.session.add(FreshSignature(packet=packet, freshman=frosh))
elif not onfloor and frosh.onfloor:
# Remove outdated onfloor signature
for packet in packets:
FreshSignature.query.filter_by(packet_id=packet.id, freshman_username=frosh.rit_username).delete()

frosh.name = name
frosh.onfloor = onfloor

results.append(f"'{name} ({rit_username})' updated")
else:
frosh = Freshman(rit_username=rit_username, name=name, onfloor=onfloor)
db.session.add(frosh)
if onfloor:
# Add onfloor signature
for packet in packets:
db.session.add(FreshSignature(packet=packet, freshman=frosh))

results.append(f"Freshman '{name} ({rit_username})' created")

db.session.commit()
return dumps(results), 200
freshmen_in_post = {freshman.rit_username: freshman for freshman in map(POSTFreshman, request.json)}
sync_freshman_list(freshmen_in_post)
return dumps('Done'), 200


@app.route('/api/v1/packets', methods=['POST'])
@packet_auth
@log_time
def create_packet():
"""
Create a new packet.
Expand Down Expand Up @@ -163,7 +138,7 @@ def get_packets_by_user(username: str) -> dict:
return {packet.id: {
'start': packet.start,
'end': packet.end,
} for packet in frosh.packets}
} for packet in frosh.packets}


@app.route('/api/v1/packets/<username>/newest', methods=['GET'])
Expand All @@ -177,13 +152,13 @@ def get_newest_packet_by_user(username: str) -> dict:
packet = frosh.packets[-1]

return {
packet.id: {
'start': packet.start,
'end': packet.end,
'required': vars(packet.signatures_required()),
'received': vars(packet.signatures_received()),
}
}
packet.id: {
'start': packet.start,
'end': packet.end,
'required': vars(packet.signatures_required()),
'received': vars(packet.signatures_received()),
}
}


@app.route('/api/v1/packet/<packet_id>', methods=['GET'])
Expand All @@ -196,9 +171,10 @@ def get_packet_by_id(packet_id: int) -> dict:
packet = Packet.by_id(packet_id)

return {
'required': vars(packet.signatures_required()),
'received': vars(packet.signatures_received()),
}
'required': vars(packet.signatures_required()),
'received': vars(packet.signatures_received()),
}


@app.route('/api/v1/sign/<packet_id>/', methods=['POST'])
@packet_auth
Expand Down Expand Up @@ -264,6 +240,7 @@ def packet_stats(packet_id):
def upperclassman_stats(uid):
return stats.upperclassman_stats(uid)


def commit_sig(packet, was_100, uid):
packet_signed_notification(packet, uid)
db.session.commit()
Expand Down
2 changes: 1 addition & 1 deletion packet/routes/shared.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
@app.route('/logout/')
@auth.oidc_logout
def logout():
return redirect('http://csh.rit.edu')
return redirect('https://csh.rit.edu')


@app.route('/packet/<packet_id>/')
Expand Down
Loading