class ScheduledRecording(models.Model):
    id = models.CharField(max_length=36)
    name = models.CharField(max_length=256)
    start_time = models.DateTimeField(null=True)
    end_time = models.DateTimeField(null=True)

    def __init__(self, *args, **kwargs):
        data = kwargs.get("data")
        if data is None:
            return super(ScheduledRecording, self).__init__(*args, **kwargs)

        self.id = data.get("Id")
        self.name = data.get("Name")
        self.start_time = parse(data.get("StartTime")) if ("StartTime"
                                                           in data) else None
        self.end_time = parse(data.get("EndTime", "")) if ("EndTime"
                                                           in data) else None

    def to_json(self):
        return {
            'id': self.id,
            'name': self.name,
            'start_time': str(self.start_time) if self.start_time else None,
            'start_time': str(self.end_time) if self.end_time else None
        }

    def __str__(self):
        return json.dumps(self.to_json())
Exemple #2
0
class Reservation(models.Model):
    STANDARD_STATE = "1"
    EXCEPTION_STATE = "2"
    WARNING_STATE = "3"
    OVERRIDE_STATE = "4"
    CANCELLED_STATE = "99"

    STATE_CHOICES = (
        (STANDARD_STATE, "Standard"),
        (EXCEPTION_STATE, "Exception"),
        (WARNING_STATE, "Warning"),
        (OVERRIDE_STATE, "Override"),
        (CANCELLED_STATE, "Cancelled"),
    )

    reservation_id = models.IntegerField()
    state = models.CharField(max_length=2, choices=STATE_CHOICES)
    start_datetime = models.DateTimeField()
    end_datetime = models.DateTimeField()
    event_id = models.IntegerField()
    event_name = models.CharField(max_length=64)
    profile_name = models.CharField(max_length=32)
    contact_name = models.CharField(max_length=64)
    contact_email = models.CharField(max_length=64)

    def state_name(self):
        return dict(self.STATE_CHOICES)[self.state]

    class Meta:
        db_table = "restclients_r25_reservation"
class Quarter(models.Model):
    id = models.IntegerField()
    begin = models.DateTimeField()
    end = models.DateTimeField()
    active_ind = models.CharField(max_length=32)
    appl_yr = models.CharField(max_length=4)
    appl_qtr = models.CharField(max_length=1)
    is_current = models.BooleanField()
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 Session(models.Model):
    id = models.CharField(max_length=36)
    name = models.CharField(max_length=256)
    description = models.CharField(max_length=256)
    start_time = models.DateTimeField(null=True)
    folder = models.CharField(max_length=256)

    def __init__(self, *args, **kwargs):
        data = kwargs.get("data")
        if data is None:
            return super(Session, self).__init__(*args, **kwargs)

        self.id = data.get("Id")
        self.name = data.get("Name")
        self.description = data.get("Description")
        self.start_time = parse(data.get("StartTime")) if ("StartTime"
                                                           in data) else None
        self.folder = data.get("Folder")

    def to_json(self):
        return {
            'id': self.id,
            'name': self.name,
            'description': self.description,
            'start_time': str(self.start_time) if self.start_time else None,
            'folder': self.folder
        }

    def __str__(self):
        return json.dumps(self.to_json())
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 SpotImage(models.Model):
    """
    An image of a Spot. Multiple images can be associated with a Spot,
    and Spot objects have a 'Spot.spotimage_set' method that will return all
    SpotImage objects for the Spot.
    """

    image_id = models.IntegerField()
    url = models.CharField(max_length=255)
    description = models.CharField(max_length=200, blank=True)
    display_index = models.PositiveIntegerField(null=True, blank=True)
    content_type = models.CharField(max_length=40)
    width = models.IntegerField()
    height = models.IntegerField()
    creation_date = models.DateTimeField()
    modification_date = models.DateTimeField()
    upload_user = models.CharField(max_length=40)
    upload_application = models.CharField(max_length=100)
