Skip to content

Commit da53e55

Browse files
authored
Merge pull request #207 from devinmatte/admin_ui_fixes
2 parents b562c5e + 84fa5d5 commit da53e55

File tree

6 files changed

+181
-174
lines changed

6 files changed

+181
-174
lines changed

packet/commands.py

Lines changed: 5 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,13 @@
55
import sys
66

77
from secrets import token_hex
8-
from datetime import datetime, time, timedelta
8+
from datetime import datetime, time
99
import csv
1010
import click
1111

12-
from packet.mail import send_start_packet_mail
13-
from packet.notifications import packet_starting_notification, packets_starting_notification
1412
from . import app, db
15-
from .models import Freshman, Packet, FreshSignature, UpperSignature, MiscSignature
16-
from .ldap import ldap_get_eboard_role, ldap_get_active_rtps, ldap_get_3das, ldap_get_webmasters, \
17-
ldap_get_drink_admins, ldap_get_constitutional_maintainers, ldap_is_intromember, ldap_get_active_members, \
18-
ldap_is_on_coop
19-
from .utils import sync_freshman
13+
from .models import Packet, FreshSignature, UpperSignature, MiscSignature
14+
from .utils import sync_freshman, create_new_packets, sync_with_ldap
2015

2116

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

8479
# Collect the necessary data
8580
base_date = input_date('Input the first day of packet season')
86-
start = datetime.combine(base_date, packet_start_time)
87-
end = datetime.combine(base_date, packet_end_time) + timedelta(days=14)
88-
89-
print('Fetching data from LDAP...')
90-
all_upper = list(filter(
91-
lambda member: not ldap_is_intromember(member) and not ldap_is_on_coop(member), ldap_get_active_members()))
92-
93-
rtp = ldap_get_active_rtps()
94-
three_da = ldap_get_3das()
95-
webmaster = ldap_get_webmasters()
96-
c_m = ldap_get_constitutional_maintainers()
97-
drink = ldap_get_drink_admins()
98-
99-
# Packet starting notifications
100-
packets_starting_notification(start)
101-
102-
# Create the new packets and the signatures for each freshman in the given CSV
10381
freshmen_in_csv = parse_csv(freshmen_csv)
104-
print('Creating DB entries and sending emails...')
105-
for freshman in Freshman.query.filter(Freshman.rit_username.in_(freshmen_in_csv)).all():
106-
packet = Packet(freshman=freshman, start=start, end=end)
107-
db.session.add(packet)
108-
send_start_packet_mail(packet)
109-
packet_starting_notification(packet)
110-
111-
for member in all_upper:
112-
sig = UpperSignature(packet=packet, member=member.uid)
113-
sig.eboard = ldap_get_eboard_role(member)
114-
sig.active_rtp = member.uid in rtp
115-
sig.three_da = member.uid in three_da
116-
sig.webmaster = member.uid in webmaster
117-
sig.c_m = member.uid in c_m
118-
sig.drink_admin = member.uid in drink
119-
db.session.add(sig)
120-
121-
for onfloor_freshman in Freshman.query.filter_by(onfloor=True).filter(Freshman.rit_username !=
122-
freshman.rit_username).all():
123-
db.session.add(FreshSignature(packet=packet, freshman=onfloor_freshman))
124-
125-
db.session.commit()
82+
create_new_packets(base_date, freshmen_in_csv)
12683
print('Done!')
12784

12885

@@ -131,60 +88,7 @@ def ldap_sync():
13188
"""
13289
Updates the upper and misc sigs in the DB to match ldap.
13390
"""
134-
print('Fetching data from LDAP...')
135-
all_upper = {member.uid: member for member in filter(
136-
lambda member: not ldap_is_intromember(member) and not ldap_is_on_coop(member), ldap_get_active_members())}
137-
138-
rtp = ldap_get_active_rtps()
139-
three_da = ldap_get_3das()
140-
webmaster = ldap_get_webmasters()
141-
c_m = ldap_get_constitutional_maintainers()
142-
drink = ldap_get_drink_admins()
143-
144-
print('Applying updates to the DB...')
145-
for packet in Packet.query.filter(Packet.end > datetime.now()).all():
146-
# Update the role state of all UpperSignatures
147-
for sig in filter(lambda sig: sig.member in all_upper, packet.upper_signatures):
148-
sig.eboard = ldap_get_eboard_role(all_upper[sig.member])
149-
sig.active_rtp = sig.member in rtp
150-
sig.three_da = sig.member in three_da
151-
sig.webmaster = sig.member in webmaster
152-
sig.c_m = sig.member in c_m
153-
sig.drink_admin = sig.member in drink
154-
155-
# Migrate UpperSignatures that are from accounts that are not active anymore
156-
for sig in filter(lambda sig: sig.member not in all_upper, packet.upper_signatures):
157-
UpperSignature.query.filter_by(packet_id=packet.id, member=sig.member).delete()
158-
if sig.signed:
159-
sig = MiscSignature(packet=packet, member=sig.member)
160-
db.session.add(sig)
161-
162-
# Migrate MiscSignatures that are from accounts that are now active members
163-
for sig in filter(lambda sig: sig.member in all_upper, packet.misc_signatures):
164-
MiscSignature.query.filter_by(packet_id=packet.id, member=sig.member).delete()
165-
sig = UpperSignature(packet=packet, member=sig.member, signed=True)
166-
sig.eboard = ldap_get_eboard_role(all_upper[sig.member])
167-
sig.active_rtp = sig.member in rtp
168-
sig.three_da = sig.member in three_da
169-
sig.webmaster = sig.member in webmaster
170-
sig.c_m = sig.member in c_m
171-
sig.drink_admin = sig.member in drink
172-
db.session.add(sig)
173-
174-
# Create UpperSignatures for any new active members
175-
# pylint: disable=cell-var-from-loop
176-
upper_sigs = set(map(lambda sig: sig.member, packet.upper_signatures))
177-
for member in filter(lambda member: member not in upper_sigs, all_upper):
178-
sig = UpperSignature(packet=packet, member=member)
179-
sig.eboard = ldap_get_eboard_role(all_upper[sig.member])
180-
sig.active_rtp = sig.member in rtp
181-
sig.three_da = sig.member in three_da
182-
sig.webmaster = sig.member in webmaster
183-
sig.c_m = sig.member in c_m
184-
sig.drink_admin = sig.member in drink
185-
db.session.add(sig)
186-
187-
db.session.commit()
91+
sync_with_ldap()
18892
print('Done!')
18993

