class Spot(models.Model):
    """ Represents a place for students to study.
    """
    spot_id = models.IntegerField()
    name = models.CharField(max_length=100, blank=True)
    uri = models.CharField(max_length=255)
    thumbnail_root = models.CharField(max_length=255)
    latitude = models.DecimalField(max_digits=11, decimal_places=8, null=True)
    longitude = models.DecimalField(max_digits=11, decimal_places=8, null=True)
    height_from_sea_level = models.DecimalField(max_digits=11,
                                                decimal_places=8,
                                                null=True,
                                                blank=True)
    building_name = models.CharField(max_length=100, blank=True)
    floor = models.CharField(max_length=50, blank=True)
    room_number = models.CharField(max_length=25, blank=True)
    building_description = models.CharField(max_length=100, blank=True)
    capacity = models.IntegerField(null=True, blank=True)
    display_access_restrictions = models.CharField(max_length=200, blank=True)
    organization = models.CharField(max_length=50, blank=True)
    manager = models.CharField(max_length=50, blank=True)
    etag = models.CharField(max_length=40)
    last_modified = models.DateTimeField()
    external_id = models.CharField(max_length=100,
                                   null=True,
                                   blank=True,
                                   default=None,
                                   unique=True)
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 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 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
        }