diff --git a/conditional/__init__.py b/conditional/__init__.py index 28f1b278..8047cfed 100644 --- a/conditional/__init__.py +++ b/conditional/__init__.py @@ -1,26 +1,30 @@ import os import subprocess -from flask import Flask -from flask import redirect +from flask import Flask, redirect, request, render_template, g from flask_sqlalchemy import SQLAlchemy from flask_migrate import Migrate from csh_ldap import CSHLDAP +from raven import fetch_git_sha +from raven.contrib.flask import Sentry +from raven.exceptions import InvalidGitRepository import structlog app = Flask(__name__) -config = os.path.join(os.getcwd(), "config.py") +config = os.path.join(app.config.get('ROOT_DIR', os.getcwd()), "config.py") app.config.from_pyfile(config) app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False -app.config["GIT_REVISION"] = subprocess.check_output(['git', - 'rev-parse', - '--short', - 'HEAD']).decode('utf-8').rstrip() +try: + app.config["GIT_REVISION"] = fetch_git_sha(app.config["ROOT_DIR"])[:7] +except (InvalidGitRepository, KeyError): + app.config["GIT_REVISION"] = "unknown" + db = SQLAlchemy(app) migrate = Migrate(app, db) logger = structlog.get_logger() +sentry = Sentry(app) ldap = CSHLDAP(app.config['LDAP_BIND_DN'], app.config['LDAP_BIND_PW'], @@ -52,6 +56,7 @@ app.register_blueprint(slideshow_bp) app.register_blueprint(cache_bp) +from conditional.util.ldap import ldap_get_member @app.route('/') def static_proxy(path): @@ -63,6 +68,42 @@ def static_proxy(path): def default_route(): return redirect('/dashboard') +@app.errorhandler(404) +@app.errorhandler(500) +def route_errors(error): + data = dict() + username = request.headers.get('x-webauth-user') + + # Handle the case where the header isn't present + if username is not None: + member = ldap_get_member(username) + data['username'] = member.uid + data['name'] = member.cn + else: + data['username'] = "unknown" + data['name'] = "Unknown" + + # Figure out what kind of error was passed + if isinstance(error, int): + code = error + elif hasattr(error, 'code'): + code = error.code + else: + # Unhandled exception + code = 500 + + # Is this a 404? + if code == 404: + error_desc = "Page Not Found" + else: + error_desc = type(error).__name__ + + return render_template('errors.html', + error=error_desc, + error_code=code, + event_id=g.sentry_event_id, + public_dsn=sentry.client.get_public_dsn('https'), + **data), int(code) @app.cli.command() def zoo(): diff --git a/conditional/blueprints/attendance.py b/conditional/blueprints/attendance.py index f6d1f81b..2a0e149e 100644 --- a/conditional/blueprints/attendance.py +++ b/conditional/blueprints/attendance.py @@ -80,7 +80,7 @@ def get_non_alumni_non_coop(internal=False): for account in active_members: if account.uid in coop_members: # Members who are on co-op don't need to go to house meeting. - pass + continue eligible_members.append( { @@ -91,8 +91,8 @@ def get_non_alumni_non_coop(internal=False): if internal: return eligible_members - else: - return jsonify({'members': eligible_members}), 200 + + return jsonify({'members': eligible_members}), 200 @attendance_bp.route('/attendance/cm_members') @@ -314,15 +314,15 @@ def alter_house_attendance(uid, hid): member_meeting.attendance_status = "Attended" db.session.commit() return jsonify({"success": True}), 200 - else: - freshman_meeting = FreshmanHouseMeetingAttendance.query.filter( - FreshmanHouseMeetingAttendance.fid == uid, - FreshmanHouseMeetingAttendance.meeting_id == hid - ).first() - freshman_meeting.attendance_status = "Attended" - db.session.commit() - return jsonify({"success": True}), 200 + freshman_meeting = FreshmanHouseMeetingAttendance.query.filter( + FreshmanHouseMeetingAttendance.fid == uid, + FreshmanHouseMeetingAttendance.meeting_id == hid + ).first() + + freshman_meeting.attendance_status = "Attended" + db.session.commit() + return jsonify({"success": True}), 200 @attendance_bp.route('/attendance/alter/hm//', methods=['POST']) diff --git a/conditional/blueprints/conditional.py b/conditional/blueprints/conditional.py index 8dce1ad8..d09fd86a 100644 --- a/conditional/blueprints/conditional.py +++ b/conditional/blueprints/conditional.py @@ -117,5 +117,5 @@ def conditional_delete(cid): db.session.flush() db.session.commit() return jsonify({"success": True}), 200 - else: - return "Must be evals director to delete!", 401 + + return "Must be evals director to delete!", 401 diff --git a/conditional/blueprints/intro_evals.py b/conditional/blueprints/intro_evals.py index 38665a6d..cf76469f 100644 --- a/conditional/blueprints/intro_evals.py +++ b/conditional/blueprints/intro_evals.py @@ -9,6 +9,7 @@ from conditional.models.models import FreshmanCommitteeAttendance from conditional.models.models import MemberCommitteeAttendance +from conditional.models.models import CommitteeMeeting from conditional.models.models import FreshmanAccount from conditional.models.models import FreshmanEvalData from conditional.models.models import FreshmanHouseMeetingAttendance @@ -33,11 +34,13 @@ def display_intro_evals(internal=False): # get user data def get_uid_cm_count(member_id): return len([a for a in MemberCommitteeAttendance.query.filter( - MemberCommitteeAttendance.uid == member_id)]) + MemberCommitteeAttendance.uid == member_id) + if CommitteeMeeting.query.filter(CommitteeMeeting.id == a.meeting_id).approved]) def get_fid_cm_count(member_id): return len([a for a in FreshmanCommitteeAttendance.query.filter( - FreshmanCommitteeAttendance.fid == member_id)]) + FreshmanCommitteeAttendance.fid == member_id) + if CommitteeMeeting.query.filter(CommitteeMeeting.id == a.meeting_id).approved]) user_name = None if not internal: @@ -88,7 +91,8 @@ def get_fid_cm_count(member_id): [s.name for s in TechnicalSeminar.query.filter( TechnicalSeminar.id.in_( [a.seminar_id for a in FreshmanSeminarAttendance.query.filter( - FreshmanSeminarAttendance.fid == fid.id)] + FreshmanSeminarAttendance.fid == fid.id) + if TechnicalSeminar.query.filter(TechnicalSeminar.id == a.seminar_id).approved] )) ], 'social_events': '', @@ -141,7 +145,8 @@ def get_fid_cm_count(member_id): [s.name for s in TechnicalSeminar.query.filter( TechnicalSeminar.id.in_( [a.seminar_id for a in MemberSeminarAttendance.query.filter( - MemberSeminarAttendance.uid == uid)] + MemberSeminarAttendance.uid == uid) + if TechnicalSeminar.query.filter(TechnicalSeminar.id == a.seminar_id).approved] )) ], 'social_events': freshman_data.social_events, @@ -160,9 +165,9 @@ def get_fid_cm_count(member_id): if internal: return ie_members - else: - # return names in 'first last (username)' format - return render_template(request, - 'intro_evals.html', - username=user_name, - members=ie_members) + + # return names in 'first last (username)' format + return render_template(request, + 'intro_evals.html', + username=user_name, + members=ie_members) diff --git a/conditional/blueprints/intro_evals_form.py b/conditional/blueprints/intro_evals_form.py index 9719cbd3..6a3910c6 100644 --- a/conditional/blueprints/intro_evals_form.py +++ b/conditional/blueprints/intro_evals_form.py @@ -6,6 +6,7 @@ from conditional.models.models import FreshmanEvalData from conditional.models.models import EvalSettings from conditional.util.ldap import ldap_is_intromember +from conditional.util.ldap import ldap_get_member from conditional.util.flask import render_template from conditional import db @@ -23,8 +24,8 @@ def display_intro_evals_form(): # get user data user_name = request.headers.get('x-webauth-user') - - if not ldap_is_intromember(user_name): + account = ldap_get_member(user_name) + if not ldap_is_intromember(account): return redirect("/dashboard") eval_data = FreshmanEvalData.query.filter( FreshmanEvalData.uid == user_name).first() diff --git a/conditional/blueprints/major_project_submission.py b/conditional/blueprints/major_project_submission.py index bc593aad..363bd59b 100644 --- a/conditional/blueprints/major_project_submission.py +++ b/conditional/blueprints/major_project_submission.py @@ -121,5 +121,5 @@ def major_project_delete(pid): db.session.flush() db.session.commit() return jsonify({"success": True}), 200 - else: - return "Must be project owner to delete!", 401 + + return "Must be project owner to delete!", 401 diff --git a/conditional/blueprints/member_management.py b/conditional/blueprints/member_management.py index 1ba253f9..146526f9 100644 --- a/conditional/blueprints/member_management.py +++ b/conditional/blueprints/member_management.py @@ -373,13 +373,13 @@ def get_hm_date(hm_id): 'missed_hm': hms_missed, 'user': 'eval' }), 200 - else: - return jsonify( - { - 'name': account.cn, - 'active_member': ldap_is_active(account), - 'user': 'financial' - }), 200 + + return jsonify( + { + 'name': account.cn, + 'active_member': ldap_is_active(account), + 'user': 'financial' + }), 200 @member_management_bp.route('/manage/user/', methods=['DELETE']) diff --git a/conditional/blueprints/spring_evals.py b/conditional/blueprints/spring_evals.py index bc865931..6931bab6 100644 --- a/conditional/blueprints/spring_evals.py +++ b/conditional/blueprints/spring_evals.py @@ -6,6 +6,7 @@ from conditional.util.ldap import ldap_get_active_members from conditional.models.models import MemberCommitteeAttendance +from conditional.models.models import CommitteeMeeting from conditional.models.models import MemberHouseMeetingAttendance from conditional.models.models import MajorProject from conditional.models.models import HouseMeeting @@ -28,7 +29,8 @@ def display_spring_evals(internal=False): def get_cm_count(member_id): return len([a for a in MemberCommitteeAttendance.query.filter( - MemberCommitteeAttendance.uid == member_id)]) + MemberCommitteeAttendance.uid == member_id) + if CommitteeMeeting.query.filter(CommitteeMeeting.id == a.meeting_id).approved]) user_name = None if not internal: @@ -87,6 +89,14 @@ def get_cm_count(member_id): MajorProject.uid == uid)] } member['major_projects_len'] = len(member['major_projects']) + member['major_project_passed'] = [ + { + 'name': p.name, + 'status': p.status, + 'description': p.description + } for p in MajorProject.query.filter(MajorProject.uid == uid) + if p.status == "Passed"] + 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": @@ -103,8 +113,8 @@ def get_cm_count(member_id): # return names in 'first last (username)' format if internal: return sp_members - else: - return render_template(request, - 'spring_evals.html', - username=user_name, - members=sp_members) + + return render_template(request, + 'spring_evals.html', + username=user_name, + members=sp_members) diff --git a/conditional/templates/base.html b/conditional/templates/base.html index 79faf4b7..7ede4465 100644 --- a/conditional/templates/base.html +++ b/conditional/templates/base.html @@ -23,8 +23,14 @@ {% block body %} {% endblock %} {% else %} -
- +
+
+ Attention! +

Congratulations or I'm Sorry...

+

We cannot reveal the results of your evaluation!

+

Evaluations underway:

+

Conditional is in Lockdown

+
{% endif %} diff --git a/conditional/templates/errors.html b/conditional/templates/errors.html new file mode 100644 index 00000000..23273164 --- /dev/null +++ b/conditional/templates/errors.html @@ -0,0 +1,19 @@ +{% extends "nav.html" %} +{% block title %}Error {{ error_code }}{% endblock %} +{% block body %} +
+
+ Attention! +

Congratulations or I'm Sorry...

+

Something has gone terribly wrong!

+

{{ error }}

+ {% if event_id %} +

The error identifier is: {{ event_id }}

+ {% endif %} +
+ {% if event_id %} + + {% endif %} +
+ +{% endblock %} diff --git a/conditional/templates/intro_evals.html b/conditional/templates/intro_evals.html index 7b7d0d4d..e106cdd2 100644 --- a/conditional/templates/intro_evals.html +++ b/conditional/templates/intro_evals.html @@ -45,12 +45,12 @@
{{ m['uid'] }}
{% if m['signatures_missed'] == 0 %}
- Sigantures Missed + Signatures Missed {{ m['signatures_missed'] }}
{% elif m['signatures_missed'] > 0 %}
- Sigantures Missed + Signatures Missed {{ m['signatures_missed'] }}
{% else %} diff --git a/conditional/templates/major_project_submission.html b/conditional/templates/major_project_submission.html index 30aa753a..8705d2ad 100644 --- a/conditional/templates/major_project_submission.html +++ b/conditional/templates/major_project_submission.html @@ -11,7 +11,8 @@

Major Project Form

- +
@@ -19,7 +20,8 @@

Major Project Form

- +
@@ -79,7 +81,7 @@