Skip to content
Open
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
1 change: 1 addition & 0 deletions conditional/blueprints/dashboard.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ def display_dashboard(user_dict=None):
log.info('display dashboard')

# Get the list of voting members.

can_vote = get_voting_members()

data = {}
Expand Down
122 changes: 74 additions & 48 deletions conditional/blueprints/spring_evals.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import structlog
from flask import Blueprint, request
from sqlalchemy import func

from conditional import db, start_of_year, auth
from conditional.models.models import HouseMeeting
from conditional.models.models import MajorProject
from conditional.models.models import MemberHouseMeetingAttendance
from conditional.models.models import SpringEval
from conditional.models.models import CommitteeMeeting, HouseMeeting, MemberCommitteeAttendance
from conditional.models.models import MajorProject, MemberHouseMeetingAttendance, SpringEval
from conditional.util.auth import get_user
from conditional.util.flask import render_template
from conditional.util.ldap import ldap_get_active_members
from conditional.util.member import get_cm, get_hm, req_cm
from conditional.util.member import req_cm

spring_evals_bp = Blueprint('spring_evals_bp', __name__)

Expand All @@ -25,6 +24,52 @@ def display_spring_evals(internal=False, user_dict=None):

active_members = ldap_get_active_members()

cm_count = dict([tuple(row) for row in MemberCommitteeAttendance.query.join(
CommitteeMeeting,
MemberCommitteeAttendance.meeting_id == CommitteeMeeting.id
).with_entities(
MemberCommitteeAttendance.uid,
CommitteeMeeting.timestamp,
CommitteeMeeting.approved,
).filter(
CommitteeMeeting.approved,
CommitteeMeeting.timestamp >= start_of_year()
).with_entities(
MemberCommitteeAttendance.uid,
func.count(MemberCommitteeAttendance.uid) #pylint: disable=not-callable
).group_by(
MemberCommitteeAttendance.uid
).all()])

hm_missed = dict([tuple(row) for row in MemberHouseMeetingAttendance.query.join(
HouseMeeting,
MemberHouseMeetingAttendance.meeting_id == HouseMeeting.id
).filter(
HouseMeeting.date >= start_of_year(),
MemberHouseMeetingAttendance.attendance_status == 'Absent'
).with_entities(
MemberHouseMeetingAttendance.uid,
func.count(MemberHouseMeetingAttendance.uid) #pylint: disable=not-callable
).group_by(
MemberHouseMeetingAttendance.uid
).all()])

major_project_query = MajorProject.query.filter(
MajorProject.date >= start_of_year()
).all()

major_projects = {}

for project in major_project_query:
if not project.uid in major_projects:
major_projects[project.uid] = []

major_projects.get(project.uid).append({
'name': project.name,
'status': project.status,
'description': project.description
})

sp_members = []
for account in active_members:
uid = account.uid
Expand All @@ -38,64 +83,45 @@ def display_spring_evals(internal=False, user_dict=None):
db.session.add(spring_entry)
db.session.flush()
db.session.commit()
elif spring_entry.status != "Pending" and internal:
elif spring_entry.status != 'Pending' and internal:
continue

eval_data = None
member_missed_hms = []

if hm_missed.get(uid, 0) != 0:
member_missed_hms = MemberHouseMeetingAttendance.query.join(
HouseMeeting,
MemberHouseMeetingAttendance.meeting_id == HouseMeeting.id
).filter(
HouseMeeting.date >= start_of_year(),
MemberHouseMeetingAttendance.attendance_status == 'Absent',
MemberHouseMeetingAttendance.uid == uid,
).with_entities(
func.array_agg(HouseMeeting.date)
).scalar()

h_meetings = [m.meeting_id for m in get_hm(account, only_absent=True)]
member = {
'name': account.cn,
'uid': uid,
'status': spring_entry.status,
'committee_meetings': len(get_cm(account)),
'committee_meetings': cm_count.get(uid, 0),
'req_meetings': req_cm(account),
'house_meetings_missed':
[
{
"date": m.date.strftime("%Y-%m-%d"),
"reason":
MemberHouseMeetingAttendance.query.filter(
MemberHouseMeetingAttendance.uid == uid).filter(
MemberHouseMeetingAttendance.meeting_id == m.id).first().excuse
}
for m in HouseMeeting.query.filter(
HouseMeeting.id.in_(h_meetings)
)
],
'major_projects': [
{
'name': p.name,
'status': p.status,
'description': p.description
} for p in MajorProject.query.filter(
MajorProject.date > start_of_year(),
MajorProject.uid == uid)]
'house_meetings_missed': member_missed_hms,
'major_projects': major_projects.get(uid, [])
}