19094

packet/routes/api.py

Lines changed: 27 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,20 @@
11
"""
22
Shared API endpoints
33
"""
4-
from datetime import datetime, timedelta
4+
from datetime import datetime
55
from json import dumps
66

77
from flask import session, request
88

99
from packet import app, db
1010
from packet.context_processors import get_rit_name
11-
from packet.commands import packet_start_time, packet_end_time
12-
from packet.ldap import ldap_get_eboard_role, ldap_get_active_rtps, ldap_get_3das, ldap_get_webmasters, \
13-
ldap_get_drink_admins, ldap_get_constitutional_maintainers, ldap_is_intromember, ldap_get_active_members, \
14-
ldap_is_on_coop, _ldap_is_member_of_group, ldap_get_member
11+
from packet.ldap import _ldap_is_member_of_group, ldap_get_member
1512
from packet.log_utils import log_time
16-
from packet.mail import send_report_mail, send_start_packet_mail
17-
from packet.utils import before_request, packet_auth, notify_slack, sync_freshman as sync_freshman_list
18-
from packet.models import Packet, MiscSignature, NotificationSubscription, Freshman, FreshSignature, UpperSignature
19-
from packet.notifications import packet_signed_notification, packet_100_percent_notification, \
20-
packet_starting_notification, packets_starting_notification
13+
from packet.mail import send_report_mail
14+
from packet.utils import before_request, packet_auth, notify_slack, sync_freshman as sync_freshman_list, \
15+
create_new_packets, sync_with_ldap
16+
from packet.models import Packet, MiscSignature, NotificationSubscription, Freshman
17+
from packet.notifications import packet_signed_notification, packet_100_percent_notification
2118
import packet.stats as stats
2219

2320

