Skip to content

Commit 176d31a

Browse files
committed
Initial Admin UI
1 parent 6e1265e commit 176d31a

File tree

15 files changed

+295
-4
lines changed

15 files changed

+295
-4
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ ENV/
103103
# JetBrains
104104
.idea/
105105

106+
# vscode
107+
.vscode
108+
106109
# Configurations
107110
config.py
108111

packet/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080

8181
if app.config['REALM'] == 'csh':
8282
from .routes import upperclassmen
83+
from .routes import admin
8384
else:
8485
from .routes import freshmen
8586

packet/context_processors.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@ def get_roles(sig):
4343

4444

4545
# pylint: disable=bare-except
46-
@lru_cache(maxsize=128)
46+
@lru_cache(maxsize=256)
4747
def get_rit_name(username):
4848
try:
4949
freshman = Freshman.query.filter_by(rit_username=username).first()
@@ -53,7 +53,7 @@ def get_rit_name(username):
5353

5454

5555
# pylint: disable=bare-except
56-
@lru_cache(maxsize=128)
56+
@lru_cache(maxsize=256)
5757
def get_rit_image(username):
5858
if username:
5959
addresses = [username + '@rit.edu', username + '@g.rit.edu']

packet/ldap.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,14 @@ def ldap_is_eboard(member):
158158
return _ldap_is_member_of_group(member, 'eboard')
159159

160160

161+
def ldap_is_evals(member):
162+
return _ldap_is_member_of_group(member, 'eboard-evaluations')
163+
164+
165+
def ldap_is_rtp(member):
166+
return _ldap_is_member_of_group(member, 'rtp')
167+
168+
161169
def ldap_is_intromember(member):
162170
"""
163171
:param member: A CSHMember instance

packet/models.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ def by_username(cls, username: str):
4949
"""
5050
return cls.query.filter_by(rit_username=username).first()
5151

52+
@classmethod
53+
def get_all(cls):
54+
"""
55+
Helper method to get all freshmen easily
56+
"""
57+
return cls.query.all()
58+
5259

5360
class Packet(db.Model):
5461
__tablename__ = 'packet'

packet/routes/admin.py

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import csv
2+
import os
3+
4+
import requests
5+
from flask import render_template, redirect, request
6+
from werkzeug.utils import secure_filename
7+
8+
from packet import app
9+
from packet.models import Packet, Freshman
10+
from packet.routes.shared import packet_sort_key
11+
from packet.utils import before_request, packet_auth, admin_auth
12+
from packet.log_utils import log_cache, log_time
13+
14+
15+
@app.route('/admin/')
16+
@log_cache
17+
@packet_auth
18+
@admin_auth
19+
@before_request
20+
@log_time
21+
def admin(info=None):
22+
open_packets = Packet.open_packets()
23+
24+
# Pre-calculate and store the return values of did_sign(), signatures_received(), and signatures_required()
25+
for packet in open_packets:
26+
packet.did_sign_result = packet.did_sign(info['uid'], app.config['REALM'] == 'csh')
27+
packet.signatures_received_result = packet.signatures_received()
28+
packet.signatures_required_result = packet.signatures_required()
29+
30+
open_packets.sort(key=packet_sort_key, reverse=True)
31+
32+
all_freshmen = Freshman.get_all()
33+
34+
return render_template('admin.html',
35+
open_packets=open_packets,
36+
all_freshmen=all_freshmen,
37+
info=info)

packet/routes/api.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
from packet.ldap import ldap_get_eboard_role, ldap_get_active_rtps, ldap_get_3das, ldap_get_webmasters, \
1313
ldap_get_drink_admins, ldap_get_constitutional_maintainers, ldap_is_intromember, ldap_get_active_members, \
1414
ldap_is_on_coop, _ldap_is_member_of_group, ldap_get_member
15+
from packet.log_utils import log_time
1516
from packet.mail import send_report_mail, send_start_packet_mail
1617
from packet.utils import before_request, packet_auth, notify_slack
1718
from packet.models import Packet, MiscSignature, NotificationSubscription, Freshman, FreshSignature, UpperSignature
@@ -80,6 +81,7 @@ def sync_freshman():
8081

