models.py 2.48 KB
Newer Older
1 2 3 4
import logging

from django.db import models, transaction

5 6
from student.models import User

7 8
from xmodule_django.models import CourseKeyField

9
log = logging.getLogger("edx.licenses")
10

11

12
class CourseSoftware(models.Model):
13 14 15
    name = models.CharField(max_length=255)
    full_name = models.CharField(max_length=255)
    url = models.CharField(max_length=255)
16
    course_id = CourseKeyField(max_length=255)
17

18 19 20
    def __unicode__(self):
        return u'{0} for {1}'.format(self.name, self.course_id)

21

22 23 24
class UserLicense(models.Model):
    software = models.ForeignKey(CourseSoftware, db_index=True)
    user = models.ForeignKey(User, null=True)
25
    serial = models.CharField(max_length=255)
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46


def get_courses_licenses(user, courses):
    course_ids = set(course.id for course in courses)
    all_software = CourseSoftware.objects.filter(course_id__in=course_ids)

    assigned_licenses = UserLicense.objects.filter(software__in=all_software,
                                                   user=user)

    licenses = dict.fromkeys(all_software, None)
    for license in assigned_licenses:
        licenses[license.software] = license

    log.info(assigned_licenses)
    log.info(licenses)

    return licenses


def get_license(user, software):
    try:
47 48 49 50
        # TODO: temporary fix for when somehow a user got more that one license.
        # The proper fix should use Meta.unique_together in the UserLicense model.
        licenses = UserLicense.objects.filter(user=user, software=software)
        license = licenses[0] if licenses else None
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
    except UserLicense.DoesNotExist:
        license = None

    return license


def get_or_create_license(user, software):
    license = get_license(user, software)
    if license is None:
        license = _create_license(user, software)

    return license


def _create_license(user, software):
    license = None

    try:
        # find one license that has not been assigned, locking the
        # table/rows with select_for_update to prevent race conditions
        with transaction.commit_on_success():
            selected = UserLicense.objects.select_for_update()
73
            license = selected.filter(user__isnull=True, software=software)[0]
74 75 76 77
            license.user = user
            license.save()
    except IndexError:
        # there are no free licenses
78
        log.error('No serial numbers available for %s', software)
79 80 81 82 83
        license = None
        # TODO [rocha]look if someone has unenrolled from the class
        # and already has a serial number

    return license