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)
Esempio n. 2
0
    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)
Esempio n. 5
0
    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)