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
106 changes: 5 additions & 101 deletions packet/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,13 @@
import sys

from secrets import token_hex
from datetime import datetime, time, timedelta
from datetime import datetime, time
import csv
import click

from packet.mail import send_start_packet_mail
from packet.notifications import packet_starting_notification, packets_starting_notification
from . import app, db
from .models import Freshman, Packet, FreshSignature, UpperSignature, MiscSignature
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
from .models import Packet, FreshSignature, UpperSignature, MiscSignature
from .utils import sync_freshman, create_new_packets, sync_with_ldap


@app.cli.command('create-secret')
Expand Down Expand Up @@ -83,46 +78,8 @@ def create_packets(freshmen_csv):

# Collect the necessary data
base_date = input_date('Input the first day of packet season')
start = datetime.combine(base_date, packet_start_time)
end = datetime.combine(base_date, packet_end_time) + timedelta(days=14)

print('Fetching data from LDAP...')
all_upper = list(filter(
lambda member: not ldap_is_intromember(member) and not ldap_is_on_coop(member), ldap_get_active_members()))

rtp = ldap_get_active_rtps()
three_da = ldap_get_3das()
webmaster = ldap_get_webmasters()
c_m = ldap_get_constitutional_maintainers()
drink = ldap_get_drink_admins()

# Packet starting notifications
packets_starting_notification(start)

# Create the new packets and the signatures for each freshman in the given CSV
freshmen_in_csv = parse_csv(freshmen_csv)
print('Creating DB entries and sending emails...')
for freshman in Freshman.query.filter(Freshman.rit_username.in_(freshmen_in_csv)).all():
packet = Packet(freshman=freshman, start=start, end=end)
db.session.add(packet)
send_start_packet_mail(packet)
packet_starting_notification(packet)

for member in all_upper:
sig = UpperSignature(packet=packet, member=member.uid)
sig.eboard = ldap_get_eboard_role(member)
sig.active_rtp = member.uid in rtp
sig.three_da = member.uid in three_da
sig.webmaster = member.uid in webmaster
sig.c_m = member.uid in c_m
sig.drink_admin = member.uid in drink
db.session.add(sig)

for onfloor_freshman in Freshman.query.filter_by(onfloor=True).filter(Freshman.rit_username !=
freshman.rit_username).all():
db.session.add(FreshSignature(packet=packet, freshman=onfloor_freshman))

db.session.commit()
create_new_packets(base_date, freshmen_in_csv)
print('Done!')


Expand All @@ -131,60 +88,7 @@ def ldap_sync():
"""
Updates the upper and misc sigs in the DB to match ldap.
"""
print('Fetching data from LDAP...')
all_upper = {member.uid: member for member in filter(
lambda member: not ldap_is_intromember(member) and not ldap_is_on_coop(member), ldap_get_active_members())}

rtp = ldap_get_active_rtps()
three_da = ldap_get_3das()
webmaster = ldap_get_webmasters()
c_m = ldap_get_constitutional_maintainers()
drink = ldap_get_drink_admins()

print('Applying updates to the DB...')
for packet in Packet.query.filter(Packet.end > datetime.now()).all():
# Update the role state of all UpperSignatures
for sig in filter(lambda sig: sig.member in all_upper, packet.upper_signatures):
sig.eboard = ldap_get_eboard_role(all_upper[sig.member])
sig.active_rtp = sig.member in rtp
sig.three_da = sig.member in three_da
sig.webmaster = sig.member in webmaster
sig.c_m = sig.member in c_m
sig.drink_admin = sig.member in drink

# Migrate UpperSignatures that are from accounts that are not active anymore
for sig in filter(lambda sig: sig.member not in all_upper, packet.upper_signatures):
UpperSignature.query.filter_by(packet_id=packet.id, member=sig.member).delete()
if sig.signed:
sig = MiscSignature(packet=packet, member=sig.member)
db.session.add(sig)

