class Activity(models.Model): assignment_date = models.DateTimeField() comment = models.TextField() user = models.CharField(max_length=12) assignment_type = models.TextField() cohort_number = models.IntegerField() major_abbr = models.CharField(max_length=32) major_program_code = models.CharField(max_length=32) total_submitted = models.IntegerField() total_assigned = models.IntegerField()
class Submission(models.Model): submission_id = models.IntegerField() body = models.TextField(null=True) attempt = models.IntegerField(max_length=2) submitted_at = models.DateTimeField() assignment_id = models.IntegerField() assignment_visible = models.BooleanField(null=True) workflow_state = models.CharField(max_length=100, null=True) preview_url = models.CharField(max_length=500) late = models.NullBooleanField() grade = models.TextField(max_length=12, null=True) score = models.DecimalField(max_digits=10, decimal_places=2, null=True) grade_matches_current_submission = models.NullBooleanField() url = models.CharField(max_length=500, null=True) grader_id = models.IntegerField() graded_at = models.DateTimeField(null=True) posted_at = models.DateTimeField(null=True) submission_type = models.CharField(max_length=100, null=True) def __init__(self, *args, **kwargs): self.attachments = [] data = kwargs.get("data") if data is None: return super(Submission, self).__init__(*args, **kwargs) self.submission_id = data['id'] self.body = data['body'] self.attempt = data['attempt'] if "submitted_at" in data and data["submitted_at"] is not None: self.submitted_at = dateutil.parser.parse(data["submitted_at"]) self.assignment_id = data["assignment_id"] self.workflow_state = data["workflow_state"] self.preview_url = data["preview_url"] self.late = data["late"] self.grade = data["grade"] self.score = data["score"] self.grade_matches_current_submission = data.get( "grade_matches_current_submission") self.url = data["url"] self.grader_id = data["grader_id"] if "graded_at" in data and data["graded_at"] is not None: self.graded_at = dateutil.parser.parse(data["graded_at"]) if "posted_at" in data and data["posted_at"] is not None: self.posted_at = dateutil.parser.parse(data["posted_at"]) self.submission_type = data["submission_type"] # assignment_visible is not always present self.assignment_visible = data.get("assignment_visible") for attachment_data in data.get("attachments", []): self.attachments.append(Attachment(data=attachment_data))
class Assignment(models.Model): assignment_type = models.CharField() quarter = models.IntegerField() campus = models.IntegerField() comments = models.TextField() user = models.CharField(max_length=12) applicants = []
class GradingStandard(models.Model): COURSE_CONTEXT = "Course" ACCOUNT_CONTEXT = "Account" CONTEXT_CHOICES = ((COURSE_CONTEXT, COURSE_CONTEXT), (ACCOUNT_CONTEXT, ACCOUNT_CONTEXT)) grading_standard_id = models.IntegerField() title = models.CharField(max_length=500) context_id = models.IntegerField() context_type = models.CharField(max_length=20, choices=CONTEXT_CHOICES) grading_scheme = models.TextField() def __init__(self, *args, **kwargs): data = kwargs.get("data") if data is None: return super(GradingStandard, self).__init__(*args, **kwargs) self.grading_standard_id = data["id"] self.title = data["title"] self.context_type = data["context_type"] self.context_id = data["context_id"] self.grading_scheme = data["grading_scheme"] def json_data(self): return { "id": self.grading_standard_id, "title": self.title, "context_type": self.context_type, "context_id": self.context_id, "grading_scheme": self.grading_scheme, }
class ModelTest(models.Model): bools = models.BooleanField() chars = models.CharField(max_length=20) dates = models.DateField() datetimes = models.DateTimeField() decimals = models.DecimalField() floats = models.FloatField() ints = models.IntegerField() nullbools = models.NullBooleanField() posints = models.PositiveIntegerField() possmalls = models.PositiveSmallIntegerField() slugs = models.SlugField() smallints = models.SmallIntegerField() texts = models.TextField() texts2 = models.TextField() times = models.TimeField() urls = models.URLField()
class Cohort(models.Model): academic_qtr_id = models.IntegerField() cohort_number = models.IntegerField() cohort_description = models.TextField() cohort_residency = models.CharField(max_length=255) admit_decision = models.CharField(max_length=255) protected_group = models.BooleanField() active_cohort = models.BooleanField() assigned_count = models.IntegerField()
class ModelTest(models.Model): f1 = models.TextField() f2 = models.BooleanField()
class ModelTest(models.Model): f1 = models.TextField(default="Has Default") f2 = models.TextField()
class CanvasUser(models.Model): user_id = models.IntegerField() name = models.CharField(max_length=100, null=True) short_name = models.CharField(max_length=100, null=True) sortable_name = models.CharField(max_length=100, null=True) sis_user_id = models.CharField(max_length=100, null=True) login_id = models.CharField(max_length=100, null=True) time_zone = models.CharField(max_length=100, null=True) locale = models.CharField(max_length=2, null=True) email = models.CharField(max_length=100, null=True) avatar_url = models.CharField(max_length=500, null=True) last_login = models.DateTimeField(null=True) bio = models.TextField(null=True) def __init__(self, *args, **kwargs): self.enrollments = [] data = kwargs.get("data") if data is None: return super(CanvasUser, self).__init__(*args, **kwargs) self.user_id = data["id"] self.name = data["name"] self.short_name = data.get("short_name") self.sortable_name = data.get("sortable_name") self.login_id = data.get("login_id") self.sis_user_id = data.get("sis_user_id") self.email = data.get("email") self.time_zone = data.get("time_zone") self.locale = data.get("locale") self.avatar_url = data.get("avatar_url") self.bio = data.get("bio") if "last_login" in data and data["last_login"] is not None: self.last_login = dateutil.parser.parse(data["last_login"]) for enr_datum in data.get("enrollments", []): self.enrollments.append(CanvasEnrollment(data=enr_datum)) def json_data(self): return { "id": self.user_id, "name": self.name, "sortable_name": self.sortable_name, "short_name": self.short_name, "sis_user_id": self.sis_user_id, "login_id": self.login_id, "avatar_url": self.avatar_url, "enrollments": self.enrollments, "email": self.email, "locale": self.locale, "last_login": self.last_login.isoformat() if (self.last_login is not None) else None, "time_zone": self.time_zone, "bio": self.bio, } def post_data(self): return { "user": { "name": self.name, "short_name": self.short_name, "sortable_name": self.sortable_name, "time_zone": self.time_zone, "locale": self.locale }, "pseudonym": { "unique_id": self.login_id, "sis_user_id": self.sis_user_id, "send_confirmation": False }, "communication_channel": { "type": "email", "address": self.email, "skip_confirmation": True } }
class CanvasEnrollment(models.Model): STUDENT = "StudentEnrollment" TEACHER = "TeacherEnrollment" TA = "TaEnrollment" OBSERVER = "ObserverEnrollment" DESIGNER = "DesignerEnrollment" GUEST_TEACHER = "Guest Teacher" LIBRARIAN = "Librarian" OTHER_FACULTY = "Other Faculty" PROGRAM_STAFF = "Program Staff" ROLE_CHOICES = ( (STUDENT, "Student"), (TEACHER, "Teacher"), (TA, "TA"), (OBSERVER, "Observer"), (DESIGNER, "Designer"), ) CUSTOM_ROLES = [GUEST_TEACHER, LIBRARIAN, OTHER_FACULTY, PROGRAM_STAFF] STATUS_ACTIVE = "active" STATUS_INVITED = "invited" STATUS_PENDING = "creation_pending" STATUS_DELETED = "deleted" STATUS_REJECTED = "rejected" STATUS_COMPLETED = "completed" STATUS_INACTIVE = "inactive" STATUS_CHOICES = ((STATUS_ACTIVE, STATUS_ACTIVE), (STATUS_INVITED, STATUS_INVITED), (STATUS_PENDING, STATUS_PENDING), (STATUS_DELETED, STATUS_DELETED), (STATUS_REJECTED, STATUS_REJECTED), (STATUS_COMPLETED, STATUS_COMPLETED), (STATUS_INACTIVE, STATUS_INACTIVE)) user_id = models.IntegerField() course_id = models.IntegerField() section_id = models.IntegerField() login_id = models.CharField(max_length=80, null=True) sis_user_id = models.CharField(max_length=100, null=True) role = models.CharField(max_length=80) base_role_type = models.CharField(max_length=80, choices=ROLE_CHOICES) status = models.CharField(max_length=100, choices=STATUS_CHOICES) name = models.CharField(max_length=100) sortable_name = models.CharField(max_length=100) html_url = models.CharField(max_length=1000) sis_section_id = models.CharField(max_length=100, null=True) sis_course_id = models.CharField(max_length=100, null=True) course_url = models.CharField(max_length=2000, null=True) course_name = models.CharField(max_length=100, null=True) current_score = models.DecimalField(max_digits=10, decimal_places=2, null=True) final_score = models.DecimalField(max_digits=10, decimal_places=2, null=True) current_grade = models.TextField(max_length=12, null=True) final_grade = models.TextField(max_length=12, null=True) unposted_current_score = models.DecimalField(max_digits=10, decimal_places=2, null=True) unposted_final_score = models.DecimalField(max_digits=10, decimal_places=2, null=True) unposted_current_grade = models.TextField(max_length=12, null=True) unposted_final_grade = models.TextField(max_length=12, null=True) override_score = models.DecimalField(max_digits=10, decimal_places=2, null=True) override_grade = models.TextField(max_length=12, null=True) grade_html_url = models.CharField(max_length=1000) total_activity_time = models.IntegerField(null=True) last_activity_at = models.DateTimeField(null=True) limit_privileges_to_course_section = models.NullBooleanField() def __init__(self, *args, **kwargs): data = kwargs.get("data") if data is None: return super(CanvasEnrollment, self).__init__(*args, **kwargs) self.course = None self.user_id = data["user_id"] self.course_id = data["course_id"] self.section_id = data["course_section_id"] self.sis_course_id = data.get("sis_course_id") self.sis_section_id = data.get("sis_section_id") self.sis_user_id = data.get("sis_user_id") self.role = data["role"] self.base_role_type = data["type"] self.status = data["enrollment_state"] self.html_url = data["html_url"] self.course_url = self.get_course_url(self.html_url) self.total_activity_time = data["total_activity_time"] self.limit_privileges_to_course_section = data.get( "limit_privileges_to_course_section", False) if data["last_activity_at"] is not None: self.last_activity_at = dateutil.parser.parse( data["last_activity_at"]) if "user" in data: user_data = data["user"] self.name = user_data.get("name") self.sortable_name = user_data.get("sortable_name") self.login_id = user_data.get("login_id") if "grades" in data: gr_data = data["grades"] self.current_score = gr_data.get("current_score") self.current_grade = gr_data.get("current_grade") self.final_score = gr_data.get("final_score") self.final_grade = gr_data.get("final_grade") self.unposted_current_score = gr_data.get("unposted_current_score") self.unposted_current_grade = gr_data.get("unposted_current_grade") self.unposted_final_score = gr_data.get("unposted_final_score") self.unposted_final_grade = gr_data.get("unposted_final_grade") self.override_score = gr_data.get("override_score") self.override_grade = gr_data.get("override_grade") self.grade_html_url = gr_data.get("html_url") def get_course_url(self, html_url): return re.sub(r'/users/\d+$', '', html_url) def sws_course_id(self): return CanvasCourse(sis_course_id=self.sis_course_id).sws_course_id() def sws_section_id(self): return CanvasSection( sis_section_id=self.sis_section_id).sws_section_id() @staticmethod def sis_import_role(role): for base, name in CanvasEnrollment.ROLE_CHOICES: if role.lower() == base.lower() or role.lower() == name.lower(): return name.lower() if role in CanvasEnrollment.CUSTOM_ROLES: return role def json_data(self): return { "user_id": self.user_id, "sis_user_id": self.sis_user_id, "course_id": self.course_id, "course_url": self.course_url, "section_id": self.section_id, "login_id": self.login_id, "sis_user_id": self.sis_user_id, "role": self.role, "base_role_type": self.base_role_type, "status": self.status, "current_score": self.current_score, "current_grade": self.current_grade, "final_score": self.final_score, "final_grade": self.final_grade, "unposted_current_score": self.unposted_current_score, "unposted_current_grade": self.unposted_current_grade, "unposted_final_score": self.unposted_final_score, "unposted_final_grade": self.unposted_final_grade, "override_score": self.override_score, "override_grade": self.override_grade }
class CanvasCourse(models.Model): RE_COURSE_SIS_ID = re.compile( r"^\d{4}-" # year r"(?:winter|spring|summer|autumn)-" # quarter r"[\w& ]+-" # curriculum r"\d{3}-" # course number r"[A-Z][A-Z0-9]?" # section id r"(?:-[A-F0-9]{32})?$", # ind. study instructor regid re.VERBOSE) course_id = models.IntegerField() sis_course_id = models.CharField(max_length=100, null=True) account_id = models.IntegerField() term = models.ForeignKey(CanvasTerm, null=True) code = models.CharField(max_length=100) name = models.CharField(max_length=200) course_url = models.CharField(max_length=2000) workflow_state = models.CharField(max_length=50) public_syllabus = models.NullBooleanField() syllabus_body = models.TextField(null=True) grading_standard_id = models.IntegerField(null=True) def __init__(self, *args, **kwargs): self.students = [] data = kwargs.get("data") if data is None: return super(CanvasCourse, self).__init__(*args, **kwargs) self.course_id = data["id"] self.sis_course_id = data.get("sis_course_id") self.account_id = data["account_id"] self.code = data["course_code"] self.name = data["name"] self.workflow_state = data["workflow_state"] self.public_syllabus = data["public_syllabus"] self.grading_standard_id = data.get("grading_standard_id") course_url = data["calendar"]["ics"] course_url = re.sub(r"(.*?[a-z]/).*", r"\1", course_url) self.course_url = "{}courses/{}".format(course_url, data["id"]) if "term" in data: self.term = CanvasTerm(data=data["term"]) if "syllabus_body" in data: self.syllabus_body = data["syllabus_body"] def is_unpublished(self): return self.workflow_state.lower() == "unpublished" def sws_course_id(self): if not self.is_academic_sis_id(): return try: (year, quarter, curr_abbr, course_num, section_id, reg_id) = self.sis_course_id.split('-', 5) except ValueError: (year, quarter, curr_abbr, course_num, section_id) = self.sis_course_id.split('-', 4) return '{year},{quarter},{curr_abbr},{course_num}/{section_id}'.format( year=year, quarter=quarter.lower(), curr_abbr=curr_abbr.upper(), course_num=course_num, section_id=section_id) def sws_instructor_regid(self): if not self.is_academic_sis_id(): return try: (year, quarter, curr_abbr, course_num, section_id, reg_id) = self.sis_course_id.split('-', 5) except ValueError: reg_id = None return reg_id def is_academic_sis_id(self): if (self.sis_course_id is None or self.RE_COURSE_SIS_ID.match(self.sis_course_id) is None): return False return True