class ItemImage(models.Model):
    image_id = models.IntegerField()
    description = models.CharField(max_length=200, blank=True)
    display_index = models.PositiveIntegerField(null=True, blank=True)
    width = models.IntegerField()
    height = models.IntegerField()
    content_type = models.CharField(max_length=40)
    creation_date = models.DateTimeField(auto_now_add=True)
    upload_user = models.CharField(max_length=40)
    upload_application = models.CharField(max_length=100)
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 CanvasTerm(models.Model):
    term_id = models.IntegerField()
    sis_term_id = models.CharField(max_length=100, null=True)
    name = models.CharField(max_length=100)
    workflow_state = models.CharField(max_length=50)
    start_at = models.DateTimeField(null=True)
    end_at = models.DateTimeField(null=True)

    def __init__(self, *args, **kwargs):
        data = kwargs.get("data")
        if data is None:
            return super(CanvasTerm, self).__init__(*args, **kwargs)

        self.term_id = data.get('id')
        self.sis_term_id = data.get('sis_term_id')
        self.name = data.get('name')
        self.workflow_state = data.get('workflow_state')
        if 'start_at' in data and data['start_at']:
            self.start_at = dateutil.parser.parse(data['start_at'])
        if 'end_at' in data and data['end_at']:
            self.end_at = dateutil.parser.parse(data['end_at'])
        self.overrides = data.get('overrides', {})
Exemple #11
0
class UserAccount(models.Model):
    uwnetid = models.CharField(max_length=128)
    display_name = models.CharField(max_length=96, null=True, default=None)
    last_visit = models.DateTimeField(null=True, default=None)
    created_at = models.DateTimeField(null=True, default=None)

    def to_json(self):
        return {
            "uwnetid": self.uwnetid,
            "display_name": self.display_name,
            "last_visit": date_to_str(self.last_visit),
            "created_at": date_to_str(self.created_at)
        }

    def __str__(self):
        return json.dumps(self.to_json())

    def __init__(self, *args, **kwargs):
        super(UserAccount, self).__init__(*args, **kwargs)

    def __hash__(self):
        return super().__hash__()
 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 Quiz(models.Model):
    quiz_id = models.IntegerField()
    due_at = models.DateTimeField()
    title = models.CharField(max_length=500)
    html_url = models.CharField(max_length=500, null=True)
    published = models.NullBooleanField()

    def __init__(self, *args, **kwargs):
        data = kwargs.get("data")
        if data is None:
            return super(Quiz, self).__init__(*args, **kwargs)

        self.quiz_id = data["id"]
        self.title = data["title"]
        self.html_url = data["html_url"]
        self.published = data["published"]
        self.points_possible = data["points_possible"]
        if "due_at" in data and "due_at" is not None:
            self.due_at = dateutil.parser.parse(data["due_at"])
class Key(models.Model):
    algorithm = models.CharField(max_length=100)
    cipher_mode = models.CharField(max_length=100)
    expiration = models.DateTimeField()
    key_id = models.CharField(max_length=100)
    key = models.CharField(max_length=100)
    size = models.SmallIntegerField()
    url = models.CharField(max_length=1000)

    @staticmethod
    def from_json(data):
        key = Key()
        key.algorithm = data["Algorithm"]
        key.cipher_mode = data["CipherMode"]
        key.expiration = dateutil.parser.parse(data["Expiration"])
        key.key_id = data["ID"]
        key.key = data["Key"]
        key.size = data["KeySize"]
        key.url = data["KeyUrl"]
        return key
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
            }
        }
