class AdminUser(Base): __tablename__ = 'admin_users' id = db.Column(db.Integer, nullable=False, primary_key=True) # noqa: A003 uid = db.Column(db.String(255), nullable=False, unique=True) deleted_at = db.Column(db.DateTime, nullable=True) def __init__(self, uid): self.uid = uid def __repr__(self): return f"""<AdminUser uid={self.uid}, created_at={self.created_at}, updated_at={self.updated_at}> """ @classmethod def delete(cls, uid): now = utc_now() user = cls.query.filter_by(uid=uid).first() user.deleted_at = now std_commit() return user @classmethod def all_admin_users(cls, include_deleted=False): query = cls.query if include_deleted else cls.query.filter_by(deleted_at=None) return query.order_by(cls.uid).all() @classmethod def is_admin(cls, uid, include_deleted=False): query = cls.query.filter_by(uid=uid) if include_deleted else cls.query.filter_by(uid=uid, deleted_at=None) return query.first() is not None
class QueuedEmail(db.Model): __tablename__ = 'queued_emails' id = db.Column(db.Integer, nullable=False, primary_key=True) # noqa: A003 subject_line = db.Column(db.String(255)) message = db.Column(db.Text) recipient = db.Column(JSONB) section_id = db.Column(db.Integer, nullable=False) template_type = db.Column(email_template_type, nullable=False) term_id = db.Column(db.Integer, nullable=False) created_at = db.Column(db.DateTime, nullable=False, default=datetime.now) __table_args__ = (db.UniqueConstraint( 'section_id', 'template_type', 'term_id', name='queued_emails_section_id_template_type_unique_constraint', ),) def __init__(self, section_id, template_type, term_id, recipient, message=None, subject_line=None): self.template_type = template_type self.section_id = section_id self.term_id = term_id self.recipient = recipient self.message = message self.subject_line = subject_line def __repr__(self): return f"""<QueuedEmail id={self.id} section_id={self.section_id}, template_type={self.template_type} term_id={self.term_id}, recipient={self.recipient}, message={self.message}, subject_line={self.subject_line}, created_at={self.created_at} """ @classmethod def create(cls, section_id, template_type, term_id, recipient, message=None, subject_line=None): course = SisSection.get_course(term_id, section_id, include_deleted=True) if not course: app.logger.error(f'Attempt to queue email for unknown course (term_id={term_id}, section_id={section_id})') return if not course['instructors']: app.logger.error(f'Attempt to queue email for course without instructors (term_id={term_id}, section_id={section_id})') return queued_email = cls( section_id=section_id, template_type=template_type, term_id=term_id, recipient=recipient, message=message, subject_line=subject_line, ) course = SisSection.get_course(term_id, queued_email.section_id, include_deleted=True) if not queued_email.is_interpolated() and not queued_email.interpolate(course): app.logger.error(f'Failed to interpolate all required values for queued email ({queued_email})') return db.session.add(queued_email) std_commit() return queued_email @classmethod def delete(cls, queued_email): db.session.delete(queued_email) std_commit() @classmethod def get_all(cls, term_id): return cls.query.filter_by(term_id=term_id).order_by(cls.created_at).all() @classmethod def get_all_section_ids(cls, template_type, term_id): return [row.section_id for row in cls.query.filter_by(template_type=template_type, term_id=term_id).all()] def is_interpolated(self): return not(self.subject_line is None or self.message is None or self.recipient is None) def interpolate(self, course): template = _get_email_template(course=course, template_type=self.template_type) if template: self.subject_line = interpolate_content( course=course, templated_string=template.subject_line, recipient_name=self.recipient['name'], ) self.message = interpolate_content( course=course, templated_string=template.message, recipient_name=self.recipient['name'], ) db.session.add(self) std_commit() # Return True only if all required data has been set. return self.is_interpolated def to_api_json(self): return { 'id': self.id, 'sectionId': self.section_id, 'templateType': self.template_type, 'templateTypeName': EmailTemplate.get_template_type_options()[self.template_type], 'termId': self.term_id, 'createdAt': to_isoformat(self.created_at), }
class Job(Base): __tablename__ = 'jobs' id = db.Column(db.Integer, nullable=False, primary_key=True) # noqa: A003 disabled = db.Column(db.Boolean, nullable=False) job_schedule_type = db.Column(job_schedule_types, nullable=False) job_schedule_value = db.Column(db.String(80), nullable=False) key = db.Column(db.String(80), nullable=False, unique=True) def __init__(self, disabled, job_schedule_type, job_schedule_value, key): self.disabled = disabled self.job_schedule_type = job_schedule_type self.job_schedule_value = job_schedule_value self.key = key def __repr__(self): return f"""<Job disabled={self.disabled}, job_schedule_type={self.job_schedule_type}, job_schedule_value={self.job_schedule_value}, key={self.key}> """ @classmethod def create(cls, job_schedule_type, job_schedule_value, key, disabled=False): job = cls( job_schedule_type=job_schedule_type, job_schedule_value=job_schedule_value, key=key, disabled=disabled, ) db.session.add(job) std_commit() return job @classmethod def update_disabled(cls, job_id, disable): job = cls.query.filter_by(id=job_id).first() job.disabled = disable db.session.add(job) std_commit() return job @classmethod def update_schedule(cls, job_id, schedule_type, schedule_value): job = cls.query.filter_by(id=job_id).first() job.job_schedule_type = schedule_type job.job_schedule_value = schedule_value db.session.add(job) std_commit() return job @classmethod def get_all(cls, include_disabled=False): if include_disabled: return cls.query.order_by(cls.key).all() else: return cls.query.filter_by(disabled=False).order_by(cls.key).all() @classmethod def get_job(cls, job_id): return cls.query.filter_by(id=job_id).first() @classmethod def get_job_by_key(cls, key): return cls.query.filter_by(key=key).first() def to_api_json(self): return { 'id': self.id, 'disabled': self.disabled, 'key': self.key, 'schedule': { 'type': self.job_schedule_type, 'value': int(self.job_schedule_value) if self.job_schedule_type in ['minutes', 'seconds'] else self.job_schedule_value, }, 'createdAt': to_isoformat(self.created_at), 'updatedAt': to_isoformat(self.updated_at), }
class Instructor(Base): __tablename__ = 'instructors' uid = db.Column(db.String(255), primary_key=True) dept_code = db.Column(db.String(80)) email = db.Column(db.String(255)) first_name = db.Column(db.String(255)) last_name = db.Column(db.String(255)) def __init__( self, dept_code, email, first_name, last_name, uid, ): self.dept_code = dept_code self.email = email self.first_name = first_name self.last_name = last_name self.uid = uid def __repr__(self): return f"""<Instructor dept_code={', '.join(self.dept_code)}, email={self.email}, first_name={self.first_name}, last_name={self.last_name}, uid={self.uid}, created_at={self.created_at}, updated_at={self.updated_at}> """ @classmethod def upsert(cls, rows): now = utc_now().strftime('%Y-%m-%dT%H:%M:%S+00') count_per_chunk = 10000 for chunk in range(0, len(rows), count_per_chunk): rows_subset = rows[chunk:chunk + count_per_chunk] query = """ INSERT INTO instructors ( created_at, dept_code, email, first_name, last_name, uid, updated_at ) SELECT created_at, dept_code, email, first_name, last_name, uid, updated_at FROM json_populate_recordset(null::instructors, :json_dumps) ON CONFLICT(uid) DO UPDATE SET dept_code = EXCLUDED.dept_code, email = EXCLUDED.email, first_name = EXCLUDED.first_name, last_name = EXCLUDED.last_name; """ data = [{ 'created_at': now, 'dept_code': row['dept_code'], 'email': row['email'], 'first_name': row['first_name'], 'last_name': row['last_name'], 'uid': row['uid'], 'updated_at': now, } for row in rows_subset] db.session.execute(query, {'json_dumps': json.dumps(data)})
class Scheduled(db.Model): __tablename__ = 'scheduled' id = db.Column(db.Integer, nullable=False, primary_key=True) # noqa: A003 section_id = db.Column(db.Integer, nullable=False) term_id = db.Column(db.Integer, nullable=False) alerts = db.Column(ARRAY(email_template_type)) instructor_uids = db.Column(ARRAY(db.String(80)), nullable=False) kaltura_schedule_id = db.Column(db.Integer, nullable=False) meeting_days = db.Column(db.String, nullable=False) meeting_end_date = db.Column(db.DateTime, nullable=False) meeting_end_time = db.Column(db.String, nullable=False) meeting_start_date = db.Column(db.DateTime, nullable=False) meeting_start_time = db.Column(db.String, nullable=False) publish_type = db.Column(publish_type, nullable=False) recording_type = db.Column(recording_type, nullable=False) room_id = db.Column(db.Integer, db.ForeignKey('rooms.id'), nullable=False) created_at = db.Column(db.DateTime, nullable=False, default=datetime.now) deleted_at = db.Column(db.DateTime, nullable=True) def __init__( self, section_id, term_id, instructor_uids, kaltura_schedule_id, meeting_days, meeting_end_date, meeting_end_time, meeting_start_date, meeting_start_time, publish_type_, recording_type_, room_id, ): self.section_id = section_id self.term_id = term_id self.instructor_uids = instructor_uids self.kaltura_schedule_id = kaltura_schedule_id self.meeting_days = meeting_days self.meeting_end_date = meeting_end_date self.meeting_end_time = meeting_end_time self.meeting_start_date = meeting_start_date self.meeting_start_time = meeting_start_time self.publish_type = publish_type_ self.recording_type = recording_type_ self.room_id = room_id def __repr__(self): return f"""<Scheduled id={self.id}, section_id={self.section_id}, term_id={self.term_id}, alerts={', '.join(self.alerts or [])}, instructor_uids={', '.join(self.instructor_uids)}, kaltura_schedule_id={self.kaltura_schedule_id} meeting_days={self.meeting_days}, meeting_end_date={self.meeting_end_date}, meeting_end_time={self.meeting_end_time}, meeting_start_date={self.meeting_start_date}, meeting_start_time={self.meeting_start_time}, publish_type={self.publish_type}, recording_type={self.recording_type}, room_id={self.room_id}, created_at={self.created_at}> """ @classmethod def create( cls, section_id, term_id, instructor_uids, kaltura_schedule_id, meeting_days, meeting_end_date, meeting_end_time, meeting_start_date, meeting_start_time, publish_type_, recording_type_, room_id, ): scheduled = cls( instructor_uids=instructor_uids, kaltura_schedule_id=kaltura_schedule_id, meeting_days=meeting_days, meeting_end_date=meeting_end_date, meeting_end_time=meeting_end_time, meeting_start_date=meeting_start_date, meeting_start_time=meeting_start_time, publish_type_=publish_type_, recording_type_=recording_type_, room_id=room_id, section_id=section_id, term_id=term_id, ) db.session.add(scheduled) std_commit() return scheduled @classmethod def get_all_scheduled(cls, term_id): return cls.query.filter_by(term_id=term_id, deleted_at=None).all() @classmethod def get_scheduled_per_section_ids(cls, section_ids, term_id): criteria = and_(cls.section_id.in_(section_ids), cls.term_id == term_id, cls.deleted_at == None) # noqa: E711 return cls.query.filter(criteria).order_by(cls.created_at).all() @classmethod def get_scheduled(cls, section_id, term_id): return cls.query.filter_by(section_id=section_id, term_id=term_id, deleted_at=None).first() @classmethod def delete(cls, section_id, term_id): sql = """UPDATE scheduled SET deleted_at = now() WHERE term_id = :term_id AND section_id = :section_id AND deleted_at IS NULL""" db.session.execute( text(sql), { 'section_id': section_id, 'term_id': term_id, }, ) @classmethod def add_alert(cls, scheduled_id, template_type): row = cls.query.filter_by(id=scheduled_id).first() if row.alerts: row.alerts = list(set(row.alerts + [template_type])) else: row.alerts = [template_type] db.session.add(row) std_commit() def to_api_json(self, rooms_by_id=None): room_feed = None if self.room_id: if rooms_by_id: room_feed = rooms_by_id.get(self.room_id, None).to_api_json() else: room_feed = Room.get_room(self.room_id).to_api_json() formatted_days = format_days(self.meeting_days) return { 'id': self.id, 'alerts': self.alerts or [], 'createdAt': to_isoformat(self.created_at), 'instructorUids': self.instructor_uids, 'kalturaScheduleId': self.kaltura_schedule_id, 'meetingDays': formatted_days, 'meetingDaysNames': get_names_of_days(formatted_days), 'meetingEndDate': datetime.strftime(self.meeting_end_date, '%Y-%m-%d'), 'meetingEndTime': self.meeting_end_time, 'meetingEndTimeFormatted': format_time(self.meeting_end_time), 'meetingStartDate': datetime.strftime(self.meeting_start_date, '%Y-%m-%d'), 'meetingStartTime': self.meeting_start_time, 'meetingStartTimeFormatted': format_time(self.meeting_start_time), 'publishType': self.publish_type, 'publishTypeName': NAMES_PER_PUBLISH_TYPE[self.publish_type], 'recordingType': self.recording_type, 'recordingTypeName': NAMES_PER_RECORDING_TYPE[self.recording_type], 'room': room_feed, 'sectionId': self.section_id, 'termId': self.term_id, }
class JobHistory(db.Model): __tablename__ = 'job_history' id = db.Column(db.Integer, nullable=False, primary_key=True) # noqa: A003 job_key = db.Column(db.String(80), nullable=False) failed = db.Column(db.Boolean, nullable=False, default=False) started_at = db.Column(db.DateTime, nullable=False, default=datetime.now) finished_at = db.Column(db.DateTime) def __init__(self, job_key): self.job_key = job_key self.failed = False self.started_at = datetime.now() def __repr__(self): return f"""<Room id={self.id}, job_key={self.job_key}, failed={self.failed}, started_at={self.started_at}, finished_at={self.finished_at}, """ @classmethod def is_job_running(cls, job_key): return cls.query.filter_by(job_key=job_key, finished_at=None).first() is not None @classmethod def job_started(cls, job_key): row = cls(job_key=job_key) db.session.add(row) std_commit() return row @classmethod def job_finished(cls, id_, failed=False): row = cls.query.filter_by(id=id_).first() row.failed = failed row.finished_at = datetime.now() db.session.add(row) std_commit() return row @classmethod def get_job_history(cls): return cls.query.order_by(desc(cls.started_at)).all() @classmethod def last_successful_run_of(cls, job_key): criteria = and_(cls.job_key == job_key, cls.failed == False, cls.finished_at != None) # noqa: E711, E712 return cls.query.filter(criteria).order_by(desc(cls.finished_at)).limit(1).first() @staticmethod def fail_orphans(): sql = """ UPDATE job_history SET failed = TRUE, finished_at = now() WHERE finished_at IS NULL""" db.session.execute(text(sql)) @staticmethod def expire_old_rows(days): sql = f"DELETE FROM job_history WHERE started_at < (now() - INTERVAL '{days} DAYS')" db.session.execute(text(sql)) def to_api_json(self): return { 'id': self.id, 'jobKey': self.job_key, 'failed': self.failed, 'startedAt': to_isoformat(self.started_at), 'finishedAt': self.finished_at and to_isoformat(self.finished_at), }
class SentEmail(db.Model): __tablename__ = 'sent_emails' id = db.Column(db.Integer, nullable=False, primary_key=True) # noqa: A003 recipient_uids = db.Column(ARRAY(db.String(80)), nullable=False) section_id = db.Column(db.Integer) template_type = db.Column(email_template_type) term_id = db.Column(db.Integer, nullable=False) sent_at = db.Column(db.DateTime, nullable=False, default=datetime.now) def __init__(self, recipient_uids, section_id, template_type, term_id): self.recipient_uids = recipient_uids self.template_type = template_type self.section_id = section_id self.term_id = term_id def __repr__(self): return f"""<SentEmail id={self.id} recipient_uids={', '.join(self.recipient_uids)} section_id={self.section_id}, template_type={self.template_type} term_id={self.term_id}, sent_at={self.sent_at} """ @classmethod def create(cls, recipient_uids, section_id, template_type, term_id): sent_email = cls( recipient_uids=recipient_uids, section_id=section_id, template_type=template_type, term_id=term_id, ) db.session.add(sent_email) std_commit() return sent_email @classmethod def get_emails_sent_to(cls, uid): return cls.query.filter(cls.recipient_uids.any(uid)).order_by( cls.sent_at).all() @classmethod def get_emails_of_type(cls, section_id, template_type, term_id): return cls.query.filter_by( section_id=section_id, template_type=template_type, term_id=term_id, ).order_by(cls.sent_at).all() def to_api_json(self): return { 'id': self.id, 'recipientUids': self.recipient_uids, 'sectionId': self.section_id, 'templateType': self.template_type, 'templateTypeName': EmailTemplate.get_template_type_options()[self.template_type], 'termId': self.term_id, 'sentAt': to_isoformat(self.sent_at), }
class Room(db.Model): __tablename__ = 'rooms' id = db.Column(db.Integer, nullable=False, primary_key=True) # noqa: A003 capability = db.Column(room_capability_type) is_auditorium = db.Column(db.Boolean, nullable=False) kaltura_resource_id = db.Column(db.Integer) location = db.Column(db.String(255), nullable=False, unique=True) created_at = db.Column(db.DateTime, nullable=False, default=datetime.now) def __init__( self, capability, is_auditorium, kaltura_resource_id, location, ): self.capability = capability self.is_auditorium = is_auditorium self.kaltura_resource_id = kaltura_resource_id self.location = location def __repr__(self): return f"""<Room id={self.id}, capability={self.capability}, location={self.location}, is_auditorium={self.is_auditorium}, kaltura_resource_id={self.kaltura_resource_id}, created_at={self.created_at}> """ @classmethod def create(cls, location, is_auditorium=False, kaltura_resource_id=None, capability=None): room = cls( capability=capability, is_auditorium=is_auditorium, kaltura_resource_id=kaltura_resource_id, location=location, ) db.session.add(room) std_commit() return room @classmethod def find_room(cls, location): return cls.query.filter_by(location=location).first() @classmethod def get_room(cls, room_id): return cls.query.filter_by(id=room_id).first() @classmethod def get_rooms(cls, room_ids): return cls.query.filter(cls.id.in_(room_ids)).all() @classmethod def get_rooms_in_locations(cls, locations): return cls.query.filter(cls.location.in_(locations)).all() @classmethod def all_rooms(cls): return cls.query.order_by(cls.capability, cls.location).all() @classmethod def total_room_count(cls): return db.session.query(func.count(cls.id)).scalar() @classmethod def get_all_locations(cls): result = db.session.execute(text('SELECT location FROM rooms')) return [row['location'] for row in result] @classmethod def get_room_id(cls, section_id, term_id): sql = """ SELECT r.id AS room_id FROM rooms r JOIN sis_sections s ON s.meeting_location = r.location WHERE s.section_id = :section_id AND s.term_id = :term_id """ rows = db.session.execute( text(sql), { 'section_id': section_id, 'term_id': term_id, }, ) ids_ = [row['room_id'] for row in rows] return ids_[0] if ids_ else None @classmethod def update_capability(cls, room_id, capability): room = cls.query.filter_by(id=room_id).first() room.capability = capability db.session.add(room) std_commit() return room @classmethod def update_kaltura_resource_mappings(cls, kaltura_resource_ids_per_room): # First, set kaltura_resource_id = null on all rows cls.query.update({cls.kaltura_resource_id: None}) # Next, insert the latest mappings all_rooms_per_id = dict((room.id, room) for room in cls.all_rooms()) for room_id, kaltura_resource_id in kaltura_resource_ids_per_room.items( ): room = all_rooms_per_id[room_id] room.kaltura_resource_id = kaltura_resource_id db.session.add(room) std_commit() @classmethod def set_auditorium(cls, room_id, is_auditorium): room = cls.query.filter_by(id=room_id).first() room.is_auditorium = is_auditorium db.session.add(room) std_commit() return room @classmethod def get_room_capability_options(cls): return { 'screencast': 'Screencast', 'screencast_and_video': 'Screencast + Video', } def to_api_json(self): recording_type_options = { 'presentation_audio': 'Presentation + Audio', } if self.is_auditorium: recording_type_options['presenter_audio'] = 'Presenter + Audio' recording_type_options[ 'presenter_presentation_audio'] = 'Presenter + Presentation + Audio' return { 'id': self.id, 'location': self.location, 'capability': self.capability, 'capabilityName': self.get_room_capability_options()[self.capability] if self.capability else None, 'createdAt': to_isoformat(self.created_at), 'isAuditorium': self.is_auditorium, 'kalturaResourceId': self.kaltura_resource_id, 'recordingTypeOptions': recording_type_options, }
class EmailTemplate(Base): __tablename__ = 'email_templates' id = db.Column(db.Integer, nullable=False, primary_key=True) # noqa: A003 template_type = db.Column(email_template_type, nullable=False) name = db.Column(db.String(255), nullable=False, unique=True) subject_line = db.Column(db.String(255), nullable=False) message = db.Column(db.Text, nullable=False) def __init__( self, template_type, name, subject_line, message, ): self.template_type = template_type self.name = name self.subject_line = subject_line self.message = message def __repr__(self): return f"""<EmailTemplate id={self.id}, template_type={self.template_type}, name={self.name}, subject_line={self.subject_line} message={self.message}> """ @classmethod def create(cls, template_type, name, subject_line, message): email_template = cls( template_type=template_type, name=name, subject_line=subject_line, message=message, ) db.session.add(email_template) std_commit() return email_template @classmethod def delete_template(cls, template_id): db.session.delete(cls.query.filter_by(id=template_id).first()) std_commit() @classmethod def get_template(cls, template_id): return cls.query.filter_by(id=template_id).first() @classmethod def get_template_by_type(cls, template_type): return cls.query.filter_by(template_type=template_type).first() @classmethod def get_all_templates_names(cls): return cls.query.with_entities(cls.id, cls.name).order_by(cls.name).all() @classmethod def all_templates(cls): return cls.query.order_by().all() @classmethod def update(cls, template_id, template_type, name, subject_line, message): email_template = cls.query.filter_by(id=template_id).first() email_template.template_type = template_type email_template.name = name email_template.subject_line = subject_line email_template.message = message db.session.add(email_template) std_commit() return email_template @classmethod def get_template_type_options(cls): return { 'admin_alert_instructor_change': 'Admin alert of instructor change', 'admin_alert_room_change': 'Admin alert: Room change', 'invitation': 'Invitation', 'notify_instructor_of_changes': 'Notify instructor of changes', 'recordings_scheduled': 'Recordings scheduled', 'room_change_no_longer_eligible': 'Room change: No longer eligible', 'waiting_for_approval': 'Waiting for approval', } def to_api_json(self): return { 'id': self.id, 'templateType': self.template_type, 'typeName': self.get_template_type_options()[self.template_type], 'name': self.name, 'subjectLine': self.subject_line, 'message': self.message, 'createdAt': to_isoformat(self.created_at), 'updatedAt': to_isoformat(self.updated_at), }
class Scheduled(db.Model): __tablename__ = 'scheduled' section_id = db.Column(db.Integer, nullable=False, primary_key=True) term_id = db.Column(db.Integer, nullable=False, primary_key=True) cross_listed_section_ids = db.Column(ARRAY(db.Integer)) instructor_uids = db.Column(ARRAY(db.String(80)), nullable=False) meeting_days = db.Column(db.String, nullable=False) meeting_start_time = db.Column(db.String, nullable=False) meeting_end_time = db.Column(db.String, nullable=False) publish_type = db.Column(publish_type, nullable=False) recording_type = db.Column(recording_type, nullable=False) room_id = db.Column(db.Integer, db.ForeignKey('rooms.id'), nullable=False) created_at = db.Column(db.DateTime, nullable=False, default=datetime.now) def __init__( self, section_id, term_id, cross_listed_section_ids, instructor_uids, meeting_days, meeting_start_time, meeting_end_time, publish_type_, recording_type_, room_id, ): self.section_id = section_id self.term_id = term_id self.cross_listed_section_ids = cross_listed_section_ids self.instructor_uids = instructor_uids self.meeting_days = meeting_days self.meeting_start_time = meeting_start_time self.meeting_end_time = meeting_end_time self.publish_type = publish_type_ self.recording_type = recording_type_ self.room_id = room_id def __repr__(self): return f"""<Scheduled section_id={self.section_id}, term_id={self.term_id}, cross_listed_section_ids={self.cross_listed_section_ids}, instructor_uids={', '.join(self.instructor_uids)}, meeting_days={self.meeting_days}, meeting_start_time={self.meeting_start_time}, meeting_end_time={self.meeting_end_time}, publish_type={self.publish_type}, recording_type={self.recording_type}, room_id={self.room_id}, created_at={self.created_at}> """ @classmethod def create( cls, section_id, term_id, cross_listed_section_ids, instructor_uids, meeting_days, meeting_start_time, meeting_end_time, publish_type_, recording_type_, room_id, ): scheduled = cls( cross_listed_section_ids=cross_listed_section_ids, instructor_uids=instructor_uids, meeting_days=meeting_days, meeting_start_time=meeting_start_time, meeting_end_time=meeting_end_time, publish_type_=publish_type_, recording_type_=recording_type_, room_id=room_id, section_id=section_id, term_id=term_id, ) db.session.add(scheduled) std_commit() return scheduled @classmethod def get_all_scheduled(cls, term_id): return cls.query.filter_by(term_id=term_id).all() @classmethod def get_scheduled_per_section_ids(cls, section_ids, term_id): criteria = and_(cls.section_id.in_(section_ids), cls.term_id == term_id) return cls.query.filter(criteria).order_by(cls.created_at).all() @classmethod def get_scheduled(cls, section_id, term_id): return cls.query.filter_by(section_id=section_id, term_id=term_id).first() def to_api_json(self): return { 'createdAt': to_isoformat(self.created_at), 'crossListedSectionIds': self.cross_listed_section_ids, 'instructorUids': self.instructor_uids, 'meetingDays': format_days(self.meeting_days), 'meetingEndTime': format_time(self.meeting_end_time), 'meetingStartTime': format_time(self.meeting_start_time), 'publishType': self.publish_type, 'publishTypeName': NAMES_PER_PUBLISH_TYPE[self.publish_type], 'recordingType': self.recording_type, 'recordingTypeName': NAMES_PER_RECORDING_TYPE[self.recording_type], 'room': Room.get_room(self.room_id).to_api_json() if self.room_id else None, 'sectionId': self.section_id, 'termId': self.term_id, }
class Blackout(Base): __tablename__ = 'blackouts' id = db.Column(db.Integer, nullable=False, primary_key=True) # noqa: A003 name = db.Column(db.String(255), nullable=False, unique=True) start_date = db.Column(db.DateTime, nullable=False) end_date = db.Column(db.DateTime, nullable=False) def __init__(self, name, start_date, end_date): self.name = name self.start_date = start_date self.end_date = end_date def __repr__(self): return f"""<Blackout id={self.id}, name={self.name}, start_date={to_isoformat(self.start_date)}, end_date={to_isoformat(self.end_date)}, """ @classmethod def create(cls, name, start_date, end_date): blackout = cls( name=name, start_date=start_date, end_date=end_date, ) db.session.add(blackout) std_commit() return blackout @classmethod def delete_blackout(cls, blackout_id): db.session.delete(cls.query.filter_by(id=blackout_id).first()) std_commit() @classmethod def get_blackout(cls, blackout_id): return cls.query.filter_by(id=blackout_id).first() @classmethod def get_all_blackouts_names(cls): return cls.query.with_entities(cls.id, cls.name).order_by(cls.name).all() @classmethod def all_blackouts(cls): return cls.query.order_by().all() @classmethod def update(cls, blackout_id, name, start_date, end_date): blackout = cls.query.filter_by(id=blackout_id).first() blackout.name = name blackout.start_date = start_date blackout.end_date = end_date db.session.add(blackout) std_commit() return blackout def to_api_json(self): def _format(date): return localize_datetime(date).strftime('%Y-%m-%d') return { 'id': self.id, 'name': self.name, 'startDate': _format(self.start_date), 'endDate': _format(self.end_date), 'createdAt': to_isoformat(self.created_at), 'updatedAt': to_isoformat(self.updated_at), }