class MessageCenterView(FlaskView): route_base = 'message-center' def __init__(self): self.base = MessageCenterController() self.wcc = WritingCenterController() @route('/') def index(self): self.wcc.check_roles_and_route(['Administrator']) users = self.base.get_active_users() users = sorted(users, key=lambda i: i.lastName) roles = self.base.get_roles() roles = sorted(roles, key=lambda i: i.id) return render_template('message_center/send-email.html', **locals()) @route('/send', methods=['POST']) def send(self): self.wcc.check_roles_and_route(['Administrator']) data = request.form # grab the group(s) from the form, use the group id to get the emails of all the people in the group(s) # make sure there are no duplicates in the email list # need to check that all the stuff is actually filled in, if its not, we need to fill it with an empty value subject = data.get('subject') message = data.get('message') groups = data.getlist('recipients') cc_ids = data.getlist('cc') bcc_ids = data.getlist('bcc') recipients = self.base.get_cc(cc_ids) bcc = self.base.get_bcc(groups, bcc_ids) if self.base.send_message(subject, message, recipients, bcc, False): self.wcc.set_alert('success', 'Email sent successfully!') else: self.wcc.set_alert('danger', 'Email failed to send.') return redirect(url_for('MessageCenterView:index'))
def __init__(self): self.sc = SchedulesController() self.wcc = WritingCenterController() self.mcc = MessageCenterController()
class SchedulesView(FlaskView): route_base = '/schedules/' def __init__(self): self.sc = SchedulesController() self.wcc = WritingCenterController() self.mcc = MessageCenterController() @route("/create-schedule") def create_time_slot(self): self.wcc.check_roles_and_route(['Administrator']) schedules = self.sc.get_all_schedules() return render_template("schedules/create_time_slot.html", **locals()) @route('/manage-tutor-schedules') def manage_tutor_schedules(self): self.wcc.check_roles_and_route(['Administrator']) schedules = self.sc.get_active_schedules() tutors = self.sc.get_active_tutors() time_setting = self.sc.get_time_setting()[0] return render_template('schedules/manage_tutor_schedules.html', **locals()) @route('view-tutor-schedules') def view_tutor_schedules(self): self.wcc.check_roles_and_route(['Tutor', 'Administrator']) schedules = self.sc.get_active_schedules() tutors = self.sc.get_active_tutors() time_setting = self.sc.get_time_setting()[0] return render_template('schedules/view_tutor_schedule.html', **locals()) @route('/create', methods=['POST']) def create_new_time_slot(self): self.wcc.check_roles_and_route(['Administrator']) form = request.form start_time = form.get('start-time') start_time = datetime.strftime(datetime.strptime(start_time, '%H:%M'), '%H:%M:%S') end_time = form.get('end-time') end_time = datetime.strftime(datetime.strptime(end_time, '%H:%M'), '%H:%M:%S') is_active = int(form.get('active')) created = self.sc.create_time_slot(start_time, end_time, is_active) if created: self.wcc.set_alert('success', 'Schedule Created Successfully!') else: self.wcc.set_alert('danger', 'Schedule already exists!') return redirect(url_for('SchedulesView:create_time_slot')) @route('deactivate-time-slots', methods=['POST']) def deactivate_time_slots(self): self.wcc.check_roles_and_route(['Administrator']) form = request.form json_schedule_ids = form.get('jsonScheduleIds') schedule_ids = json.loads(json_schedule_ids) try: for schedule_id in schedule_ids: self.sc.deactivate_time_slot(schedule_id) self.wcc.set_alert('success', 'Time slot(s) deactivated successfully!') except Exception as error: self.wcc.set_alert('danger', 'Failed to deactivate time slot(s).') return 'done' # Return doesn't matter: success or failure take you to the same page. Only the alert changes. @route('/add-tutors-to-shifts', methods=['POST']) def add_tutors_to_shifts(self): self.wcc.check_roles_and_route(['Administrator']) form = request.form start_date = form.get('start-date') end_date = form.get('end-date') if not start_date or not end_date: self.wcc.set_alert('danger', 'You must set a start date AND an end date!') return redirect(url_for('SchedulesView:manage_tutor_schedules')) # Formats the date strings into date objects start = datetime.strptime(start_date, '%a %b %d %Y').date() end = datetime.strptime(end_date, '%a %b %d %Y').date() if start > end: self.wcc.set_alert( 'danger', 'Start date cannot be further in the future than the end date!' ) return redirect(url_for('SchedulesView:manage_tutor_schedules')) multilingual = int(form.get('multilingual')) drop_in = int(form.get('drop-in')) virtual = int(form.get('virtual')) tutors = form.getlist('tutors') days = form.getlist('days') time_slots = form.getlist('time-slots') if tutors[0] == 'Select All Tutors': tutors = [] for tutor in self.sc.get_active_tutors(): tutors.append(tutor.id) success = self.sc.create_tutor_shifts(start, end, multilingual, drop_in, virtual, tutors, days, time_slots) if not success: self.wcc.set_alert( 'warning', 'The shifts failed to be scheduled! One or more of the selected day of week never occurs.' ) return redirect(url_for('SchedulesView:manage_tutor_schedules')) if success == 'warning': self.wcc.set_alert( 'warning', 'One or more of the shifts failed to be scheduled.') return redirect(url_for('SchedulesView:manage_tutor_schedules')) self.wcc.set_alert( 'success', 'Successfully added the tutor(s) to the time slot(s).') return redirect(url_for('SchedulesView:manage_tutor_schedules')) @route('/show-schedule', methods=['POST']) def show_tutor_schedule(self): self.wcc.check_roles_and_route(['Administrator', 'Tutor']) names = json.loads(request.data).get('tutors') if 'view-all' in names: tutors = self.sc.get_active_tutors() names = [] for tutor in tutors: names.append(str(tutor.id)) all_tutor_appts = self.sc.get_tutor_appointments(names) appointments = [] # Formats the times to match the fullcalendar desired format for tutor_appts in all_tutor_appts: for appointment in tutor_appts: if appointment.actualStart and appointment.actualEnd: start_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format( appointment.actualStart.year, appointment.actualStart.strftime('%m'), appointment.actualStart.strftime('%d'), appointment.actualStart.strftime('%H'), appointment.actualStart.strftime('%M'), appointment.actualStart.strftime('%S')) end_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format( appointment.actualEnd.year, appointment.actualEnd.strftime('%m'), appointment.actualEnd.strftime('%d'), appointment.actualEnd.strftime('%H'), appointment.actualEnd.strftime('%M'), appointment.actualEnd.strftime('%S')) elif appointment.scheduledStart and appointment.scheduledEnd: start_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format( appointment.scheduledStart.year, appointment.scheduledStart.strftime('%m'), appointment.scheduledStart.strftime('%d'), appointment.scheduledStart.strftime('%H'), appointment.scheduledStart.strftime('%M'), appointment.scheduledStart.strftime('%S')) end_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format( appointment.scheduledEnd.year, appointment.scheduledEnd.strftime('%m'), appointment.scheduledEnd.strftime('%d'), appointment.scheduledEnd.strftime('%H'), appointment.scheduledEnd.strftime('%M'), appointment.scheduledEnd.strftime('%S')) else: start_time = None end_time = None tutor = self.sc.get_user_by_id(appointment.tutor_id) appointments.append({ 'id': appointment.id, 'studentId': appointment.student_id, 'tutorName': '{0} {1}'.format(tutor.firstName, tutor.lastName), 'startTime': start_time, 'endTime': end_time, 'multilingual': appointment.multilingual, 'virtual': appointment.online, 'dropIn': appointment.dropIn, 'sub': appointment.sub }) return jsonify(appointments) @route('delete-confirmation', methods=['POST']) def confirm_delete(self): self.wcc.check_roles_and_route(['Administrator']) # Post method that displays a confirmation before appointments within a given range for selected tutors are # deleted to make sure the person knows what they are doing start_date = str(json.loads(request.data).get('startDate')) end_date = str(json.loads(request.data).get('endDate')) start = datetime.strptime(start_date, '%a %b %d %Y').date() end = datetime.strptime(end_date, '%a %b %d %Y').date() tutor_ids = json.loads(request.data).get('tutors') names = [] if start > end: invalid_date = True if 'view-all' in tutor_ids: tutors = self.sc.get_active_tutors() for tutor in tutors: user = self.sc.get_user_by_id(tutor.id) name = '{0} {1}'.format(user.firstName, user.lastName) names.append(name) else: for tutor_id in tutor_ids: user = self.sc.get_user_by_id(tutor_id) if user: name = '{0} {1}'.format(user.firstName, user.lastName) names.append(name) return render_template('schedules/delete_confirmation.html', **locals()) @route('delete-appointment', methods=['POST']) def delete_appointment(self): self.wcc.check_roles_and_route(['Administrator']) appt_id = str(json.loads(request.data).get('appt_id')) deleted = self.sc.delete_appointment(appt_id) if deleted: if deleted == 'sub': return deleted else: return appt_id else: self.wcc.set_alert('danger', 'Failed to delete appointment!') return redirect(url_for('SchedulesView:manage_tutor_schedules')) @route('confirm-delete', methods=['post']) def confirm_delete_appointment(self): self.wcc.check_roles_and_route(['Administrator']) appt_id = str(json.loads(request.data).get('appt_id')) deleted = self.sc.confirm_delete_appointment(appt_id) if deleted: # TODO: probably should send an email here return appt_id else: self.wcc.set_alert('danger', 'Failed to delete appointment!') return redirect(url_for('SchedulesView:manage_tutor_schedules')) @route('delete-tutor-shifts', methods=['POST']) def delete_tutors_from_shifts(self): self.wcc.check_roles_and_route(['Administrator']) # Post method to delete appointments which selected tutors are running in a given date range start_date = str(json.loads(request.data).get('startDate')) end_date = str(json.loads(request.data).get('endDate')) start = datetime.strptime(start_date, '%a %b %d %Y').date() end = datetime.strptime(end_date, '%a %b %d %Y').date() # If start > end that means start is further into the future than end in so we should the confirmation html # again to tell them to fix that if start > end: invalid_date = True return render_template('schedules/delete_confirmation.html', **locals()) # If we get past that check, then we delete the appointment(s) and show the substitution table tutor_ids = json.loads(request.data).get('tutors') if 'view-all' in tutor_ids: tutors = self.sc.get_active_tutors() tutor_ids = [] for ids in tutors: tutor_ids.append(str(ids.id)) sub_appts = self.sc.delete_tutor_shifts(tutor_ids, start, end) if sub_appts == 'none': return '<h3>All appointments in the selected range were deleted successfully!</h3>' if sub_appts: return render_template('schedules/sub_table.html', **locals(), id_to_user=self.sc.get_user_by_id) return '<h3>There weren\'t any appointments within the date range selected!</h3>' @route('request-sub', methods=['POST']) def request_sub(self): self.wcc.check_roles_and_route(['Administrator']) # Post method to request a sub for a given appointment or subs for all given appointments appt_id = json.loads(request.data).get('apptID') appt_id_list = json.loads(request.data).get('apptIDList') if appt_id == 'all': worked = self.sc.sub_all(appt_id_list) if not worked: self.wcc.set_alert( 'danger', 'Failed to request a substitute for all appointments.') else: worked = self.sc.request_substitute(appt_id) if not worked: self.wcc.set_alert( 'danger', 'Failed to request a substitute for appointment id {0}.'. format(appt_id)) return 'Substitute Requested Successfully' @route('get-appointments', methods=['GET']) def get_users_appointments(self): self.wcc.check_roles_and_route(['Student', 'Tutor', 'Administrator']) if flask_session['USERNAME'] in [ 'Student', 'Tutor', 'Administrator', 'Observer' ]: return '' appts = self.sc.get_all_user_appointments(flask_session['USERNAME']) appointments = [] # Formats the times to match the fullcalendar desired format for appointment in appts: if appointment.actualStart and appointment.actualEnd: start_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format( appointment.actualStart.year, appointment.actualStart.strftime('%m'), appointment.actualStart.strftime('%d'), appointment.actualStart.strftime('%H'), appointment.actualStart.strftime('%M'), appointment.actualStart.strftime('%S')) end_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format( appointment.actualEnd.year, appointment.actualEnd.strftime('%m'), appointment.actualEnd.strftime('%d'), appointment.actualEnd.strftime('%H'), appointment.actualEnd.strftime('%M'), appointment.actualEnd.strftime('%S')) elif appointment.scheduledStart and appointment.scheduledEnd: start_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format( appointment.scheduledStart.year, appointment.scheduledStart.strftime('%m'), appointment.scheduledStart.strftime('%d'), appointment.scheduledStart.strftime('%H'), appointment.scheduledStart.strftime('%M'), appointment.scheduledStart.strftime('%S')) end_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format( appointment.scheduledEnd.year, appointment.scheduledEnd.strftime('%m'), appointment.scheduledEnd.strftime('%d'), appointment.scheduledEnd.strftime('%H'), appointment.scheduledEnd.strftime('%M'), appointment.scheduledEnd.strftime('%S')) else: start_time = None end_time = None tutor = self.sc.get_user_by_id(appointment.tutor_id) appointments.append({ 'id': appointment.id, 'studentId': appointment.student_id, 'tutorName': '{0} {1}'.format(tutor.firstName, tutor.lastName), 'startTime': start_time, 'endTime': end_time, 'multilingual': appointment.multilingual, 'virtual': appointment.online, 'dropIn': appointment.dropIn, 'sub': appointment.sub }) return jsonify(appointments) def get_sub_appointments(self): self.wcc.check_roles_and_route(['Tutor', 'Administrator']) appts = self.sc.get_sub_appointments() appointments = [] # Formats the times to match the fullcalendar desired format for appointment in appts: if appointment.actualStart and appointment.actualEnd: start_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format( appointment.actualStart.year, appointment.actualStart.strftime('%m'), appointment.actualStart.strftime('%d'), appointment.actualStart.strftime('%H'), appointment.actualStart.strftime('%M'), appointment.actualStart.strftime('%S')) end_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format( appointment.actualEnd.year, appointment.actualEnd.strftime('%m'), appointment.actualEnd.strftime('%d'), appointment.actualEnd.strftime('%H'), appointment.actualEnd.strftime('%M'), appointment.actualEnd.strftime('%S')) elif appointment.scheduledStart and appointment.scheduledEnd: start_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format( appointment.scheduledStart.year, appointment.scheduledStart.strftime('%m'), appointment.scheduledStart.strftime('%d'), appointment.scheduledStart.strftime('%H'), appointment.scheduledStart.strftime('%M'), appointment.scheduledStart.strftime('%S')) end_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format( appointment.scheduledEnd.year, appointment.scheduledEnd.strftime('%m'), appointment.scheduledEnd.strftime('%d'), appointment.scheduledEnd.strftime('%H'), appointment.scheduledEnd.strftime('%M'), appointment.scheduledEnd.strftime('%S')) else: start_time = None end_time = None tutor = self.sc.get_user_by_id(appointment.tutor_id) appointments.append({ 'id': appointment.id, 'studentId': appointment.student_id, 'tutorName': '{0} {1}'.format(tutor.firstName, tutor.lastName), 'startTime': start_time, 'endTime': end_time, 'multilingual': appointment.multilingual, 'virtual': appointment.online, 'dropIn': appointment.dropIn, 'sub': appointment.sub }) return jsonify(appointments) @route('pickup-shift', methods=['POST']) def pickup_shift(self): self.wcc.check_roles_and_route(['Tutor', 'Administrator']) if flask_session['USERNAME'] in [ 'Administrator', 'Observer', 'Tutor', 'Student' ]: self.wcc.set_alert( 'danger', 'You cannot pick up a shift while acting as a role.') else: appointment_id = str(json.loads(request.data).get('appt_id')) appt = self.sc.get_one_appointment(appointment_id) self.mcc.substitute_request_filled(appointment_id) # TODO MAYBE EMAIL STUDENT ABOUT TUTOR CHANGE IF APPLICABLE? picked_up = self.sc.pickup_shift(appointment_id, flask_session['USERNAME']) if picked_up: self.wcc.set_alert('success', 'Successfully picked up the shift!') else: self.wcc.set_alert('danger', 'Failed to pick up the shift.') return 'finished' @route('request-subtitute', methods=['POST']) def request_substitute(self): self.wcc.check_roles_and_route(['Tutor', 'Administrator']) appointment_id = str(json.loads(request.data).get('appt_id')) appt = self.sc.get_one_appointment(appointment_id) success = self.sc.request_substitute(appointment_id) if success: self.mcc.request_substitute(appointment_id) self.wcc.set_alert('success', 'Successfully requested a substitute!') else: self.wcc.set_alert('danger', 'Error! Substitute not requested.') return 'finished'
class StatisticsView(FlaskView): def __init__(self): self.sc = StatisticsController() self.wcc = WritingCenterController() @route('/stats') def stats(self): self.wcc.check_roles_and_route(['Observer', 'Administrator']) # Use the default start and end dates to get the first tables of data start = flask_session['DATE-SELECTOR-START'] end = flask_session['DATE-SELECTOR-END'] value = flask_session['DATE-SELECTOR-VALUE'] appointments, walk_in_appts, no_show_appts = self.get_statistics_data(start, end, value) return render_template('statistics/statistics.html', **locals()) @route('/hours-worked') def hours_worked(self): self.wcc.check_roles_and_route(['Tutor', 'Administrator']) return render_template('statistics/hours_worked.html', **locals()) @route('/get-hours', methods=['POST']) def get_hours_worked(self): self.wcc.check_roles_and_route(['Tutor', 'Administrator']) if flask_session['USERNAME'] in ['Student', 'Tutor', 'Administrator', 'Observer']: return "No user selected" start = str(json.loads(request.data).get('start')) end = str(json.loads(request.data).get('end')) start = datetime.strptime(start, '%a %b %d %Y') end = datetime.strptime(end, '%a %b %d %Y') appointments, time = self.sc.get_appt_hours(start, end, flask_session['USERNAME']) user = self.sc.get_user_by_username(flask_session['USERNAME']) start = start.strftime('%B %d %Y') end = end.strftime('%B %d %Y') return render_template('statistics/hours_worked_table.html', **locals(), id_to_user=self.sc.get_user_by_id) @route('/handle-stats-change', methods=['POST']) def handle_stats_change(self): self.wcc.check_roles_and_route(['Observer', 'Administrator']) start = str(json.loads(request.data).get('startDate')) end = str(json.loads(request.data).get('endDate')) start = datetime.strptime(start, '%a %b %d %Y') end = datetime.strptime(end, '%a %b %d %Y') value = str(json.loads(request.data).get('value')) stat_id = str(json.loads(request.data).get('id')) # We store what 'page' we are on last so check which 'page' we were last on and apply those tables to it if stat_id == 'busyness' or flask_session['STATISTICS-PAGE'] == 'busyness' and stat_id != 'course-busyness': appointments, walk_in_appts, no_show_appts, busiest_day, busiest_tod, busiest_week, busiest_tutors \ = self.get_statistics_data(start, end, value, stat_id) elif stat_id == 'course-busyness' or flask_session['STATISTICS-PAGE'] == 'course-busyness': appointments, walk_in_appts, no_show_appts, courses = self.get_statistics_data(start, end, value, stat_id) else: # If we aren't on the busyness or course-busyness page, then we are on the homepage appointments, walk_in_appts, no_show_appts, = self.get_statistics_data(start, end, value, stat_id) # print(flask_session['DATE-SELECTOR-START']) return render_template('statistics/statistics_tables.html', **locals()) def get_statistics_data(self, start, end, value, stat_id=''): self.wcc.check_roles_and_route(['Observer', 'Administrator']) # Set stored values flask_session['DATE-SELECTOR-START'] = start flask_session['DATE-SELECTOR-END'] = end flask_session['DATE-SELECTOR-VALUE'] = value # If stat_id is date-appt-change that means that either the date or type of appointment we are viewing has # changed so we must check which 'page' we are on by looking at what is stored in the session if stat_id == 'date-appt-change': stat_id = flask_session['STATISTICS-PAGE'] else: # Else we are changing which 'page' we are saving that we are on flask_session['STATISTICS-PAGE'] = stat_id # Gets some basic appointment data appointments = self.sc.get_appointments(start, end, value) walk_in_appts = self.sc.get_walk_in_appointments(start, end, value) no_show_appts = self.sc.get_no_show_appointments(start, end, value) appts_list = [] appts_list.extend(appointments) appts_list.extend(walk_in_appts) # If stat_id == busyness then we are only looking at busyness statistics so only return them to save time if stat_id == 'busyness': # Used to get the busiest week(s) busiest_week = {} beginning_of_week = start mid_week = start # Assume that we are starting on a Sunday in_mid_week = False # If we aren't starting on a Sunday then we are somewhere in the middle of the week if start.weekday() != 6: in_mid_week = True while start < end: # If our iterator, start, is Sunday, we can just keep moving a week forward in time to get our date # range if start.weekday() == 6: # If we started in the middle of the week, than our first date range is going to be different than # the rest of our date ranges so we have some custom logic for it if in_mid_week: in_mid_week = False beginning_of_week = beginning_of_week.replace(hour=0, minute=0, second=0) mid_week = mid_week.replace(hour=23, minute=59, second=59) week_str = '{0} - {1}'.format(beginning_of_week.strftime('%m/%d/%Y'), mid_week.strftime('%m/%d/%Y')) busiest_week.update({ week_str: { 'start': beginning_of_week, 'end': mid_week, 'count': 0 } }) # Update values beginning_of_week = start start += timedelta(weeks=1) # Add a week for next session end_of_week = start - timedelta(days=1) beginning_of_week = beginning_of_week.replace(hour=0, minute=0, second=0) end_of_week = end_of_week.replace(hour=23, minute=59, second=59) # If end_of_week is less than our end date, then we are still iterating through the dates so we can # create our current week date range using the beginning_of_week and end_of_week variables if end_of_week < end: week_str = '{0} - {1}'.format(beginning_of_week.strftime('%m/%d/%Y'), end_of_week.strftime('%m/%d/%Y')) busiest_week.update({ week_str: { 'start': beginning_of_week, 'end': end_of_week, 'count': 0 } }) else: # If end is greater or equal to end_of_week, then we are stopping at some point midweek, so we # have this custom logic to create the final week date range end = end.replace(hour=23, minute=59, second=59) week_str = '{0} - {1}'.format(beginning_of_week.strftime('%m/%d/%Y'), end.strftime('%m/%d/%Y')) busiest_week.update({ week_str: { 'start': beginning_of_week, 'end': end, 'count': 0 } }) else: # Moves us to the next day until we are on a Sunday mid_week = start # If the next day is equal to the end of the date range, then we haven't encountered a Sunday and # thus we should just show our week as the first start value and the end value. Once start is # updated below, we will break out of the while loop if start + timedelta(days=1) == end: beginning_of_week = beginning_of_week.replace(hour=0, minute=0, second=0) end = end.replace(hour=23, minute=59, second=59) week_str = '{0} - {1}'.format(beginning_of_week.strftime('%m/%d/%Y'), end.strftime('%m/%d/%Y')) busiest_week.update({ week_str: { 'start': beginning_of_week, 'end': end, 'count': 0 } }) # else we will increase the day by 1 to keep searching for a Sunday start += timedelta(days=1) # Adds a day until we are on sunday busiest_day = {} busiest_tod = {} busiest_tutors = {} for appt in appts_list: # Used to get the busiest day(s) if appt.scheduledStart and appt.scheduledEnd: date = appt.scheduledStart.strftime('%b %d %Y') else: date = appt.actualStart.strftime("%b %d %Y") try: if busiest_day[date] != None: count = busiest_day[date] + 1 busiest_day.update({ date: count }) except Exception as e: busiest_day.update({ date: 1 }) # Used to get busiest time(s) of day if appt.scheduledStart and appt.scheduledEnd: timeslot = '{0} - {1}'.format(self.sc.datetimeformat(appt.scheduledStart), self.sc.datetimeformat(appt.scheduledEnd)) else: timeslot = '{0} - {1} (Walk In)'.format(self.sc.datetimeformat(appt.actualStart), self.sc.datetimeformat(appt.actualEnd)) try: if busiest_tod[timeslot] != None: count = busiest_tod[timeslot] + 1 busiest_tod.update({ timeslot: count }) except Exception as e: busiest_tod.update({ timeslot: 1 }) # Used to get busiest week(s) for week in busiest_week: if appt.scheduledStart and appt.scheduledEnd: time_start = appt.scheduledStart time_end = appt.scheduledEnd else: time_start = appt.actualStart time_end = appt.actualEnd if time_start > busiest_week[week]['start'] and time_end < busiest_week[week]['end']: count = busiest_week[week]['count'] + 1 busiest_week[week].update({ 'count': count }) # Used to get busiest tutor(s) tutor = self.sc.get_user_by_id(appt.tutor_id) tutor_str = '{0} {1} ({2})'.format(tutor.firstName, tutor.lastName, tutor.username) try: if busiest_tutors[tutor_str] != None: count = busiest_tutors[tutor_str] + 1 busiest_tutors.update({ tutor_str: count }) except Exception as e: busiest_tutors.update({ tutor_str: 1 }) return appointments, walk_in_appts, no_show_appts, busiest_day, busiest_tod, busiest_week, busiest_tutors elif stat_id == 'course-busyness': # Else if stat_id == course-busyness we are only looking at courses so only return that data courses = {} for appt in appts_list: # Used to get the Courses course_str = '{0} {1}'.format(appt.courseCode, appt.courseSection) try: if courses[course_str] != None: count = courses[course_str]['count'] + 1 courses[course_str].update({ 'count': count }) except Exception as e: if appt.courseCode: course_code = appt.courseCode tag = appt.courseCode[-1:] if tag.isalpha() and tag.isupper(): course_code = appt.courseCode[:-1] courses.update({ course_str: { 'courseCode': course_code, 'tag': tag, 'section': appt.courseSection, 'profName': appt.profName, 'count': 1 } }) else: courses.update({ course_str: { 'courseCode': course_code, 'tag': '', 'section': appt.courseSection, 'profName': appt.profName, 'count': 1 } }) return appointments, walk_in_appts, no_show_appts, courses else: # Else we are on the statistics homepage so only return general appointment information return appointments, walk_in_appts, no_show_appts
def __init__(self): self.sc = StatisticsController() self.wcc = WritingCenterController()
class ProfileView(FlaskView): route_base = '/profile' def __init__(self): self.pc = ProfileController() self.wcc = WritingCenterController() self.mcc = MessageCenterController() @route('/edit') def index(self): self.wcc.check_roles_and_route( ['Student', 'Tutor', 'Observer', 'Administrator']) user = self.pc.get_user_by_username(flask_session['USERNAME']) preferences = self.mcc.get_email_preferences() return render_template('profile/profile.html', **locals()) @route('/save-edits', methods=['POST']) def save_edits(self): self.wcc.check_roles_and_route( ['Student', 'Tutor', 'Observer', 'Administrator']) try: form = request.form first_name = form.get('first-name') last_name = form.get('last-name') username = form.get('username') if isinstance( form.get('shift'), str ): # if shift is there, the box is checked and should be set to true self.mcc.toggle_shift(1) else: # otherwise, it should be set to false self.mcc.toggle_shift(0) if isinstance( form.get('substitute'), str ): # if sub is there, the box is checked and should be set to true self.mcc.toggle_substitute(1) else: # otherwise, it should be set to false self.mcc.toggle_substitute(0) self.pc.edit_user(first_name, last_name, username) # Need to reset the users name, which appears in the upper right corner flask_session['NAME'] = '{0} {1}'.format(first_name, last_name) flask_session.modified = True self.wcc.set_alert('success', 'Your profile has been edited successfully!') except Exception as error: self.wcc.set_alert( 'danger', 'Failed to edit your profile: {0}.'.format(str(error))) return redirect(url_for('ProfileView:index')) @route('/view-role') def role_viewer(self): self.wcc.check_roles_and_route(['Administrator']) role_list = self.pc.get_all_roles() return render_template('profile/role_viewer.html', **locals()) @route('/change-role', methods=['POST']) def change_role(self): self.wcc.check_roles_and_route(['Administrator']) if not flask_session['ADMIN-VIEWER']: form = request.form role_id = form.get('role') role = self.pc.get_role(role_id) flask_session['ADMIN-VIEWER'] = True # Saving old info to return too flask_session['ADMIN-USERNAME'] = flask_session['USERNAME'] flask_session['ADMIN-ROLES'] = flask_session['USER-ROLES'] flask_session['ADMIN-NAME'] = flask_session['NAME'] # Setting up viewing role flask_session['USERNAME'] = role.name flask_session['NAME'] = "" flask_session['USER-ROLES'] = role.name return redirect(url_for('View:index')) @route('/toggle-substitute', methods=['POST']) def toggle_substitute(self): self.wcc.check_roles_and_route(['Tutor', 'Observer', 'Administrator']) data = request.form return self.mcc.toggle_substitute(int(data['substitute'])) @route('/toggle-shift', methods=['POST']) def toggle_shift(self): self.wcc.check_roles_and_route(['Tutor', 'Observer', 'Administrator']) data = request.form return self.mcc.toggle_shift(data['shift'])
def __init__(self): self.pc = ProfileController() self.wcc = WritingCenterController() self.mcc = MessageCenterController()
def __init__(self): self.ac = AppointmentsController() self.wcc = WritingCenterController() self.mcc = MessageCenterController() self.wsapi = WSAPIController()
class AppointmentsView(FlaskView): route_base = 'appointments' def __init__(self): self.ac = AppointmentsController() self.wcc = WritingCenterController() self.mcc = MessageCenterController() self.wsapi = WSAPIController() @route('schedule') def schedule_appointment_landing(self): self.wcc.check_roles_and_route(['Student', 'Administrator']) return render_template('appointments/schedule_appointment.html', **locals()) @route('view-all-appointments') def view_appointments(self): self.wcc.check_roles_and_route(['Observer', 'Administrator']) return render_template('appointments/view_appointments.html', **locals()) @route('load-appointment-data', methods=['POST']) def load_appointment_data(self): self.wcc.check_roles_and_route(['Student', 'Tutor', 'Observer', 'Administrator']) appt_id = json.loads(request.data).get('id') schedule = json.loads(request.data).get('schedule') cancel = json.loads(request.data).get('cancel') pickup_sub_delete = json.loads(request.data).get('subDelete') tutor_edit = json.loads(request.data).get('tutorEdit') add_google_calendar = json.loads(request.data).get('gcalAdd', None) show_zoom_url = json.loads(request.data).get('zoom-url', None) if 'Tutor' not in flask_session['USER-ROLES']: tutor_edit = False appointment = self.ac.get_appointment_by_id(appt_id) walk_in_hours = True if appointment.dropIn == 1 else False student = self.ac.get_user_by_id(appointment.student_id) student_name = 'None' student_email = 'None' if student: student_name = '{0} {1}'.format(student.firstName, student.lastName) student_email = student.email tutor = self.ac.get_user_by_id(appointment.tutor_id) tutor_name = 'None' if tutor: tutor_name = '{0} {1}'.format(tutor.firstName, tutor.lastName) courses = self.wsapi.get_student_courses(flask_session['USERNAME']) zoom_url = self.ac.get_zoom_url()[0] return render_template('macros/appointment_modal.html', **locals()) @route('load-appointments', methods=['POST']) def load_appointments(self): self.wcc.check_roles_and_route(['Student', 'Observer', 'Administrator']) dates = json.loads(request.data).get('dates') schedule_appt = json.loads(request.data).get('scheduleAppt') start = dates['start'] end = dates['end'] start = start.replace("T", " ").split(" ")[0] start = datetime.strptime(start, '%Y-%m-%d') end = end.replace("T", " ").split(" ")[0] end = datetime.strptime(end, '%Y-%m-%d').date() - timedelta(days=1) end = datetime.combine(end, datetime.max.time()) if schedule_appt: time_limit = int(self.ac.get_time_limit()[0]) range_appointments = self.ac.get_open_appointments_in_range(start, end, time_limit) open_no_show_appts = self.ac.get_no_show_appointments_in_range(start, end, time_limit) range_appointments.extend(open_no_show_appts) else: range_appointments = self.ac.get_appointments_in_range(start, end) walk_in_appointments = self.ac.get_walk_in_appointments_in_range(start, end) range_appointments.extend(walk_in_appointments) appointments = [] # Formats the times to match the fullcalendar desired format if range_appointments: for appointment in range_appointments: if appointment.actualStart and appointment.actualEnd: start_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format(appointment.actualStart.year, appointment.actualStart.strftime('%m'), appointment.actualStart.strftime('%d'), appointment.actualStart.strftime('%H'), appointment.actualStart.strftime('%M'), appointment.actualStart.strftime('%S')) end_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format(appointment.actualEnd.year, appointment.actualEnd.strftime('%m'), appointment.actualEnd.strftime('%d'), appointment.actualEnd.strftime('%H'), appointment.actualEnd.strftime('%M'), appointment.actualEnd.strftime('%S')) elif appointment.scheduledStart and appointment.scheduledEnd: start_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format(appointment.scheduledStart.year, appointment.scheduledStart.strftime('%m'), appointment.scheduledStart.strftime('%d'), appointment.scheduledStart.strftime('%H'), appointment.scheduledStart.strftime('%M'), appointment.scheduledStart.strftime('%S')) end_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format(appointment.scheduledEnd.year, appointment.scheduledEnd.strftime('%m'), appointment.scheduledEnd.strftime('%d'), appointment.scheduledEnd.strftime('%H'), appointment.scheduledEnd.strftime('%M'), appointment.scheduledEnd.strftime('%S')) else: start_time = None end_time = None tutor = self.ac.get_user_by_id(appointment.tutor_id) appointments.append({ 'id': appointment.id, 'studentId': appointment.student_id, 'tutorName': '{0} {1}'.format(tutor.firstName, tutor.lastName), 'startTime': start_time, 'endTime': end_time, 'multilingual': appointment.multilingual, 'virtual': appointment.online, 'dropIn': appointment.dropIn, 'sub': appointment.sub }) return jsonify(appointments) def appointments_and_walk_ins(self): self.wcc.check_roles_and_route(['Tutor', 'Administrator']) tutor = flask_session['USERNAME'] appointments = self.ac.get_scheduled_appointments(tutor) in_progress_appointments = self.ac.get_in_progress_appointments(tutor) in_progress_walk_ins = self.ac.get_in_progress_walk_ins(tutor) appointments.extend(in_progress_appointments) appointments.extend(in_progress_walk_ins) users = {} for appt in appointments: user = self.ac.get_user_by_id(appt.student_id) if user != None: name = '{0} {1}'.format(user.firstName, user.lastName) else: name = "" users.update({appt.student_id: name}) return render_template('appointments/appointments_and_walk_ins.html', **locals()) @route('/begin-checks', methods=['POST']) def begin_walk_in_checks(self): self.wcc.check_roles_and_route(['Tutor', 'Administrator']) username = str(json.loads(request.data).get('username')) if not self.wsapi.get_names_from_username(username): self.wcc.set_alert('danger', 'Username ' + username + ' is not valid. Please try again with a valid username.') return 'invalid username' exists = self.ac.check_for_existing_user(username) if exists: self.ac.reactivate_user(exists.id) else: name = self.wsapi.get_names_from_username(username) self.ac.create_user(username, name) courses = self.wsapi.get_student_courses(username) return render_template('appointments/appointment_sign_in.html', **locals()) @route('begin-walk-in', methods=['POST']) def begin_walk_in(self): self.wcc.check_roles_and_route(['Tutor', 'Administrator']) form = request.form username = form.get('username') course = form.get('course') assignment = form.get('assignment') multilingual = int(form.get('multi')) if 'no-course' == course: course = None else: student_courses = self.wsapi.get_student_courses(username) for key in student_courses: if student_courses[key]['crn'] == course: course_code = '{0}{1}'.format(student_courses[key]['subject'], student_courses[key]['cNumber']) instructor_email = '{0}@bethel.edu'.format(student_courses[key]['instructorUsername']) course = { 'course_code': course_code, 'section': student_courses[key]['section'], 'instructor': student_courses[key]['instructor'], 'instructor_email': instructor_email } break user = self.ac.get_user_by_username(username) tutor = self.ac.get_user_by_username(flask_session['USERNAME']) appt = self.ac.begin_walk_in_appointment(user, tutor, course, assignment, multilingual) if not appt: self.wcc.set_alert('danger', 'Walk in appointment failed to be started.') return self.appointments_and_walk_ins() self.wcc.set_alert('success', 'Appointment for ' + user.firstName + ' ' + user.lastName + ' started.') return redirect(url_for('AppointmentsView:in_progress_appointment', appt_id=appt.id)) @route('search-appointments') def search_appointments(self): self.wcc.check_roles_and_route(['Observer', 'Administrator']) students = self.ac.get_users_by_role("Student") tutors = self.ac.get_users_by_role("Tutor") profs = self.ac.get_profs() courses = self.ac.get_courses() return render_template('appointments/search_appointments.html', **locals()) @route('view-appointments') def student_view_appointments(self): self.wcc.check_roles_and_route(['Student', 'Administrator']) return render_template('appointments/student_view_appointments.html', **locals()) @route('get-appointments', methods=['GET']) def get_users_appointments(self): self.wcc.check_roles_and_route(['Student', 'Administrator']) if flask_session['USERNAME'] in ['Student', 'Tutor', 'Administrator', 'Observer']: return '' appts = self.ac.get_all_user_appointments(flask_session['USERNAME']) appointments = [] # Formats the times to match the fullcalendar desired format for appointment in appts: if appointment.actualStart and appointment.actualEnd: start_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format(appointment.actualStart.year, appointment.actualStart.strftime('%m'), appointment.actualStart.strftime('%d'), appointment.actualStart.strftime('%H'), appointment.actualStart.strftime('%M'), appointment.actualStart.strftime('%S')) end_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format(appointment.actualEnd.year, appointment.actualEnd.strftime('%m'), appointment.actualEnd.strftime('%d'), appointment.actualEnd.strftime('%H'), appointment.actualEnd.strftime('%M'), appointment.actualEnd.strftime('%S')) elif appointment.scheduledStart and appointment.scheduledEnd: start_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format(appointment.scheduledStart.year, appointment.scheduledStart.strftime('%m'), appointment.scheduledStart.strftime('%d'), appointment.scheduledStart.strftime('%H'), appointment.scheduledStart.strftime('%M'), appointment.scheduledStart.strftime('%S')) end_time = '{0}-{1}-{2}T{3}:{4}:{5}'.format(appointment.scheduledEnd.year, appointment.scheduledEnd.strftime('%m'), appointment.scheduledEnd.strftime('%d'), appointment.scheduledEnd.strftime('%H'), appointment.scheduledEnd.strftime('%M'), appointment.scheduledEnd.strftime('%S')) else: start_time = None end_time = None tutor = self.ac.get_user_by_id(appointment.tutor_id) appointments.append({ 'id': appointment.id, 'studentId': appointment.student_id, 'tutorName': '{0} {1}'.format(tutor.firstName, tutor.lastName), 'startTime': start_time, 'endTime': end_time, 'multilingual': appointment.multilingual, 'dropIn': appointment.dropIn }) return jsonify(appointments) @route('schedule-appointment', methods=['POST']) def schedule_appointment(self): self.wcc.check_roles_and_route(['Student', 'Administrator']) appt_id = str(json.loads(request.data).get('appt_id')) course = str(json.loads(request.data).get('course')) assignment = str(json.loads(request.data).get('assignment')) username = flask_session['USERNAME'] if username in ['Administrator', 'Observer', 'Tutor', 'Student']: self.wcc.set_alert('danger', 'You cannot schedule an appointment while acting as a role.') else: # Checks if the user already exists in WC DB. If a user does, we either continue or reactivate them. If they # don't exist then we create them exists = self.ac.check_for_existing_user(username) if not exists: name = self.wsapi.get_names_from_username(username) self.ac.create_user(username, name) user = self.ac.get_user_by_username(username) # Checks to make sure the user isn't banned. if not user.bannedDate: # Checks to make sure the user is part of CAS. roles = self.wsapi.get_roles_for_username(username) cas = False for role in roles: if 'STUDENT-CAS' == roles[role]['userRole']: cas = True if flask_session['USERNAME'] == 'schapr': cas = True if cas: appt = self.ac.get_appointment_by_id(appt_id) # Checks to make sure the student hasn't scheduled the limit of appointments per week. appt_limit = int(self.ac.get_appointment_limit()[0]) date = appt.scheduledStart weekly_appts = self.ac.get_weekly_users_appointments(user.id, date) if len(weekly_appts) < appt_limit: # Checks to make sure the student isn't scheduled for an appointment that overlaps with the one they # are trying to schedule. already_scheduled = False user_appointments = self.ac.get_future_user_appointments(user.id) for appointment in user_appointments: if appointment.scheduledStart <= appt.scheduledStart < appointment.scheduledEnd or \ appointment.scheduledStart < appt.scheduledEnd <= appointment.scheduledEnd: already_scheduled = True if already_scheduled: self.wcc.set_alert('danger', 'Failed to schedule appointment! You already have an appointment ' 'that overlaps with the one you are trying to schedule.') else: # Sets course to none if no specific course was selected for the appointment. if 'no-course' == course: course = None else: # Gets information about the selected course for the appointment. student_courses = self.wsapi.get_student_courses(username) for key in student_courses: if student_courses[key]['crn'] == course: course_code = '{0}{1}'.format(student_courses[key]['subject'], student_courses[key]['cNumber']) instructor_email = '{0}@bethel.edu'.format(student_courses[key]['instructorUsername']) course = { 'course_code': course_code, 'section': student_courses[key]['section'], 'instructor': student_courses[key]['instructor'], 'instructor_email': instructor_email } break # Schedules the appointment and sends an email to the student and tutor if it is scheduled # successfully. if not self.ac.get_appointment_by_id(appt_id).student_id: appt = self.ac.schedule_appointment(appt_id, course, assignment) if appt: self.mcc.appointment_signup_student(appt_id) self.mcc.appointment_signup_tutor(appt_id) self.wcc.set_alert('success', 'Your Appointment Has Been Scheduled! To View Your ' 'Appointments, Go To The "View Your Appointments" Page!') else: self.wcc.set_alert('danger', 'Error! Appointment Not Scheduled!') else: self.wcc.set_alert('danger', 'Appointment has already been scheduled by someone else. Please try again.') else: self.wcc.set_alert('danger', 'Failed to schedule appointment. You already have ' + str(appt_limit) + ' appointments scheduled and can\'t schedule any more.') else: # TODO MAYBE GIVE THEM A SPECIFIC EMAIL TO EMAIL? self.wcc.set_alert('danger', 'Appointment NOT scheduled! Only CAS students can schedule' ' appointments here. If you wish to schedule an appointment email a' ' Writing Center Administrator.') else: # TODO MAYBE GIVE THEM A SPECIFIC EMAIL TO EMAIL? self.wcc.set_alert('danger', 'You are banned from making appointments! If you have any questions email a' ' Writing Center Administrator.') # Returns the appointment id to remove it from the scheduling calendar. return appt_id @route('cancel-appointment', methods=['POST']) def cancel_appointment(self): self.wcc.check_roles_and_route(['Student', 'Administrator']) appt_id = str(json.loads(request.data).get('appt_id')) cancelled = self.ac.cancel_appointment(appt_id) if cancelled: self.mcc.cancel_appointment_student(appt_id) self.wcc.set_alert('success', 'Successfully cancelled appointment.') else: self.wcc.set_alert('danger', 'Failed to cancel appointment.') return appt_id @route('start-appt/<int:appt_id>') def start_appointment(self, appt_id): try: self.ac.start_appointment(appt_id) self.wcc.set_alert('success', 'Appointment Started Successfully!') return redirect(url_for('AppointmentsView:in_progress_appointment', appt_id=appt_id)) except Exception as error: self.wcc.set_alert('danger', 'Failed to start appointment: {0}.'.format(error)) return redirect(url_for('AppointmentsView:appointments_and_walk_ins')) @route('toggle-no-show/<int:appt_id>') def toggle_no_show(self, appt_id): try: appt = self.ac.get_appointment_by_id(appt_id) student = self.ac.get_user_by_id(appt.student_id) if appt.noShow == 0: self.ac.mark_no_show(appt_id) self.ac.ban_if_no_show_check(appt.student_id) self.wcc.set_alert('success', '{0} {1} successfully marked as no show.'.format(student.firstName, student.lastName)) else: self.ac.revert_no_show(appt_id) self.wcc.set_alert('success', '{0} {1} no longer marked as no show.'.format(student.firstName, student.lastName)) except Exception as error: self.wcc.set_alert('danger', 'Failed to toggle no show: {0}.'.format(error)) return redirect(url_for('AppointmentsView:appointments_and_walk_ins')) @route('toggle-multilingual/<int:appt_id>') def toggle_multilingual(self, appt_id): try: appt = self.ac.get_appointment_by_id(appt_id) student = self.ac.get_user_by_id(appt.student_id) if appt.multilingual == 0: self.ac.mark_multilingual(appt_id) self.wcc.set_alert('success', '{0} {1}\'s appointment successfully marked as multilingual.'.format(student.firstName, student.lastName)) else: self.ac.revert_multilingual(appt_id) self.wcc.set_alert('success', '{0} {1}\'s appointment no longer marked as multilingual.'.format(student.firstName, student.lastName)) except Exception as error: self.wcc.set_alert('danger', 'Failed to toggle multilingual: {0}.'.format(error)) return redirect(url_for('AppointmentsView:appointments_and_walk_ins')) @route('end-appt/<int:appt_id>', methods=['post', 'get']) def end_appointment(self, appt_id): form = request.form course = form.get('course') assignment = form.get('assignment') notes = form.get('notes') suggestions = form.get('suggestions') ferpa_agreement = True if form.get('ferpa') == 'on' else False if 'no-course' == course: course = None else: appt = self.ac.get_appointment_by_id(appt_id) student = self.ac.get_user_by_id(appt.student_id) student_courses = self.wsapi.get_student_courses(student.username) for key in student_courses: if student_courses[key]['crn'] == course: course_code = '{0}{1}'.format(student_courses[key]['subject'], student_courses[key]['cNumber']) instructor_email = '{0}@bethel.edu'.format(student_courses[key]['instructorUsername']) course = { 'course_code': course_code, 'section': student_courses[key]['section'], 'instructor': student_courses[key]['instructor'], 'instructor_email': instructor_email } break try: self.ac.end_appointment(appt_id, course, assignment, notes, suggestions) self.mcc.close_session_student(appt_id) if ferpa_agreement: self.mcc.end_appt_prof(appt_id) qualtrics_link = self.ac.get_survey_link()[0] self.wcc.set_alert('success', 'Appointment ended successfully!') return render_template('appointments/end_appointment.html', **locals()) except Exception as error: self.wcc.set_alert('danger', 'Failed to end appointment: {0}.'.format(error)) return redirect(url_for('AppointmentsView:in_progress_appointment', appt_id=appt_id)) @route('in-progress/<int:appt_id>') def in_progress_appointment(self, appt_id): appt = self.ac.get_appointment_by_id(appt_id) student = self.ac.get_user_by_id(appt.student_id) courses = self.wsapi.get_student_courses(student.username) zoom_url = self.ac.get_zoom_url()[0] return render_template('appointments/in_progress_appointment.html', **locals()) @route('save-changes', methods=['POST']) def save_changes(self): self.wcc.check_roles_and_route(['Tutor']) appt_id = json.loads(request.data).get('appt_id') assignment = str(json.loads(request.data).get('assignment')) notes = str(json.loads(request.data).get('notes')) suggestions = str(json.loads(request.data).get('suggestions')) success = self.ac.tutor_change_appt(appt_id, assignment, notes, suggestions) if success: return 'close' else: return 'failed' @route('/search', methods=['POST']) def search(self): self.wcc.check_roles_and_route(['Observer', 'Administrator']) form = request.form student = None if form.get('student') == 'None' else int(form.get('student')) tutor = None if form.get('tutor') == 'None' else int(form.get('tutor')) prof = None if form.get('prof') == 'None' else form.get('prof') course = None if form.get('course') == 'None' else form.get('course') start = form.get('start') start_date = None if start == '' else datetime.strptime(start, "%a %b %d %Y") end = form.get('end') end_date = None if end == '' else datetime.strptime(end, "%a %b %d %Y") # If no parameters sent in return the following message if student is None and tutor is None and prof is None and course is None and start_date is None and end_date is None: return 'Please enter parameters to search by.' appointments = self.ac.search_appointments(student, tutor, prof, course, start_date, end_date) appts_and_info = {} for appt in appointments: appts_and_info[appt] = { 'student': self.ac.get_user_by_id(appt.student_id), 'tutor': self.ac.get_user_by_id(appt.tutor_id) } return render_template('appointments/appointment_search_table.html', **locals()) @route('/edit/<int:appt_id>', methods=['GET', 'POST']) def edit(self, appt_id): self.wcc.check_roles_and_route(['Administrator']) appt = self.ac.get_appointment_by_id(appt_id) all_tutors = self.ac.get_users_by_role('Tutor') all_students = self.ac.get_all_users() all_profs = self.ac.get_profs_and_emails() all_courses = self.ac.get_courses() return render_template('appointments/edit_appointment.html', **locals()) @route('/submit-edits', methods=['POST']) def submit_edits(self): self.wcc.check_roles_and_route(['Administrator']) form = request.form appt_id = int(form.get('id')) tutor_id = None if form.get('tutor') == '-1' else int(form.get('tutor')) student_id = None if form.get('student') == '-1' else int(form.get('student')) date = None if form.get('date') == '' else form.get('date') sched_start_time = None if form.get('sched-start') == '' else form.get('sched-start') sched_end_time = None if form.get('sched-end') == '' else form.get('sched-end') if not date: self.wcc.set_alert('danger', 'You must select a date.') return redirect(url_for('AppointmentsView:edit', appt_id=appt_id)) if sched_start_time and sched_end_time: sched_start_time = "{0} {1}".format(datetime.strptime(date, '%a %b %d %Y').strftime("%Y-%m-%d"), sched_start_time) sched_end_time = "{0} {1}".format(datetime.strptime(date, '%a %b %d %Y').strftime("%Y-%m-%d"), sched_end_time) actual_start_time = None if form.get('actual-start') == '' else form.get('actual-start') actual_end_time = None if form.get('actual-end') == '' else form.get('actual-end') actual_start = None if not actual_start_time else "{0} {1}".format(datetime.strptime(date, '%a %b %d %Y').strftime("%Y-%m-%d"), actual_start_time) actual_end = None if not actual_end_time else "{0} {1}".format(datetime.strptime(date, '%a %b %d %Y').strftime("%Y-%m-%d"), actual_end_time) prof = None if form.get('prof') == 'None' else form.get('prof') prof_email = None if form.get('email') == 'None' else form.get('email') course = None if form.get('course') == 'None' else form.get('course') section = None if form.get('section') == 'None' else int(form.get('section')) assignment = None if form.get('assignment') == 'None' else form.get('assignment') notes = None if form.get('notes') == 'None' else form.get('notes') suggestions = None if form.get('suggestions') == 'None' else form.get('suggestions') sub = int(form.get('sub-req')) drop_in = int(form.get('drop-in-check')) multilingual = int(form.get('multi-check')) virtual = int(form.get('virtual-check')) no_show = int(form.get('no-show-check')) in_progress = int(form.get('in-progress-check')) try: self.ac.edit_appt(appt_id, student_id, tutor_id, sched_start_time, sched_end_time, actual_start, actual_end, prof, prof_email, drop_in, virtual, sub, assignment, notes, suggestions, multilingual, course, section, no_show, in_progress) self.wcc.set_alert('success', 'Appointment edited successfully!') except Exception as e: self.wcc.set_alert('danger', 'Failed to edit appointment: {0}.'.format(str(e))) return redirect(url_for('AppointmentsView:edit', appt_id=appt_id))
def __init__(self): self.sc = SettingsController() self.wcc = WritingCenterController()
class SettingsView(FlaskView): def __init__(self): self.sc = SettingsController() self.wcc = WritingCenterController() @route('/') def index(self): self.wcc.check_roles_and_route(['Administrator']) settings = self.sc.get_settings() return render_template('settings/index.html', **locals()) @route('change-settings', methods=['POST']) def change_settings(self): self.wcc.check_roles_and_route(['Administrator']) form = request.form setting_name = form.get('setting_name') new_setting = form.get('new_setting') try: self.sc.update_setting(setting_name, new_setting) self.wcc.set_alert('success', 'Settings updated successfully!') return 'success' except Exception as error: self.wcc.set_alert('danger', 'Failed to update settings: {0}.'.format(str(error))) return 'failed' @route('cleanse', methods=['get']) def cleanse(self): self.wcc.check_roles_and_route(['Administrator']) try: self.sc.cleanse() self.wcc.set_alert('success', 'System cleansed successfully!') except Exception as error: self.wcc.set_alert('danger', 'Failed to cleanse system: {0}.'.format(str(error))) return redirect(url_for('SettingsView:index'))
def __init__(self): self.base = MessageCenterController() self.wcc = WritingCenterController()
def __init__(self): self.uc = UsersController() self.wsapi = WSAPIController() self.wcc = WritingCenterController()
class UsersView(FlaskView): route_base = '/user' def __init__(self): self.uc = UsersController() self.wsapi = WSAPIController() self.wcc = WritingCenterController() @route('/manage-bans/') def manage_bans(self): self.wcc.check_roles_and_route(['Administrator']) users = self.uc.get_banned_users() return render_template('users/manage_bans.html', **locals()) @route('/view-users') def view_all_users(self): self.wcc.check_roles_and_route(['Administrator']) users_query = self.uc.get_users() users = {} for user, role in users_query: try: if users[user.id]['roles'] != None: roles = '{0}, {1}'.format(users[user.id]['roles'], role.name) users.update({ user.id: { 'id': user.id, 'username': user.username, 'firstName': user.firstName, 'lastName': user.lastName, 'email': user.email, 'roles': roles } }) except: users.update({ user.id: { 'id': user.id, 'username': user.username, 'firstName': user.firstName, 'lastName': user.lastName, 'email': user.email, 'roles': role.name } }) return render_template('users/view_all_users.html', **locals()) @route("/add-user") def add_user(self): self.wcc.check_roles_and_route(['Administrator']) return render_template('users/add_user.html', **locals()) @route("/search-users", methods=['POST']) def search_users(self): self.wcc.check_roles_and_route(['Administrator']) form = request.form first_name = form.get('firstName') last_name = form.get('lastName') results = self.wsapi.get_username_from_name(first_name, last_name) return render_template('users/user_search_results.html', **locals()) @route('/create/<username>/<first_name>/<last_name>') def select_user_roles(self, username, first_name, last_name): self.wcc.check_roles_and_route(['Administrator']) roles = self.uc.get_all_roles() existing_user = self.uc.get_user_by_username(username) if existing_user: # User exists in system if existing_user.deletedAt: # Has been deactivated in the past success = self.uc.activate_existing_user(existing_user.id) if success: message = 'This user has been deactivated in the past, but now they are reactivated with their '\ 'same roles.' else: message = 'Failed to reactivate the user.' return render_template('users/select_user_roles.html', **locals()) @route('/create-user', methods=['POST']) def create_user(self): self.wcc.check_roles_and_route(['Administrator']) form = request.form first_name = form.get('first-name') last_name = form.get('last-name') username = form.get('username') roles = form.getlist('roles') sub_email_pref = 0 # Default sending emails to No stu_email_pref = 0 # Default sending emails to No # If the user is a administrator or a professor, they get emails. if 'Administrator' in roles: sub_email_pref = 1 stu_email_pref = 1 if 'Tutor' in roles: stu_email_pref = 1 try: self.uc.create_user(first_name, last_name, username, sub_email_pref, stu_email_pref) self.uc.set_user_roles(username, roles) self.wcc.set_alert( 'success', '{0} {1} ({2}) added successfully!'.format( first_name, last_name, username)) return redirect(url_for('UsersView:view_all_users')) except Exception as error: self.wcc.set_alert('danger', 'Failed to add user: {0}.'.format(str(error))) return redirect( url_for('UsersView:select_user_roles', username=username, first_name=first_name, last_name=last_name)) @route("/edit/<int:user_id>") def edit_user(self, user_id): self.wcc.check_roles_and_route(['Administrator']) user = self.uc.get_user_by_id(user_id) roles = self.uc.get_all_roles() user_role_ids = self.uc.get_user_role_ids(user_id) return render_template('users/edit_user.html', **locals()) @route('/save-user-edits', methods=['POST']) def save_user_edits(self): self.wcc.check_roles_and_route(['Administrator']) form = request.form user_id = form.get('user-id') username = form.get('username') first_name = form.get('first-name') last_name = form.get('last-name') email = form.get('email') roles = form.getlist('roles') try: self.uc.update_user_info(user_id, first_name, last_name, email) self.uc.clear_current_roles(user_id) self.uc.set_user_roles(username, roles) self.wcc.set_alert( 'success', '{0} {1} edited successfully!'.format(first_name, last_name)) return redirect(url_for('UsersView:view_all_users')) except Exception as error: self.wcc.set_alert('danger', 'Failed to edit user: {0}.'.format(str(error))) return redirect(url_for('UsersView:edit_user', user_id=user_id)) @route("/remove-ban/", methods=['POST']) def remove_ban(self): self.wcc.check_roles_and_route(['Administrator']) user_id = str(json.loads(request.data).get('id')) self.uc.remove_user_ban(user_id) return redirect(url_for('UsersView:manage_bans')) @route("/unban-all", methods=['POST']) def remove_all_bans(self): self.wcc.check_roles_and_route(['Administrator']) self.uc.remove_all_bans() return redirect(url_for('UsersView:manage_bans')) @route('/search-ban-users', methods=['POST']) def search_ban_users(self): self.wcc.check_roles_and_route(['Administrator']) form = request.form first_name = form.get('firstName') last_name = form.get('lastName') users = self.uc.get_users_by_name(first_name, last_name) return render_template('users/user_ban_search_results.html', **locals()) @route('/ban/user/', methods=['POST']) def save_user_ban(self): self.wcc.check_roles_and_route(['Administrator']) form = request.form username = form.get('username') user = self.uc.get_user_by_username(username) appointments = self.uc.get_future_user_appointments(user.id) for appt in appointments: self.uc.cancel_appointment(appt.id) if flask_session['USERNAME'] == username: self.wcc.set_alert('danger', 'Error! You Can\'t Ban Yourself!') else: self.uc.ban_user(username) return redirect(url_for('UsersView:manage_bans')) def act_as_user(self, user_id): self.wcc.check_roles_and_route(['Administrator']) if not flask_session['ADMIN-VIEWER']: user_info = self.uc.get_user_by_id(user_id) flask_session['ADMIN-VIEWER'] = True # Saving old info to return to flask_session['ADMIN-USERNAME'] = flask_session['USERNAME'] flask_session['ADMIN-ROLES'] = flask_session['USER-ROLES'] flask_session['ADMIN-NAME'] = flask_session['NAME'] # Setting up viewing role flask_session['USERNAME'] = user_info.username flask_session['NAME'] = '{0} {1}'.format(user_info.firstName, user_info.lastName) flask_session['USER-ROLES'] = [] user_roles = self.uc.get_user_roles(user_info.id) for role in user_roles: flask_session['USER-ROLES'].append(role.name) return redirect(url_for('View:index')) @route('/reset-act-as', methods=['POST']) def reset_act_as(self): if flask_session['ADMIN-VIEWER']: try: # Resetting info flask_session['USERNAME'] = flask_session['ADMIN-USERNAME'] flask_session['ADMIN-VIEWER'] = False flask_session['NAME'] = flask_session['ADMIN-NAME'] flask_session['USER-ROLES'] = flask_session['ADMIN-ROLES'] # Clearing out unneeded variables flask_session.pop('ADMIN-USERNAME') flask_session.pop('ADMIN-ROLES') flask_session.pop('ADMIN-NAME') return redirect(url_for('View:index')) except Exception as error: self.wcc.set_alert( 'danger', 'An error occurred: {0}.'.format(str(error))) return redirect(url_for('View:index')) else: self.wcc.set_alert( 'danger', 'You do not have permission to access this function.') return redirect(url_for('View:index')) @route('/deactivate/<int:user_id>', methods=['POST', 'GET']) def deactivate_user(self, user_id): self.wcc.check_roles_and_route(['Administrator']) try: self.uc.deactivate_user(user_id) self.wcc.set_alert('success', 'Users deactivated successfully!') return redirect(url_for("UsersView:view_all_users")) except Exception as e: self.wcc.set_alert('danger', 'Failed to deactivate user(s).') return redirect(url_for("UsersView:edit", user_id=user_id)) @route("/deactivate-users", methods=['post']) def deactivate_users(self): self.wcc.check_roles_and_route(['Administrator']) form = request.form json_user_ids = form.get('jsonUserIds') user_ids = json.loads(json_user_ids) try: for user in user_ids: self.uc.deactivate_user(user) self.wcc.set_alert('success', 'User(s) deactivated successfully!') except Exception as error: self.wcc.set_alert( 'danger', 'Failed to deactivate user(s): {0}.'.format(str(error))) return 'done' # Return doesn't matter: success or failure take you to the same page. Only the alert changes.