passed_mps = [project for project in member['major_projects'] if project['status'] == 'Passed']

member['major_projects_len'] = len(member['major_projects'])
member['major_projects_passed'] = [
{
'name': p.name,
'status': p.status,
'description': p.description
} for p in MajorProject.query.filter(
MajorProject.date > start_of_year(),
MajorProject.status == "Passed",
MajorProject.uid == uid)]
member['major_projects_passed'] = passed_mps
member['major_projects_passed_len'] = len(member['major_projects_passed'])
member['major_project_passed'] = False
for mp in member['major_projects']:
if mp['status'] == "Passed":
member['major_project_passed'] = True
break

if internal:
member['housing_evals'] = eval_data
member['major_project_passed'] = member['major_projects_passed_len'] > 0

sp_members.append(member)

sp_members.sort(key=lambda x: x['committee_meetings'], reverse=True)
sp_members.sort(key=lambda x: len(x['house_meetings_missed']))
sp_members.sort(key=lambda x: len([p for p in x['major_projects'] if p['status'] == "Passed"]), reverse=True)
sp_members.sort(key=lambda x: x['major_projects_passed_len'], reverse=True)
# return names in 'first last (username)' format
if internal:
return sp_members
Expand Down
4 changes: 2 additions & 2 deletions conditional/templates/spring_evals.html
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ <h4>Missed House Meetings</h4>
<tbody>
{% for hm_missed in m['house_meetings_missed'] %}
<tr>
<td>{{hm_missed['date']}}</td>
<td>{{hm_missed['reason']}}</td>
<td>{{hm_missed}}</td>
<td></td>
</tr>
{% endfor %}
</tbody>
Expand Down
47 changes: 28 additions & 19 deletions conditional/util/housing.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

from conditional.models.models import InHousingQueue
from conditional.models.models import OnFloorStatusAssigned
from conditional.util.ldap import ldap_get_current_students
from conditional.util.ldap import ldap_is_onfloor
from conditional.util.ldap import ldap_get_member, ldap_is_current_student


def get_housing_queue(is_eval_director=False):
Expand All @@ -12,23 +11,34 @@ def get_housing_queue(is_eval_director=False):
# and {'time': <datetime obj>} is the value. We are doing a left
# outer join on the two tables to get a single result that has
# both the member's UID and their on-floor datetime.
in_queue = {entry.uid: {'time': entry.onfloor_granted} for entry
in InHousingQueue.query.outerjoin(OnFloorStatusAssigned,
OnFloorStatusAssigned.uid == InHousingQueue.uid)\
.with_entities(InHousingQueue.uid, OnFloorStatusAssigned.onfloor_granted)\
.all()}
in_queue = {
entry.uid: {
'time': entry.onfloor_granted
} for entry in InHousingQueue.query.outerjoin(
OnFloorStatusAssigned,
OnFloorStatusAssigned.uid == InHousingQueue.uid
).with_entities(
InHousingQueue.uid,
OnFloorStatusAssigned.onfloor_granted
).all()
}

# CSHMember accounts that are in queue
potential_accounts = [ldap_get_member(username) for username in in_queue]

# Populate a list of dictionaries containing the name, username,
# and on-floor datetime for each member who has on-floor status,
# is not already assigned to a room and is in the above query.
queue = [{"uid": account.uid,
"name": account.cn,
"points": account.housingPoints,
"time": in_queue.get(account.uid, {}).get('time', datetime.now()) or datetime.now(),
"in_queue": account.uid in in_queue}
for account in ldap_get_current_students()
if ldap_is_onfloor(account) and (is_eval_director or account.uid in in_queue)
and account.roomNumber is None]
# and on-floor datetime for each current studetn who has on-floor status
# and is not already assigned to a room
queue = [
{
"uid": account.uid,
"name": account.cn,
"points": account.housingPoints,
"time": in_queue.get(account.uid, {}).get('time', datetime.now()) or datetime.now(),
"in_queue": account.uid in in_queue
} for account in potential_accounts
if ldap_is_current_student(account) and (is_eval_director or account.roomNumber is None)
]

# Sort based on time (ascending) and then points (decending).
queue.sort(key=lambda m: m['time'])
Expand All @@ -40,8 +50,7 @@ def get_housing_queue(is_eval_director=False):
def get_queue_position(username):
queue = get_housing_queue()
try:
index = next(index for (index, d) in enumerate(get_housing_queue())
if d["uid"] == username) + 1
index = next(index for (index, d) in enumerate(queue) if d["uid"] == username) + 1
except (KeyError, StopIteration):
index = None
return index, len(queue)
Loading