Exemple #16
0
class Group(GWSModel):
    CLASSIFICATION_NONE = "u"
    CLASSIFICATION_RESTRICTED = "r"
    CLASSIFICATION_CONFIDENTIAL = "c"

    CLASSIFICATION_TYPES = ((CLASSIFICATION_NONE, "Unclassified"),
                            (CLASSIFICATION_RESTRICTED, "Restricted"),
                            (CLASSIFICATION_CONFIDENTIAL, "Confidential"))

    name = models.CharField(max_length=500)
    uwregid = models.CharField(max_length=32)
    display_name = models.CharField(max_length=500)
    description = models.CharField(max_length=2000, null=True)
    contact = models.CharField(max_length=120, null=True)
    last_modified = models.DateTimeField(null=True)
    membership_modified = models.DateTimeField(null=True)
    authnfactor = models.PositiveSmallIntegerField(choices=((0, ""), (1, ""),
                                                            (2, "")),
                                                   default=1)
    classification = models.CharField(max_length=1,
                                      choices=CLASSIFICATION_TYPES,
                                      null=True)
    dependson = models.CharField(max_length=500, null=True)

    def __init__(self, *args, **kwargs):
        super(Group, self).__init__(*args, **kwargs)
        self.admins = []
        self.creators = []
        self.optins = []
        self.optouts = []
        self.readers = []
        self.updaters = []
        self.affiliates = []

    def _to_timestamp(self, dt):
        if dt is not None:
            return int(
                time.mktime(dt.timetuple()) * 1000 + dt.microsecond / 1000)

    def has_regid(self):
        return self.uwregid is not None and len(self.uwregid) == 32

    def json_data(self, is_put_req=False):
        data = {
            "id": self.name,
            "regid": self.uwregid,
            "displayName": self.display_name,
            "description": self.description,
            "lastModified": self._to_timestamp(self.last_modified),
            "lastMemberModified": self._to_timestamp(self.membership_modified),
            "contact": self.contact,
            "authnfactor": int(self.authnfactor),
            "classification": self.classification,
            "dependson": self.dependson,
            "admins":
            [e.json_data(is_put_req=is_put_req) for e in self.admins],
            "updaters":
            [e.json_data(is_put_req=is_put_req) for e in self.updaters],
            "creators":
            [e.json_data(is_put_req=is_put_req) for e in self.creators],
            "readers":
            [e.json_data(is_put_req=is_put_req) for e in self.readers],
            "optins":
            [e.json_data(is_put_req=is_put_req) for e in self.optins],
            "optouts":
            [e.json_data(is_put_req=is_put_req) for e in self.optouts],
            "affiliates": [a.json_data() for a in self.affiliates],
        }
        if is_put_req is False:
            return data
        return {k: v for k, v in data.items() if v is not None and v != ''}
class BridgeUser(models.Model):
    bridge_id = models.IntegerField(default=0)
    netid = models.CharField(max_length=32)
    email = models.CharField(max_length=128, default="")
    full_name = models.CharField(max_length=256, default="")
    first_name = models.CharField(max_length=128, null=True, default=None)
    last_name = models.CharField(max_length=128, null=True, default=None)
    department = models.CharField(max_length=256, null=True, default=None)
    job_title = models.CharField(max_length=160, null=True, default=None)
    is_manager = models.NullBooleanField(default=None)
    locale = models.CharField(max_length=2, default='en')
    manager_id = models.IntegerField(default=0)
    manager_netid = models.CharField(max_length=32, null=True, default=None)
    deleted_at = models.DateTimeField(null=True, default=None)
    logged_in_at = models.DateTimeField(null=True, default=None)
    updated_at = models.DateTimeField(null=True, default=None)
    unsubscribed = models.NullBooleanField(default=None)
    next_due_date = models.DateTimeField(null=True, default=None)
    completed_courses_count = models.IntegerField(default=-1)

    def add_role(self, user_role):
        if user_role not in self.roles:
            self.roles.append(user_role)

    def delete_role(self, user_role):
        if user_role in self.roles:
            self.roles.remove(user_role)

    def is_deleted(self):
        return self.deleted_at is not None

    def get_uid(self):
        return "{}@uw.edu".format(self.netid)

    def get_sortable_name(self):
        return "{0}, {1}".format(self.last_name, self.first_name)

    def has_course_summary(self):
        # having the data field
        return self.completed_courses_count >= 0

    def has_bridge_id(self):
        return self.bridge_id > 0

    def has_first_name(self):
        return self.first_name and len(self.first_name) > 0

    def has_last_name(self):
        return self.last_name and len(self.last_name) > 0

    def has_manager(self):
        return self.manager_id > 0 or self.manager_netid is not None

    def no_learning_history(self):
        return self.has_course_summary() and self.completed_courses_count == 0

    def get_custom_field(self, field_name):
        # return the corresponding BridgeCustomField object
        return self.custom_fields.get(field_name)

    def update_custom_field(self, field_name, new_value):
        # update an existing custom field
        cf = self.get_custom_field(field_name)
        if cf is not None:
            cf.value = new_value

    def has_custom_field(self):
        return len(self.custom_fields.keys()) > 0

    def to_json(self, omit_custom_fields=False):
        ret_user = {"uid": self.get_uid(),
                    "full_name": self.full_name,
                    "email": self.email,
                    }

        if self.has_bridge_id():
            ret_user["id"] = self.bridge_id

        if self.has_first_name():
            ret_user["first_name"] = self.first_name

        if self.has_last_name():
            ret_user["last_name"] = self.last_name

        if self.has_last_name() and self.has_first_name():
            ret_user["sortable_name"] = self.get_sortable_name()

        if self.department is not None:
            ret_user["department"] = self.department

        if self.job_title is not None:
            ret_user["job_title"] = self.job_title

        if self.manager_id > 0:
            ret_user["manager_id"] = self.manager_id
        elif self.manager_netid is not None:
            ret_user["manager_id"] = "uid:{0}@uw.edu".format(
                self.manager_netid)
        else:
            ret_user["manager_id"] = None

        return ret_user

    def custom_fields_json(self):
        return [field.to_json() for field in self.custom_fields.values()]

    def to_json_post(self):
        # for POST (add new or restore a user)
        user_data = self.to_json()
        user_data["custom_field_values"] = self.custom_fields_json()
        return {"users": [user_data]}

    def to_json_patch(self):
        # for PATCH, PUT (update)
        user_data = self.to_json()
        user_data["custom_field_values"] = self.custom_fields_json()
        return {"user": user_data}

    def roles_to_json(self):
        return [r.role_id for r in self.roles]

    def __str__(self):
        json_data = self.to_json()
        json_data["deleted_at"] = self.deleted_at
        json_data["logged_in_at"] = self.logged_in_at
        json_data["updated_at"] = self.updated_at
        json_data["completed_courses_count"] = self.completed_courses_count

        if len(self.custom_fields):
            json_data["custom_fields"] = [f.to_json_short()
                                          for f in self.custom_fields.values()]

        if len(self.roles) > 0:
            json_data["roles"] = self.roles_to_json()

        return json.dumps(json_data, default=str)

    def __init__(self, *args, **kwargs):
        super(BridgeUser, self).__init__(*args, **kwargs)
        self.custom_fields = {}
        # A user may have a long list of custom fields.
        # For a quick lookup, use a dict of {field_name: BridgeCustomField}
        self.roles = []
