def get(self): """ Processes student register class GET requests. More specifically, it loads a form that a student (once logged in) can fill out and submit in order to register for an active Capstone session. Input: self Output: a rendering of the student register page: featuring a student registration form if everything went well, or an error message if something went wrong """ # Get the database objects we will need capstone_session = gbmodel.capstone_session() professors = gbmodel.professors() # Get the currently active Capstone sessions sessions = capstone_session.get_active_sessions() if sessions is None: # https://docs.python.org/3/howto/logging.html#logging-basic-tutorial # (discovered via: https://docs.python-guide.org/writing/logging/) logging.warning(( "A student tried to register for a Capstone session, but no active sessions " "were available")) return self.display_error( "There aren't any active Capstone sessions to register for") # Build a list containing the id and a descriptor string of the active sessions active_sessions = [] for session in sessions: # Get the name of the professor running the session professor = professors.get_professor(session.professor_id) if professor is None: logging.error(( "Student Registration Failure - the professor of a specific Capstone session " "wasn't found. Was the professor removed from the database?" )) return self.display_error("Something went wrong") # Create the data structure entry active_sessions.append({ "id": session.id, "descriptor": "{} {} - {}".format(session.start_term, str(session.start_year), professor.name) }) # Render the studentRegister template using the list we put together return render_template('studentRegister.html', sessions=active_sessions)
def get_state(self, user_id, capstone_id): """ This method queries the database to get the user's report state. It will test for any database errors. input: only self output: String -- The user's "active" attribute or 'Error' to indicate something went wrong (could be user error, thus no need to abort) """ try: # get the state based on the capstone id and the current time state = gbmodel.capstone_session().check_review_state( capstone_id, datetime.now()) except SQLAlchemyError: logging.error( 'Fill Out Review - Student Look Up Error - Get State') return 'Error' # return student state return state
def get(self): """ This method handles get requests go addSession.html Input: only self Output: rendering the addSession.html template with session id from profDashboard.html """ if not validate_professor(): return display_access_control_error() # Canceling creating a session, render to the current session old_session_id = request.args.get('session_id') session = gbmodel.capstone_session() # Session id for new session session_id = session.get_max() professors = gbmodel.professors() prof_list = professors.get_all_professors() return render_template('addSession.html', error=None, session_id=session_id, old_session_id=old_session_id, prof_list=prof_list)
def get(self): """ Get session_id from the previous selected session If None returned then request for a selection. Otherwise, display the current session_id """ if not validate_professor(): return display_access_control_error() session = gbmodel.capstone_session() team = gbmodel.teams() session_id = request.args.get('session_id') if session_id is None: user_session = request.args.get('selected_session') # When professor first login, user_session = None if user_session is None: session_id = "" else: term = str(user_session[:user_session.index("-")].strip()) year = int(user_session[user_session.index("-") + 1:user_session.index("(")].strip()) prof = str(user_session[user_session.index("(") + 1:user_session.index(")")].strip()) session_id = session.get_session_id(term, year, prof) # Lists - a list of teams and students of a selected session to display on the dashboard # Sessions - a list of sessions to display in drop downs lists, sessions = team.dashboard(session_id) # If theres no team in the session, do not display teams if lists is None: return render_template('profDashboard.html', sessions=sessions, session_id=session_id) return render_template('profDashboard.html', lists=lists, sessions=sessions, session_id=session_id)
def post(self, capstone_id): """ This method handles post requests from review.html. Input: only self Output: rendering the review.html template with errors reported to the user or rendering the success page to indicate the user was successful in submitting their report """ # check if user exists user_id = request.form.get('user_id') test_user = self.confirm_user(user_id, capstone_id) if test_user is False: logging.error('Fill Out Review - Error when identifiyng user') return render_template( 'review.html', mems=None, state=None, input_error=None, fatal_error='You have no open reviews.', ) # get user's team id tid = self.get_tid(user_id, capstone_id) # get users state state = self.get_state(user_id, capstone_id) if state == 'Error': logging.error( 'Fill Out Review - Error while retrieving student state') return render_template( 'review.html', name=self.get_self_name(user_id), mems=None, state=None, input_error=None, fatal_error='You have no open reviews.', ) # get user's team members try: mems = gbmodel.students().get_team_members(tid) except SQLAlchemyError: logging.error( 'Fill Out Review - Error while retrieving team members') return render_template( 'review.html', name=self.get_self_name(), mems=None, state=None, input_error=None, fatal_error= 'There was an error while retrieving user team members.', ) # get student's cid cid = capstone_id # generate a list of the DB ids for students on the team id_list = [] for mem in mems: if mem is not None: id_list.append(mem.id) # check points total total = 0 points_pass = True # check that conditions for points match requirements for j in id_list: logging.info('checking points') # check points for being in bounds and adding to 100 points = request.form[('points_' + str(j))] try: try: # ensure that points are all integers points = int(points) except ValueError: flash('points must be an integer') points = 0 points_pass = False if (points_pass is True) and points < 0: flash('Points must be 0 or greater') points = 0 points_pass = False if points_pass is True: # add up the total points total = total + points if j == user_id: # make sure own score is 0 if points > 0 or points < 0: flash('Points must be 0 for self') points_pass = False except ValueError: self.display_error('Invalid input for points') points = 0 points_pass = False # check that total is 100 if total != 100: flash('Points total must be 100') points = 0 points_pass = False done = self.get_done(user_id, capstone_id) # get form inputs and submit to the database if points_pass is True: logging.info('Retrieving Form Input') pass_insert = True # will test if all insertions are successful for i in id_list: # Get each radio input and verify that it's an integer tech = request.form[('tech_mast_' + str(i))] tech = self.convert_to_int(tech) ethic = request.form[('work_ethic_' + str(i))] ethic = self.convert_to_int(ethic) com = request.form[('comm_' + str(i))] com = self.convert_to_int(com) coop = request.form[('coop_' + str(i))] coop = self.convert_to_int(coop) init = request.form[('init_' + str(i))] init = self.convert_to_int(init) focus = request.form[('team_focus_' + str(i))] focus = self.convert_to_int(focus) cont = request.form[('contr_' + str(i))] cont = self.convert_to_int(cont) # default leader skills to None for Null in database lead = None org = None dlg = None # check if current student is leader try: is_lead = gbmodel.students().check_team_lead( i, capstone_id) except SQLAlchemyError: self.display_error('student look up error') if is_lead is True: # get leader values lead = request.form[('lead_' + str(i))] lead = self.convert_to_int(lead) org = request.form[('org_' + str(i))] org = self.convert_to_int(org) dlg = request.form[('dlg_' + str(i))] dlg = self.convert_to_int(dlg) # Get string inputs strn = request.form[('str_' + str(i))] strn = strn.strip() wkn = request.form[('wkn_' + str(i))] wkn = wkn.strip() traits = request.form[('traits_' + str(i))] traits = traits.strip() learned = None if i == user_id: learned = request.form[('learned')] learned = learned.strip() if len(learned) > 30000: logging.error('learned string too long') abort(422) proud = None # only get 'proud' if the student is filling out final review if self.get_state(user_id, capstone_id) == 'final': if i == user_id: proud = request.form[('proud')] proud = proud.strip() if len(proud) > 30000: logging.error('proud string too long') abort(422) points = request.form[('points_' + str(i))] points = points.strip() if ((len(strn) > 30000) or (len(wkn) > 30000) or (len(traits) > 30000)): logging.error('str/wkn/traits string too long') abort(422) points = self.convert_to_int(points) # default to not late late = False is_final = False try: logging.info('Checking if Late') is_not_late = gbmodel.capstone_session().check_not_late( cid, datetime.now(), self.get_state( user_id, capstone_id, ), ) if is_not_late is False: late = True except SQLAlchemyError: self.display_error('student look up error - capstone') logging.info('checking student state') if self.get_state(user_id, capstone_id) == 'midterm': # for midterm set final to false is_final = False elif self.get_state(user_id, capstone_id) == 'final': # for midterm set final to false is_final = True if done == 1: # update existing record try: logging.info('updating report') report = gbmodel.reports().get_report( user_id, i, tid, is_final, ) if report is not None: report.tech_mastery = tech report.work_ethic = ethic report.communication = com report.cooperation = coop report.initiative = init report.team_focus = focus report.contribution = cont report.leadership = lead report.organization = org report.delegation = dlg report.points = points report.strengths = strn report.weaknesses = wkn report.traits_to_work_on = traits report.what_you_learned = learned report.proud_of_accomplishment = proud else: test_sub = gbmodel.reports().insert_report( cid, datetime.now(), user_id, tid, i, tech, ethic, com, coop, init, focus, cont, lead, org, dlg, points, strn, wkn, traits, learned, proud, is_final, late) if test_sub is False: logging.error('report creation failure') pass_insert = False except SQLAlchemyError: pass_insert = False else: logging.info('creating report') # insert new record # add report, but do not commit yet test_sub = gbmodel.reports().insert_report( cid, datetime.now(), user_id, tid, i, tech, ethic, com, coop, init, focus, cont, lead, org, dlg, points, strn, wkn, traits, learned, proud, is_final, late, ) # remember if this report submission failed if test_sub is False: logging.error('report creation failure') pass_insert = False if done == 1: # commit updates logging.info('committing edits') test_commit = gbmodel.reports().commit_updates(pass_insert) else: logging.info('committing reports') # commit reports and update the user's state. # roll back changes if insertion failed test_commit = gbmodel.reports().commit_reports( user_id, self.get_state(user_id, capstone_id), capstone_id, pass_insert, ) if test_commit is True: # success return render_template('submitted.html') else: self.display_error('Submission Error') return render_template('review.html', name=self.get_self_name(user_id, capstone_id), mems=mems, human_fields=self.human_fields, code_fields=self.code_fields, state=self.get_state(user_id, capstone_id), input_error=True, fatal_error=None)
def post(self): """ This method handles all the functionalities from proDashboard includes add/remove students/teams, add new session, set review midterm/final start/end dates, setting reviews to be open/closed, and set team lead """ if not validate_professor(): return display_access_control_error() session = gbmodel.capstone_session() student = gbmodel.students() team = gbmodel.teams() professor = gbmodel.professors() # Get current session id from dropdowns in profDashboard.html session_id = request.form['session_id'] if 'student_name' in request.form: # Add New Student (student name, student id and student email) # Get team name and session id from profDashboard.html, # new student id, name, email from addStudent.html team_name = request.form.get('team_name') if not student.check_dup_student(request.form['student_id'], session_id): # If student id in a current session already exists # Return to addStudent.html with error msg and request a new form error = "Student id " + str( request.form['student_id']) + " already exists" return render_template('addStudent.html', team_name=team_name, session_id=session_id, error=error) if request.form['student_email'] != '': # If new email is invalid, return to addStudent.html # with error msg and request a new form if self.valid_email(str( request.form['student_email'])) is False: error = "Invalid Email Address" return render_template('addStudent.html', team_name=team_name, session_id=session_id, error=error) # Insert new student information into the database student.insert_student(request.form['student_name'], request.form['student_email'], request.form['student_id'], session_id, team_name) # Update new list of students to reflect on profDashboard.html lists, sessions = team.dashboard(session_id) return render_template('profDashboard.html', lists=lists, sessions=sessions, session_id=session_id) elif 'team' in request.form: # Remove a student/students from a team # get list of students and team name from profDashboard.html students = request.form.getlist('removed_student') team_name = request.form.get('team') # Remove student/students from database student.remove_student(students, team_name, session_id) lists, sessions = team.dashboard(session_id) return render_template('profDashboard.html', lists=lists, sessions=sessions, session_id=session_id) elif 'removed_team' in request.form: # Remove a team in a session # Get team name in current session from profDashboard.html team_name = request.form.get('removed_team') # There was a problem removing teams with blank names, so (in remove team requests) a '_' # character was added to the beginning of the name. # We will want to remove it before we continue # https://stackoverflow.com/questions/4945548/remove-the-first-character-of-a-string team_name = team_name[1:] # Remove team and students in the team from database team.remove_team(team_name, session_id) lists, sessions = team.dashboard(session_id) return render_template('profDashboard.html', lists=lists, sessions=sessions, session_id=session_id) elif 'start_term' in request.form: # Add a new session to the profDashboard # Gets all professors in DB and stores into prof_list professors = gbmodel.professors() prof_list = professors.get_all_professors() while not session.check_term_name(request.form['start_term']): error = "Enter a valid term (Example: Summer)" return render_template('addSession.html', error=error, session_id=session_id, prof_list=prof_list) while not session.check_term_year(request.form['start_year']): error = "Enter a valid year (Example: 2019)" return render_template('addSession.html', error=error, session_id=session_id, prof_list=prof_list) while not professor.check_professor(request.form['professor_id']): error = "Enter a valid professor ID" return render_template('addSession.html', error=error, session_id=session_id, prof_list=prof_list) while not session.check_dup_session(request.form['start_term'], request.form['start_year'], request.form['professor_id']): error = "Session already exists" return render_template('addSession.html', error=error, session_id=session_id, prof_list=prof_list) start_term = request.form.get('start_term') start_year = request.form.get('start_year') start_term = start_term.replace("_", " ") start_year = start_year.replace("_", " ") professor_id = request.form.get('professor_id') professor_id = professor_id.replace("_", " ") session_id = session.insert_session(start_term, start_year, professor_id) lists, sessions = team.dashboard(session_id) return render_template('profDashboard.html', lists=lists, sessions=sessions, session_id=session_id) # If REMOVE SESSION was submitted (removed_session) elif 'removed_session' in request.form: while not session.check_session_id_valid( request.form['removed_session']): error = "Invalid session ID" return render_template('profDashboard.html', lists=lists, sessions=sessions, session_id=session_id) remove_session = request.form.get('removed_session') remove_session = remove_session.replace("_", " ") session.remove_session(session_id) session_id = session.get_max() - 1 lists, sessions = team.dashboard(session_id) return render_template('profDashboard.html', lists=lists, sessions=sessions, session_id=session_id) # If ADD TEAM was submitted (addTeam) elif 'team_name' in request.form: # Add a new team to a current session # Request new team name from addTeam.html if not team.check_dup_team(request.form['team_name'], session_id): # If new name already exists in current session # Rentering the addTeam.html with given error message error = "Team name already exists" return render_template('addTeam.html', error=error, session_id=session_id) team_name = request.form.get('team_name') # Add new team to the given session from profDashboard.html team.insert_team(session_id, team_name) # Update new list of sessions, teams, students to reflect on profDashboard.html lists, sessions = team.dashboard(session_id) return render_template('profDashboard.html', lists=lists, sessions=sessions, session_id=session_id) # if ASSIGNED TEAMS for to place new students on teams was submitted elif 'assigned_teams' in request.form: size = request.form.get('size') size = int(size) unassigned_students = student.get_unassigned_students(session_id) team_names = [] i = 1 while i <= size: team_name = (request.form.get('assigned_team' + str(i))) if team.check_dup_team(team_name, session_id) is False: t_id = team.get_tid_from_name(team_name, session_id) student.update_team(unassigned_students[i - 1].name, session_id, t_id) else: team.insert_team(session_id, team_name) t_id = team.get_tid_from_name(team_name, session_id) student.update_team(unassigned_students[i - 1].name, session_id, t_id) team_names.append(team_name) i += 1 lists, sessions = team.dashboard(session_id) return render_template('profDashboard.html', lists=lists, sessions=sessions, session_id=session_id) # If IMPORT STUDENTS was submitted (addTeamCSV) elif 'student_data_csv' in request.files: session_id = int(request.form['session_id']) teams_table = gbmodel.teams() # Accessor to the teams table students_table = gbmodel.students( ) # Accessor to the students table file = request.files['student_data_csv'] # If 'Create from File' was selected with no file # return back to import student page. if (file.filename == ''): return render_template('csvAddTeam.html', session_id=session_id, error="Please select a file to upload") stream = io.StringIO(file.stream.read().decode("UTF8"), newline=None) csv_reader = csv.reader(stream, delimiter=',') uninserted_students = [] for row in csv_reader: if len(row) > 3: return render_template('csvAddTeam.html', session_id=session_id, error="Incorrect csv Format") try: student_name = row[0] student_id = row[1] team_name = row[2] except IndexError: logging.warning( "CSV Add Students/Team - Problem parsing csv") return render_template('csvAddTeam.html', session_id=session_id, error="Incorrect csv Format") # Create team if it doesn't exist, then create the student. try: if teams_table.check_dup_team(team_name, session_id) is True: teams_table.insert_team(session_id, team_name) except SQLAlchemyError: logging.error(( 'CSV Add Students/Team - Error checking for existing team and/or' ' inserting a new one')) return render_template('csvAddTeam.html', session_id=session_id, error="Something went wrong") try: if students_table.check_dup_student( student_id, session_id) is True: students_table.insert_student(student_name, "", student_id, session_id, team_name) else: # Keep track of what students weren't added to the database (and make a note it) logging.warning( "CSV Add Students/Team -" " Error inserting student into the database") uninserted_students.append(student_name) except SQLAlchemyError: logging.error(( 'CSV Add Students/Team -' ' Error inserting students or checking if they exist in the database' )) return render_template('csvAddTeam.html', session_id=session_id, error="Something went wrong") # If everything went well, reload the professor dashboard if len(uninserted_students) == 0: logging.info( "CSV Add Students/Team - added student data from uploaded csv file" ) lists, sessions = team.dashboard(session_id) return render_template('profDashboard.html', lists=lists, sessions=sessions, session_id=session_id) # If there were some problems, let the user know else: error_str = "There was a problem inserting the following students into the database: " error_str = error_str + ", ".join(uninserted_students) error_str = error_str + ". They are already in this session." return render_template('csvAddTeam.html', session_id=session_id, error=error_str) # If SET DATE for reviews was submitted (setDate) elif 'midterm_start' in request.form: # Add midterm/final start/end dates for review form # Request start and end dates for midterm and final from setDate.html midterm_start = request.form.get('midterm_start') midterm_end = request.form.get('midterm_end') final_start = request.form.get('final_start') final_end = request.form.get('final_end') params = { 'midterm_start': midterm_start, 'midterm_end': midterm_end, 'final_start': final_start, 'final_end': final_end } if session.date_error(params) is not None: # Check if the dates are valid, rendering to setDate.html # with a error message error_msg = session.date_error(params) return render_template('setDate.html', error=error_msg, session_id=session_id) # Insert dates into database session.insert_dates(midterm_start, midterm_end, final_start, final_end, session_id) # Update new list of sessions, teams, students to reflect on profDashboard.html lists, sessions = team.dashboard(session_id) return render_template('profDashboard.html', lists=lists, sessions=sessions, session_id=session_id) elif 'team_lead' in request.form: # Set team lead for a team in current session # Get team name and lead from checkboxes in profDashboard.html team_name = request.form.get('team_lead') student_name = request.form.get('is_lead') # Set lead for chosen team in current sesison student.set_lead(session_id, team_name, student_name) # Update new list of sessions, teams, students to reflect on profDashboard.html lists, sessions = team.dashboard(session_id) return render_template('profDashboard.html', lists=lists, sessions=sessions, session_id=session_id) elif 'set_review_available' in request.form: # update students' review availability setting = request.form.get('set_review_available') result = student.set_active(session_id, setting) if result is True: # back to page lists, sessions = team.dashboard(session_id) return render_template('profDashboard.html', lists=lists, sessions=sessions, session_id=session_id) else: error_msg = "Error When Selecting Option" return render_template('setAvailable.html', error=error_msg, session_id=session_id)