@@ -63,7 +60,11 @@ def create_packet():
6360
Body parameters: {
6461
start_date: the start date of the packets in MM/DD/YYYY format
6562
freshmen: [
66-
rit_username: string
63+
{
64+
rit_username: string
65+
name: string
66+
onfloor: boolean
67+
}
6768
]
6869
}
6970
"""
@@ -75,56 +76,23 @@ def create_packet():
7576

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

78-
start = datetime.combine(base_date, packet_start_time)
79-
end = datetime.combine(base_date, packet_end_time) + timedelta(days=14)
80-
81-
frosh = request.json['freshmen']
82-
results = list()
83-
84-
# Gather upperclassmen data from LDAP
85-
all_upper = list(filter(
86-
lambda member: not ldap_is_intromember(member) and not ldap_is_on_coop(member), ldap_get_active_members()))
87-
88-
rtp = ldap_get_active_rtps()
89-
three_da = ldap_get_3das()
90-
webmaster = ldap_get_webmasters()
91-
c_m = ldap_get_constitutional_maintainers()
92-
drink = ldap_get_drink_admins()
93-
94-
# Packet starting notifications
95-
packets_starting_notification(start)
96-
97-
for frosh_rit_username in frosh:
98-
# Create the packet and signatures
99-
freshman = Freshman.query.filter_by(rit_username=frosh_rit_username).first()
100-
if freshman is None:
101-
results.append(f"Freshman '{frosh_rit_username}' not found")
102-
continue
103-
104-
packet = Packet(freshman=freshman, start=start, end=end)
105-
db.session.add(packet)
106-
send_start_packet_mail(packet)
107-
packet_starting_notification(packet)
108-
109-
for member in all_upper:
110-
sig = UpperSignature(packet=packet, member=member.uid)
111-
sig.eboard = ldap_get_eboard_role(member)
112-
sig.active_rtp = member.uid in rtp
113-
sig.three_da = member.uid in three_da
114-
sig.webmaster = member.uid in webmaster
115-
sig.c_m = member.uid in c_m
116-
sig.drink_admin = member.uid in drink
117-
db.session.add(sig)
118-
119-
for onfloor_freshman in Freshman.query.filter_by(onfloor=True).filter(Freshman.rit_username !=
120-
freshman.rit_username).all():
121-
db.session.add(FreshSignature(packet=packet, freshman=onfloor_freshman))
122-
123-
results.append(f'Packet created for {frosh_rit_username}')
79+
freshmen_in_post = {freshman.rit_username: freshman for freshman in map(POSTFreshman, request.json['freshmen'])}
80+
81+
create_new_packets(base_date, freshmen_in_post)
82+
83+
return dumps('Done'), 201
12484

125-
db.session.commit()
12685

127-
return dumps(results), 201
86+
@app.route('/api/v1/sync', methods=['POST'])
87+
@packet_auth
88+
@log_time
89+
def sync_ldap():
90+
# Only allow evals to sync ldap
91+
username = str(session['userinfo'].get('preferred_username', ''))
92+
if not _ldap_is_member_of_group(ldap_get_member(username), 'eboard-evaluations'):
93+
return 'Forbidden: not Evaluations Director', 403
94+
sync_with_ldap()
95+
return dumps('Done'), 201
12896

12997

13098
@app.route('/api/v1/packets/<username>', methods=['GET'])

packet/static/js/admin.js

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ $(document).ready(function () {
3838
syncFreshmen();
3939
})
4040

41+
$("#sync-ldap").click(() => {
42+
syncLdap();
43+
})
44+
4145
});
4246

4347
// Is this gross, yes. Do I feel like cleaning it up yet, no.
@@ -54,7 +58,11 @@ let makePackets = () => {
5458
for (let i = 0; i < rows.length; i++) {
5559
let cells = rows[i].split(",");
5660
if (cells.length > 1) {
57-
freshmen.push(cells[3]);
61+
freshmen.push({
62+
rit_username: cells[3],
63+
name: cells[0],
64+
onfloor: cells[1]
65+
});
5866
}
5967
}
6068
const payload = {start_date: $('#packet-start-date').val(), freshmen: freshmen}
@@ -120,7 +128,7 @@ let syncFreshmen = () => {
120128
$('#sync-freshmen-modal').modal('hide');
121129
location.reload();
122130
} else {
123-
alert("There was an syncing freshmen")
131+
alert("There was an error syncing freshmen")
124132
}
125133
})
126134
}
@@ -129,3 +137,22 @@ let syncFreshmen = () => {
129137
}
130138
}
131139
}
140+
141+
let syncLdap = () => {
142+
$("#sync-ldap").append("&nbsp;<span class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\"></span>");
143+
$("#sync-ldap").attr('disabled', true);
144+
fetch('/api/v1/sync',
145+
{
146+
method: 'POST',
147+
headers: {
148+
'Content-Type': 'application/json'
149+
}
150+
}
151+
).then(response => {
152+
if (response.status < 300) {
153+
location.reload();
154+
} else {
155+
alert("There was an error syncing with ldap")
156+
}
157+
})
158+
}

packet/templates/admin_packets.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@ <h4 class="page-title">Active Packets</h4>
1111
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#new-packets-modal">
1212
Create new Packets
1313
</button>
14+
<button type="button" id="sync-ldap" class="btn btn-primary">
15+
Sync with LDAP
16+
</button>
1417
{% include 'include/admin/new_packets.html' %}
1518
</div>
1619
</div>

packet/templates/packet.html

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,18 @@ <h3>{{ get_rit_name(packet.freshman_username) }}</h3>
2020
class="fa fa-check"></i>&nbsp;Signed
2121
</button>
2222
{% endif %}
23+
{% if info.realm == "csh" %}
24+
<div class="col">
25+
<a class="btn btn-primary" style="float: right"
26+
href="{{ url_for('packet_graphs', packet_id=packet.id) }}">Graphs</a>
27+
</div>
28+
{% endif %}
2329
</div>
2430
</div>
25-
<div class="row w-100 mb-1">
26-
{% if info.realm == "csh" %}
27-
<div class="col">
28-
<a class="btn btn-primary" style="float: right" href="{{ url_for('packet_graphs', packet_id=packet.id) }}">Graphs</a>
29-
</div>
30-
{% endif %}
31-
</div>
3231
<div class="row">
3332
<div class="col ml-1 mb-1">
34-
<h6>Signatures: <span class="badge badge-secondary">{{ received.total }}/{{ required.total }}</span></h6>
33+
<h6>Signatures: <span class="badge badge-secondary">{{ received.total }}/{{ required.total }}</span>
34+
</h6>
3535
</div>
3636
<div class="col mr-1 mb-1">
3737
<h6 class="right-align">Ends: <span class="badge badge-secondary">{{ packet_end }}</span></h6>

0 commit comments

Comments
 (0)