diff --git a/conditional/__init__.py b/conditional/__init__.py index 1df474e..83c02a6 100644 --- a/conditional/__init__.py +++ b/conditional/__init__.py @@ -108,7 +108,7 @@ def database_processor(logger, log_method, event_dict): # pylint: disable=unuse # pylint: disable=wrong-import-order from conditional.util import context_processors from conditional.util.auth import get_user -from conditional.util.member import gatekeep_status +from conditional.util.member import gatekeep_status, get_voting_members from .blueprints.dashboard import dashboard_bp # pylint: disable=ungrouped-imports from .blueprints.attendance import attendance_bp from .blueprints.major_project_submission import major_project_bp @@ -167,7 +167,7 @@ def health(): @app.route("/gatekeep/") -def gatekeep(username): +def gatekeep_user(username): token = request.headers.get("X-VOTE-TOKEN", "") if token != app.config["VOTE_TOKEN"]: return "Users cannot access this page", 403 @@ -178,6 +178,13 @@ def gatekeep(username): return gatekeep_data, 200 +@app.route("/gatekeep") +def gatekeep_all(): + token = request.headers.get("X-VOTE-TOKEN", "") + if token != app.config["VOTE_TOKEN"]: + return "Users cannot access this page", 403 + return list(get_voting_members()), 200 + @app.errorhandler(404) @app.errorhandler(500) diff --git a/conditional/util/member.py b/conditional/util/member.py index 8dc3d69..b485d19 100644 --- a/conditional/util/member.py +++ b/conditional/util/member.py @@ -2,7 +2,7 @@ from sqlalchemy import func, or_ from conditional import start_of_year -from conditional.models.models import CommitteeMeeting +from conditional.models.models import CommitteeMeeting, FreshmanAccount from conditional.models.models import CurrentCoops from conditional.models.models import FreshmanEvalData from conditional.models.models import HouseMeeting @@ -21,6 +21,7 @@ from conditional.util.ldap import ldap_is_intromember from conditional.util.ldap import ldap_get_member + @service_cache(maxsize=1024) def get_members_info(): members = ldap_get_current_students() @@ -57,18 +58,18 @@ def get_freshman_data(user_name): MemberCommitteeAttendance.query.filter( MemberCommitteeAttendance.uid == user_name ) if CommitteeMeeting.query.filter( - CommitteeMeeting.id == m.meeting_id).first().approved] + CommitteeMeeting.id == m.meeting_id).first().approved] freshman['committee_meetings'] = len(c_meetings) # technical seminar total t_seminars = [s.seminar_id for s in MemberSeminarAttendance.query.filter( MemberSeminarAttendance.uid == user_name ) if TechnicalSeminar.query.filter( - TechnicalSeminar.id == s.seminar_id).first().approved] + TechnicalSeminar.id == s.seminar_id).first().approved] freshman['ts_total'] = len(t_seminars) attendance = [m.name for m in TechnicalSeminar.query.filter( TechnicalSeminar.id.in_(t_seminars) - )] + )] freshman['ts_list'] = attendance @@ -114,20 +115,20 @@ def get_cm(member): def get_hm(member, only_absent=False): h_meetings = MemberHouseMeetingAttendance.query.outerjoin( - HouseMeeting, - MemberHouseMeetingAttendance.meeting_id == HouseMeeting.id).with_entities( - MemberHouseMeetingAttendance.meeting_id, - MemberHouseMeetingAttendance.attendance_status, - HouseMeeting.date).filter( - HouseMeeting.date > start_of_year(), - MemberHouseMeetingAttendance.uid == member.uid) + HouseMeeting, + MemberHouseMeetingAttendance.meeting_id == HouseMeeting.id).with_entities( + MemberHouseMeetingAttendance.meeting_id, + MemberHouseMeetingAttendance.attendance_status, + HouseMeeting.date).filter( + HouseMeeting.date > start_of_year(), + MemberHouseMeetingAttendance.uid == member.uid) if only_absent: h_meetings = h_meetings.filter(MemberHouseMeetingAttendance.attendance_status == "Absent") return h_meetings # @service_cache(maxsize=128) -def req_cm(uid, members_on_coop = None): +def req_cm(uid, members_on_coop=None): # Get the number of required committee meetings based on if the member # is going on co-op in the current operating session. on_coop = False @@ -143,14 +144,16 @@ def req_cm(uid, members_on_coop = None): return 15 return 30 + @service_cache(maxsize=256) def get_voting_members(): - if datetime.today() < datetime(start_of_year().year, 12, 31): + today = datetime.today() + if today < datetime(start_of_year().year, 12, 31): semester = "Fall" - semester_start = datetime(start_of_year().year,6,1) + semester_start = datetime(start_of_year().year, 6, 1) else: semester = "Spring" - semester_start = datetime(start_of_year().year + 1,1,1) + semester_start = datetime(start_of_year().year + 1, 1, 1) active_members = set(ldap_get_active_members()) intro_members = set(ldap_get_intro_members()) @@ -169,8 +172,8 @@ def get_voting_members(): coop_members = set(coop_members) passed_fall_members = FreshmanEvalData.query.filter( - FreshmanEvalData.freshman_eval_result == "Passed", - FreshmanEvalData.eval_date > start_of_year(), + FreshmanEvalData.freshman_eval_result == "Passed", + FreshmanEvalData.eval_date > start_of_year(), ).with_entities( func.array_agg(FreshmanEvalData.uid) ).scalar() @@ -185,6 +188,12 @@ def get_voting_members(): elligible_members = (active_not_intro - coop_members) | passed_fall_members + # Check to see if there's an Intro Evals in the future of this semester. If there is, everyone gets to vote! + before_evals_one = len(FreshmanAccount.query.filter(FreshmanAccount.eval_date > today).limit(1).all()) + before_evals_two = len(FreshmanEvalData.query.filter(FreshmanEvalData.eval_date > today).limit(1).all()) + if before_evals_one > 0 or before_evals_two > 0: + return elligible_members + passing_dm = set(member.uid for member in MemberCommitteeAttendance.query.join( CommitteeMeeting, MemberCommitteeAttendance.meeting_id == CommitteeMeeting.id @@ -200,7 +209,7 @@ def get_voting_members(): ).group_by( MemberCommitteeAttendance.uid ).having( - func.count(MemberCommitteeAttendance.uid) >= 6 #pylint: disable=not-callable + func.count(MemberCommitteeAttendance.uid) >= 6 # pylint: disable=not-callable ).with_entities( MemberCommitteeAttendance.uid ).all()) @@ -216,36 +225,47 @@ def get_voting_members(): ).group_by( MemberSeminarAttendance.uid ).having( - func.count(MemberSeminarAttendance.uid) >= 2 #pylint: disable=not-callable + func.count(MemberSeminarAttendance.uid) >= 2 # pylint: disable=not-callable ).all()) - passing_hm = set(member.uid for member in MemberHouseMeetingAttendance.query.join( + absent_hm = set(member.uid for member in MemberHouseMeetingAttendance.query.join( HouseMeeting, MemberHouseMeetingAttendance.meeting_id == HouseMeeting.id ).filter( HouseMeeting.date >= semester_start, or_( - MemberHouseMeetingAttendance.attendance_status == 'Attended', - # MemberHouseMeetingAttendance.attendance_status == 'Excused' + MemberHouseMeetingAttendance.attendance_status == 'Absent', ) ).with_entities( MemberHouseMeetingAttendance.uid ).group_by( MemberHouseMeetingAttendance.uid ).having( - func.count(MemberHouseMeetingAttendance.uid) >= 6 #pylint: disable=not-callable + func.count(MemberHouseMeetingAttendance.uid) > 1 # pylint: disable=not-callable ).all()) - passing_reqs = passing_dm & passing_ts & passing_hm + passing_reqs = (passing_dm & passing_ts) - absent_hm return elligible_members & passing_reqs + def gatekeep_status(username): - if datetime.today() < datetime(start_of_year().year, 12, 31): + today = datetime.today() + # Check to see if there's an Intro Evals in the future of this semester. If there is, everyone gets to vote! + before_evals_one = len(FreshmanAccount.query.filter(FreshmanAccount.eval_date > today).limit(1).all()) + before_evals_two = len(FreshmanEvalData.query.filter(FreshmanEvalData.eval_date > today).limit(1).all()) + if before_evals_one > 0 or before_evals_two > 0: + return { + "result": True, + "h_meetings_missed": 0, + "c_meetings": 0, + "t_seminars": 0, + } + if today < datetime(start_of_year().year, 12, 31): semester = "Fall" - semester_start = datetime(start_of_year().year,6,1) + semester_start = datetime(start_of_year().year, 6, 1) else: semester = "Spring" - semester_start = datetime(start_of_year().year + 1,1,1) + semester_start = datetime(start_of_year().year + 1, 1, 1) # groups ldap_member = ldap_get_member(username) @@ -253,21 +273,21 @@ def gatekeep_status(username): is_active_member = ldap_is_active(ldap_member) and not is_intro_member is_on_coop = ( - CurrentCoops.query.filter( - CurrentCoops.date_created > start_of_year(), - CurrentCoops.semester == semester, - CurrentCoops.uid == username, - ).first() - is not None + CurrentCoops.query.filter( + CurrentCoops.date_created > start_of_year(), + CurrentCoops.semester == semester, + CurrentCoops.uid == username, + ).first() + is not None ) passed_fall = ( - FreshmanEvalData.query.filter( - FreshmanEvalData.freshman_eval_result == "Passed", - FreshmanEvalData.eval_date > start_of_year(), - FreshmanEvalData.uid == username, - ).first() - is not None + FreshmanEvalData.query.filter( + FreshmanEvalData.freshman_eval_result == "Passed", + FreshmanEvalData.eval_date > start_of_year(), + FreshmanEvalData.uid == username, + ).first() + is not None ) eligibility_of_groups = (is_active_member and not is_on_coop) or passed_fall @@ -298,22 +318,23 @@ def gatekeep_status(username): .count() ) # number of house meetings attended in the current semester - h_meetings = ( + h_meetings_missed = ( MemberHouseMeetingAttendance.query.join( HouseMeeting, MemberHouseMeetingAttendance.meeting_id == HouseMeeting.id, ) .filter( + MemberHouseMeetingAttendance.attendance_status == 'Absent', MemberHouseMeetingAttendance.uid == username, HouseMeeting.date >= semester_start ) .count() ) - result = eligibility_of_groups and (d_meetings >= 6 and t_seminars >= 2 and h_meetings >= 6) + result = eligibility_of_groups and (d_meetings >= 6 and t_seminars >= 2 and h_meetings_missed < 2) # pylint: disable=chained-comparison return { "result": result, - "h_meetings": h_meetings, + "h_meetings_missed": h_meetings_missed, "c_meetings": d_meetings, "t_seminars": t_seminars, }