82 lines
2.4 KiB
Python
82 lines
2.4 KiB
Python
import logging
|
|
|
|
from django.db import models, transaction
|
|
|
|
from student.models import User
|
|
|
|
log = logging.getLogger("mitx.licenses")
|
|
|
|
|
|
class CourseSoftware(models.Model):
|
|
name = models.CharField(max_length=255)
|
|
full_name = models.CharField(max_length=255)
|
|
url = models.CharField(max_length=255)
|
|
course_id = models.CharField(max_length=255)
|
|
|
|
def __unicode__(self):
|
|
return u'{0} for {1}'.format(self.name, self.course_id)
|
|
|
|
|
|
class UserLicense(models.Model):
|
|
software = models.ForeignKey(CourseSoftware, db_index=True)
|
|
user = models.ForeignKey(User, null=True)
|
|
serial = models.CharField(max_length=255)
|
|
|
|
|
|
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:
|
|
# 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
|
|
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()
|
|
license = selected.filter(user__isnull=True, software=software)[0]
|
|
license.user = user
|
|
license.save()
|
|
except IndexError:
|
|
# there are no free licenses
|
|
log.error('No serial numbers available for %s', software)
|
|
license = None
|
|
# TODO [rocha]look if someone has unenrolled from the class
|
|
# and already has a serial number
|
|
|
|
return license
|