8182
@app.route('/api/v1/packets', methods=['POST'])
8283
@packet_auth
84+
@log_time
8385
def create_packet():
8486
"""
8587
Create a new packet.

packet/routes/shared.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
@app.route('/logout/')
1414
@auth.oidc_logout
1515
def logout():
16-
return redirect('http://csh.rit.edu')
16+
return redirect('https://csh.rit.edu')
1717

1818

1919
@app.route('/packet/<packet_id>/')

packet/static/js/admin.js

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
$(document).ready(function () {
2+
3+
let openPacketsTable = $('#open_packets_table');
4+
openPacketsTable.DataTable({
5+
"searching": true,
6+
"order": [],
7+
"scrollX": false,
8+
"paging": true,
9+
"info": false,
10+
"columnDefs": [
11+
{
12+
"targets": 0,
13+
"max-width": "50%",
14+
},
15+
{
16+
"type": "num-fmt",
17+
"targets": 1,
18+
"visible": true,
19+
"max-width": "15%",
20+
}
21+
]
22+
});
23+
24+
let allFreshmenTable = $('#all_freshmen_table');
25+
allFreshmenTable.DataTable({
26+
"searching": true,
27+
"order": [],
28+
"scrollX": false,
29+
"paging": true,
30+
"info": false,
31+
});
32+
33+
$("#create-packets").click(() => {
34+
makePackets();
35+
});
36+
37+
});
38+
39+
let makePackets = () => {
40+
let freshmen = [];
41+
let fileUpload = document.getElementById("newPacketsFile");
42+
let regex = /^([a-zA-Z0-9\s_\\.\-:])+(.csv|.txt)$/;
43+
if (regex.test(fileUpload.value.toLowerCase())) {
44+
if (typeof (FileReader) != "undefined") {
45+
let reader = new FileReader();
46+
reader.onload = (e) => {
47+
let rows = e.target.result.split("\n");
48+
for (let i = 0; i < rows.length; i++) {
49+
let cells = rows[i].split(",");
50+
if (cells.length > 1) {
51+
freshmen.push(cells[3]);
52+
}
53+
}
54+
const payload = {start_date: $('#packet-start-date').val(), freshmen: freshmen}
55+
if (freshmen.length >= 1) {
56+
$("#create-packets").append("&nbsp;<span class=\"spinner-border spinner-border-sm\" role=\"status\" aria-hidden=\"true\"></span>");
57+
$("#create-packets").attr('disabled', true);
58+
fetch('/api/v1/packets',
59+
{
60+
method: 'POST',
61+
headers: {
62+
'Content-Type': 'application/json'
63+
},
64+
body: JSON.stringify(payload)
65+
}
66+
).then(response => {
67+
if (response.status < 300) {
68+
$('#new-packets-modal').modal('hide');
69+
location.reload();
70+
} else {
71+
alert("There was an error creating packets")
72+
}
73+
})
74+
}
75+
}
76+
reader.readAsText(fileUpload.files[0]);
77+
}
78+
}
79+
}

packet/templates/admin.html

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{% extends "extend/base.html" %}
2+
3+
{% block body %}
4+
<div class="container main">
5+
<div class="ml-4">
6+
<div class="row justify-content-between w-100">
7+
<div class="col-xs-10">
8+
<h4 class="page-title">Active Packets</h4>
9+
</div>
10+
<div class="col-xs-2">
11+
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#new-packets-modal">
12+
Create new Packets
13+
</button>
14+
{% include 'include/admin/new_packets.html' %}
15+
</div>
16+
</div>
17+
</div>
18+
<div id="eval-blocks">
19+
{% include 'include/admin/open_packets.html' %}
20+
</div>
21+
{# <div class="ml-4">#}
22+
{# <div class="row justify-content-between w-100">#}
23+
{# <div class="col-xs-10">#}
24+
{# <h4 class="page-title">All Freshmen</h4>#}
25+
{# </div>#}
26+
{# </div>#}
27+
{# </div>#}
28+
{# <div id="eval-blocks">#}
29+
{# {% include 'include/admin/all_freshmen.html' %}#}
30+
{# </div>#}
31+
</div>
32+
{% endblock %}
33+
34+
{% block scripts %}
35+
{{ super() }}
36+
<script src="{{ url_for('static', filename='js/admin.js') }}"></script>
37+
{% endblock %}

0 commit comments

Comments
 (0)