# Migrate MiscSignatures that are from accounts that are now active members
for sig in filter(lambda sig: sig.member in all_upper, packet.misc_signatures):
MiscSignature.query.filter_by(packet_id=packet.id, member=sig.member).delete()
sig = UpperSignature(packet=packet, member=sig.member, signed=True)
sig.eboard = ldap_get_eboard_role(all_upper[sig.member])
sig.active_rtp = sig.member in rtp
sig.three_da = sig.member in three_da
sig.webmaster = sig.member in webmaster
sig.c_m = sig.member in c_m
sig.drink_admin = sig.member in drink
db.session.add(sig)

# Create UpperSignatures for any new active members
# pylint: disable=cell-var-from-loop
upper_sigs = set(map(lambda sig: sig.member, packet.upper_signatures))
for member in filter(lambda member: member not in upper_sigs, all_upper):
sig = UpperSignature(packet=packet, member=member)
sig.eboard = ldap_get_eboard_role(all_upper[sig.member])
sig.active_rtp = sig.member in rtp
sig.three_da = sig.member in three_da
sig.webmaster = sig.member in webmaster
sig.c_m = sig.member in c_m
sig.drink_admin = sig.member in drink
db.session.add(sig)

db.session.commit()
sync_with_ldap()
print('Done!')


Expand Down
86 changes: 27 additions & 59 deletions packet/routes/api.py
Original file line number Diff line number Diff line change
@@ -1,23 +1,20 @@
"""
Shared API endpoints
"""
from datetime import datetime, timedelta
from datetime import datetime
from json import dumps

from flask import session, request

from packet import app, db
from packet.context_processors import get_rit_name
from packet.commands import packet_start_time, packet_end_time
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.ldap import _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, 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
from packet.mail import send_report_mail
from packet.utils import before_request, packet_auth, notify_slack, sync_freshman as sync_freshman_list, \
create_new_packets, sync_with_ldap
from packet.models import Packet, MiscSignature, NotificationSubscription, Freshman
from packet.notifications import packet_signed_notification, packet_100_percent_notification
import packet.stats as stats