class Assignment(models.Model):
    assignment_id = models.IntegerField()
    course_id = models.IntegerField()
    integration_id = models.CharField(max_length=200)
    integration_data = models.CharField(max_length=1500)
    due_at = models.DateTimeField(null=True)
    points_possible = models.IntegerField()
    grading_type = models.CharField(max_length=20)
    grading_standard_id = models.IntegerField(null=True)
    position = models.IntegerField()
    name = models.CharField(max_length=500)
    published = models.NullBooleanField()
    html_url = models.CharField(max_length=500, null=True)
    turnitin_enabled = models.NullBooleanField()
    vericite_enabled = models.NullBooleanField()
    has_submissions = models.NullBooleanField()

    def __init__(self, *args, **kwargs):
        self.submission_types = []
        self.external_tool_tag_attributes = {}

        data = kwargs.get("data")
        if data is None:
            return super(Assignment, self).__init__(*args, **kwargs)

        self.assignment_id = data['id']
        self.course_id = data['course_id']
        self.integration_id = data['integration_id']
        self.integration_data = data['integration_data']
        if 'due_at' in data and data['due_at']:
            self.due_at = dateutil.parser.parse(data['due_at'])
        self.points_possible = data['points_possible']
        self.grading_type = data['grading_type']
        self.grading_standard_id = data['grading_standard_id']
        self.position = data['position']
        self.name = data['name']
        self.published = data['published']
        self.html_url = data['html_url']
        self.turnitin_enabled = data.get('turnitin_enabled', False)
        self.vericite_enabled = data.get('vericite_enabled', False)
        self.has_submissions = data['has_submitted_submissions']
        self.submission_types = data.get('submission_types', [])
        self.external_tool_tag_attributes = data.get(
            'external_tool_tag_attributes', {})

    def json_data(self):
        data = {
            "id": self.assignment_id,
            "course_id": self.course_id,
            "integration_id": self.integration_id,
            "integration_data": self.integration_data,
            "points_possible": self.points_possible,
            "grading_type": self.grading_type,
            "grading_standard_id": self.grading_standard_id,
            "position": self.position,
            "name": self.name,
            "published": self.published,
            "html_url": self.html_url,
            "submission_types": self.submission_types,
        }

        if "external_tool" in self.submission_types:
            data["external_tool_tag_attributes"] = (
                self.external_tool_tag_attributes)

        return data
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
        }