Expand Down Expand Up @@ -63,7 +60,11 @@ def create_packet():
Body parameters: {
start_date: the start date of the packets in MM/DD/YYYY format
freshmen: [
rit_username: string
{
rit_username: string
name: string
onfloor: boolean
}
]
}
"""
Expand All @@ -75,56 +76,23 @@ def create_packet():

base_date = datetime.strptime(request.json['start_date'], '%m/%d/%Y').date()

start = datetime.combine(base_date, packet_start_time)
end = datetime.combine(base_date, packet_end_time) + timedelta(days=14)

frosh = request.json['freshmen']
results = list()

# Gather upperclassmen data from LDAP
all_upper = list(filter(
lambda member: not ldap_is_intromember(member) and not ldap_is_on_coop(member), ldap_get_active_members()))

rtp = ldap_get_active_rtps()
three_da = ldap_get_3das()
webmaster = ldap_get_webmasters()
c_m = ldap_get_constitutional_maintainers()
drink = ldap_get_drink_admins()

# Packet starting notifications
packets_starting_notification(start)

for frosh_rit_username in frosh:
# Create the packet and signatures
freshman = Freshman.query.filter_by(rit_username=frosh_rit_username).first()
if freshman is None:
results.append(f"Freshman '{frosh_rit_username}' not found")
continue

packet = Packet(freshman=freshman, start=start, end=end)
db.session.add(packet)
send_start_packet_mail(packet)
packet_starting_notification(packet)

for member in all_upper:
sig = UpperSignature(packet=packet, member=member.uid)
sig.eboard = ldap_get_eboard_role(member)
sig.active_rtp = member.uid in rtp
sig.three_da = member.uid in three_da
sig.webmaster = member.uid in webmaster
sig.c_m = member.uid in c_m
sig.drink_admin = member.uid in drink
db.session.add(sig)

for onfloor_freshman in Freshman.query.filter_by(onfloor=True).filter(Freshman.rit_username !=
freshman.rit_username).all():
db.session.add(FreshSignature(packet=packet, freshman=onfloor_freshman))

results.append(f'Packet created for {frosh_rit_username}')
freshmen_in_post = {freshman.rit_username: freshman for freshman in map(POSTFreshman, request.json['freshmen'])}

create_new_packets(base_date, freshmen_in_post)

return dumps('Done'), 201

db.session.commit()

return dumps(results), 201
@app.route('/api/v1/sync', methods=['POST'])
@packet_auth
@log_time
def sync_ldap():
# Only allow evals to sync ldap
username = str(session['userinfo'].get('preferred_username', ''))
if not _ldap_is_member_of_group(ldap_get_member(username), 'eboard-evaluations'):
return 'Forbidden: not Evaluations Director', 403
sync_with_ldap()
return dumps('Done'), 201


@app.route('/api/v1/packets/<username>', methods=['GET'])
Expand Down
31 changes: 29 additions & 2 deletions packet/static/js/admin.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ $(document).ready(function () {
syncFreshmen();
})

$("#sync-ldap").click(() => {
syncLdap();
})

});

// Is this gross, yes. Do I feel like cleaning it up yet, no.
Expand All @@ -54,7 +58,11 @@ let makePackets = () => {
for (let i = 0; i < rows.length; i++) {
let cells = rows[i].split(",");
if (cells.length > 1) {
freshmen.push(cells[3]);
freshmen.push({
rit_username: cells[3],
name: cells[0],
onfloor: cells[1]
});
}
}
const payload = {start_date: $('#packet-start-date').val(), freshmen: freshmen}
Expand Down Expand Up @@ -120,7 +128,7 @@ let syncFreshmen = () => {
$('#sync-freshmen-modal').modal('hide');
location.reload();
} else {
alert("There was an syncing freshmen")
alert("There was an error syncing freshmen")
}
})
}
Expand All @@ -129,3 +137,22 @@ let syncFreshmen = () => {
}
}
}

let syncLdap = () => {
$("#sync-ldap").append("&nbsp;<span class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\"></span>");
$("#sync-ldap").attr('disabled', true);
fetch('/api/v1/sync',
{
method: 'POST',
headers: {
'Content-Type': 'application/json'
}
}
).then(response => {
if (response.status < 300) {
location.reload();
} else {
alert("There was an error syncing with ldap")
}
})
}
3 changes: 3 additions & 0 deletions packet/templates/admin_packets.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ <h4 class="page-title">Active Packets</h4>
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#new-packets-modal">
Create new Packets
</button>
<button type="button" id="sync-ldap" class="btn btn-primary">
Sync with LDAP
</button>
{% include 'include/admin/new_packets.html' %}
</div>
</div>
Expand Down
16 changes: 8 additions & 8 deletions packet/templates/packet.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,18 +20,18 @@ <h3>{{ get_rit_name(packet.freshman_username) }}</h3>
class="fa fa-check"></i>&nbsp;Signed
</button>
{% endif %}
{% if info.realm == "csh" %}
<div class="col">
<a class="btn btn-primary" style="float: right"
href="{{ url_for('packet_graphs', packet_id=packet.id) }}">Graphs</a>
</div>
{% endif %}
</div>
</div>
<div class="row w-100 mb-1">
{% if info.realm == "csh" %}
<div class="col">
<a class="btn btn-primary" style="float: right" href="{{ url_for('packet_graphs', packet_id=packet.id) }}">Graphs</a>
</div>
{% endif %}
</div>
<div class="row">
<div class="col ml-1 mb-1">
<h6>Signatures: <span class="badge badge-secondary">{{ received.total }}/{{ required.total }}</span></h6>
<h6>Signatures: <span class="badge badge-secondary">{{ received.total }}/{{ required.total }}</span>
</h6>
</div>
<div class="col mr-1 mb-1">
<h6 class="right-align">Ends: <span class="badge badge-secondary">{{ packet_end }}</span></h6>
Expand Down
Loading