Remove "Licenses" djangoapp
This commit is contained in:
@@ -1875,33 +1875,6 @@ CREATE TABLE `instructor_task_instructortask` (
|
||||
CONSTRAINT `instructor_task_in_requester_id_3383acfe2fe42391_fk_auth_user_id` FOREIGN KEY (`requester_id`) REFERENCES `auth_user` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `licenses_coursesoftware`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `licenses_coursesoftware` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`name` varchar(255) NOT NULL,
|
||||
`full_name` varchar(255) NOT NULL,
|
||||
`url` varchar(255) NOT NULL,
|
||||
`course_id` varchar(255) NOT NULL,
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `licenses_userlicense`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `licenses_userlicense` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`serial` varchar(255) NOT NULL,
|
||||
`software_id` int(11) NOT NULL,
|
||||
`user_id` int(11) DEFAULT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `licen_software_id_209fd400b7c7a3ca_fk_licenses_coursesoftware_id` (`software_id`),
|
||||
KEY `licenses_userlicense_user_id_7d98c37aa4438a34_fk_auth_user_id` (`user_id`),
|
||||
CONSTRAINT `licen_software_id_209fd400b7c7a3ca_fk_licenses_coursesoftware_id` FOREIGN KEY (`software_id`) REFERENCES `licenses_coursesoftware` (`id`),
|
||||
CONSTRAINT `licenses_userlicense_user_id_7d98c37aa4438a34_fk_auth_user_id` FOREIGN KEY (`user_id`) REFERENCES `auth_user` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
DROP TABLE IF EXISTS `lms_xblock_xblockasidesconfig`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
|
||||
@@ -1,60 +0,0 @@
|
||||
from uuid import uuid4
|
||||
|
||||
from django.utils.html import escape
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
from licenses.models import CourseSoftware, UserLicense
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = """Generate random serial numbers for software used in a course.
|
||||
|
||||
Usage: generate_serial_numbers <course_id> <software_name> <count>
|
||||
|
||||
<count> is the number of numbers to generate.
|
||||
|
||||
Example:
|
||||
|
||||
import_serial_numbers MITx/6.002x/2012_Fall matlab 100
|
||||
|
||||
"""
|
||||
args = "course_id software_id count"
|
||||
|
||||
def handle(self, *args, **options):
|
||||
course_id, software_name, count = self._parse_arguments(args)
|
||||
|
||||
software, _ = CourseSoftware.objects.get_or_create(course_id=course_id,
|
||||
name=software_name)
|
||||
self._generate_serials(software, count)
|
||||
|
||||
def _parse_arguments(self, args):
|
||||
if len(args) != 3:
|
||||
raise CommandError("Incorrect number of arguments")
|
||||
|
||||
course_id = args[0]
|
||||
course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
|
||||
if not modulestore().has_course(course_key):
|
||||
raise CommandError("Unknown course_id")
|
||||
|
||||
software_name = escape(args[1].lower())
|
||||
|
||||
try:
|
||||
count = int(args[2])
|
||||
except ValueError:
|
||||
raise CommandError("Invalid <count> argument.")
|
||||
|
||||
return course_key, software_name, count
|
||||
|
||||
def _generate_serials(self, software, count):
|
||||
print "Generating {0} serials".format(count)
|
||||
|
||||
# add serial numbers them to the database
|
||||
for _ in xrange(count):
|
||||
serial = str(uuid4())
|
||||
license = UserLicense(software=software, serial=serial)
|
||||
license.save()
|
||||
|
||||
print "{0} new serial numbers generated.".format(count)
|
||||
@@ -1,66 +0,0 @@
|
||||
import os.path
|
||||
|
||||
from django.utils.html import escape
|
||||
from django.core.management.base import BaseCommand, CommandError
|
||||
|
||||
from xmodule.modulestore.django import modulestore
|
||||
|
||||
from licenses.models import CourseSoftware, UserLicense
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
|
||||
class Command(BaseCommand):
|
||||
help = """Imports serial numbers for software used in a course.
|
||||
|
||||
Usage: import_serial_numbers <course_id> <software_name> <file>
|
||||
|
||||
<file> is a text file that list one available serial number per line.
|
||||
|
||||
Example:
|
||||
|
||||
import_serial_numbers MITx/6.002x/2012_Fall matlab serials.txt
|
||||
|
||||
"""
|
||||
args = "course_id software_id serial_file"
|
||||
|
||||
def handle(self, *args, **options):
|
||||
course_id, software_name, filename = self._parse_arguments(args)
|
||||
|
||||
software, _ = CourseSoftware.objects.get_or_create(course_id=course_id,
|
||||
name=software_name)
|
||||
self._import_serials(software, filename)
|
||||
|
||||
def _parse_arguments(self, args):
|
||||
if len(args) != 3:
|
||||
raise CommandError("Incorrect number of arguments")
|
||||
|
||||
course_id = args[0]
|
||||
course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
|
||||
if not modulestore().has_course(course_key):
|
||||
raise CommandError("Unknown course_id")
|
||||
|
||||
software_name = escape(args[1].lower())
|
||||
|
||||
filename = os.path.abspath(args[2])
|
||||
if not os.path.exists(filename):
|
||||
raise CommandError("Cannot find filename {0}".format(filename))
|
||||
|
||||
return course_key, software_name, filename
|
||||
|
||||
def _import_serials(self, software, filename):
|
||||
print "Importing serial numbers for {0}.".format(software)
|
||||
|
||||
serials = set(unicode(l.strip()) for l in open(filename))
|
||||
|
||||
# remove serial numbers we already have
|
||||
licenses = UserLicense.objects.filter(software=software)
|
||||
known_serials = set(l.serial for l in licenses)
|
||||
if known_serials:
|
||||
serials = serials.difference(known_serials)
|
||||
|
||||
# add serial numbers them to the database
|
||||
for serial in serials:
|
||||
license = UserLicense(software=software, serial=serial)
|
||||
license.save()
|
||||
|
||||
print "{0} new serial numbers imported.".format(len(serials))
|
||||
@@ -1,35 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from django.db import migrations, models
|
||||
from django.conf import settings
|
||||
import xmodule_django.models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
migrations.swappable_dependency(settings.AUTH_USER_MODEL),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.CreateModel(
|
||||
name='CourseSoftware',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('name', models.CharField(max_length=255)),
|
||||
('full_name', models.CharField(max_length=255)),
|
||||
('url', models.CharField(max_length=255)),
|
||||
('course_id', xmodule_django.models.CourseKeyField(max_length=255)),
|
||||
],
|
||||
),
|
||||
migrations.CreateModel(
|
||||
name='UserLicense',
|
||||
fields=[
|
||||
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
|
||||
('serial', models.CharField(max_length=255)),
|
||||
('software', models.ForeignKey(to='licenses.CourseSoftware')),
|
||||
('user', models.ForeignKey(to=settings.AUTH_USER_MODEL, null=True)),
|
||||
],
|
||||
),
|
||||
]
|
||||
@@ -1,83 +0,0 @@
|
||||
import logging
|
||||
|
||||
from django.db import models, transaction
|
||||
|
||||
from student.models import User
|
||||
|
||||
from xmodule_django.models import CourseKeyField
|
||||
|
||||
log = logging.getLogger("edx.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 = CourseKeyField(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.atomic():
|
||||
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
|
||||
@@ -1,227 +0,0 @@
|
||||
"""Tests for License package"""
|
||||
import logging
|
||||
import json
|
||||
|
||||
from uuid import uuid4
|
||||
from random import shuffle
|
||||
from tempfile import NamedTemporaryFile
|
||||
import factory
|
||||
from factory.django import DjangoModelFactory
|
||||
|
||||
from django.test import TestCase
|
||||
from django.test.client import Client
|
||||
from django.core.management import call_command
|
||||
from django.core.urlresolvers import reverse
|
||||
from nose.tools import assert_true
|
||||
|
||||
from licenses.models import CourseSoftware, UserLicense
|
||||
|
||||
from student.tests.factories import UserFactory
|
||||
from xmodule.modulestore.tests.factories import CourseFactory
|
||||
from xmodule.modulestore.tests.django_utils import ModuleStoreTestCase
|
||||
|
||||
COURSE_1 = 'edX/toy/2012_Fall'
|
||||
|
||||
SOFTWARE_1 = 'matlab'
|
||||
SOFTWARE_2 = 'stata'
|
||||
|
||||
SERIAL_1 = '123456abcde'
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class CourseSoftwareFactory(DjangoModelFactory):
|
||||
'''Factory for generating CourseSoftware objects in database'''
|
||||
class Meta(object):
|
||||
model = CourseSoftware
|
||||
|
||||
name = SOFTWARE_1
|
||||
full_name = SOFTWARE_1
|
||||
url = SOFTWARE_1
|
||||
course_id = COURSE_1
|
||||
|
||||
|
||||
class UserLicenseFactory(DjangoModelFactory):
|
||||
'''
|
||||
Factory for generating UserLicense objects in database
|
||||
|
||||
By default, the user assigned is null, indicating that the
|
||||
serial number has not yet been assigned.
|
||||
'''
|
||||
class Meta(object):
|
||||
model = UserLicense
|
||||
|
||||
user = None
|
||||
software = factory.SubFactory(CourseSoftwareFactory)
|
||||
serial = SERIAL_1
|
||||
|
||||
|
||||
class LicenseTestCase(TestCase):
|
||||
'''Tests for licenses.views'''
|
||||
def setUp(self):
|
||||
'''creates a user and logs in'''
|
||||
|
||||
super(LicenseTestCase, self).setUp()
|
||||
# self.setup_viewtest_user()
|
||||
self.user = UserFactory(username='test',
|
||||
email='test@edx.org', password='test_password')
|
||||
self.client = Client()
|
||||
assert_true(self.client.login(username='test', password='test_password'))
|
||||
self.software = CourseSoftwareFactory()
|
||||
|
||||
def test_get_license(self):
|
||||
UserLicenseFactory(user=self.user, software=self.software)
|
||||
response = self.client.post(reverse('user_software_license'),
|
||||
{'software': SOFTWARE_1, 'generate': 'false'},
|
||||
HTTP_X_REQUESTED_WITH='XMLHttpRequest',
|
||||
HTTP_REFERER='/courses/{0}/some_page'.format(COURSE_1))
|
||||
self.assertEqual(200, response.status_code)
|
||||
json_returned = json.loads(response.content)
|
||||
self.assertFalse('error' in json_returned)
|
||||
self.assertTrue('serial' in json_returned)
|
||||
self.assertEquals(json_returned['serial'], SERIAL_1)
|
||||
|
||||
def test_get_nonexistent_license(self):
|
||||
response = self.client.post(reverse('user_software_license'),
|
||||
{'software': SOFTWARE_1, 'generate': 'false'},
|
||||
HTTP_X_REQUESTED_WITH='XMLHttpRequest',
|
||||
HTTP_REFERER='/courses/{0}/some_page'.format(COURSE_1))
|
||||
self.assertEqual(200, response.status_code)
|
||||
json_returned = json.loads(response.content)
|
||||
self.assertFalse('serial' in json_returned)
|
||||
self.assertTrue('error' in json_returned)
|
||||
|
||||
def test_create_nonexistent_license(self):
|
||||
'''Should not assign a license to an unlicensed user when none are available'''
|
||||
response = self.client.post(reverse('user_software_license'),
|
||||
{'software': SOFTWARE_1, 'generate': 'true'},
|
||||
HTTP_X_REQUESTED_WITH='XMLHttpRequest',
|
||||
HTTP_REFERER='/courses/{0}/some_page'.format(COURSE_1))
|
||||
self.assertEqual(200, response.status_code)
|
||||
json_returned = json.loads(response.content)
|
||||
self.assertFalse('serial' in json_returned)
|
||||
self.assertTrue('error' in json_returned)
|
||||
|
||||
def test_create_license(self):
|
||||
'''Should assign a license to an unlicensed user if one is unassigned'''
|
||||
# create an unassigned license
|
||||
UserLicenseFactory(software=self.software)
|
||||
response = self.client.post(reverse('user_software_license'),
|
||||
{'software': SOFTWARE_1, 'generate': 'true'},
|
||||
HTTP_X_REQUESTED_WITH='XMLHttpRequest',
|
||||
HTTP_REFERER='/courses/{0}/some_page'.format(COURSE_1))
|
||||
self.assertEqual(200, response.status_code)
|
||||
json_returned = json.loads(response.content)
|
||||
self.assertFalse('error' in json_returned)
|
||||
self.assertTrue('serial' in json_returned)
|
||||
self.assertEquals(json_returned['serial'], SERIAL_1)
|
||||
|
||||
def test_get_license_from_wrong_course(self):
|
||||
response = self.client.post(reverse('user_software_license'),
|
||||
{'software': SOFTWARE_1, 'generate': 'false'},
|
||||
HTTP_X_REQUESTED_WITH='XMLHttpRequest',
|
||||
HTTP_REFERER='/courses/{0}/some_page'.format('some/other/course'))
|
||||
self.assertEqual(404, response.status_code)
|
||||
|
||||
def test_get_license_from_non_ajax(self):
|
||||
response = self.client.post(reverse('user_software_license'),
|
||||
{'software': SOFTWARE_1, 'generate': 'false'},
|
||||
HTTP_REFERER='/courses/{0}/some_page'.format(COURSE_1))
|
||||
self.assertEqual(404, response.status_code)
|
||||
|
||||
def test_get_license_without_software(self):
|
||||
response = self.client.post(reverse('user_software_license'),
|
||||
{'generate': 'false'},
|
||||
HTTP_X_REQUESTED_WITH='XMLHttpRequest',
|
||||
HTTP_REFERER='/courses/{0}/some_page'.format(COURSE_1))
|
||||
self.assertEqual(404, response.status_code)
|
||||
|
||||
def test_get_license_without_login(self):
|
||||
self.client.logout()
|
||||
response = self.client.post(reverse('user_software_license'),
|
||||
{'software': SOFTWARE_1, 'generate': 'false'},
|
||||
HTTP_X_REQUESTED_WITH='XMLHttpRequest',
|
||||
HTTP_REFERER='/courses/{0}/some_page'.format(COURSE_1))
|
||||
# if we're not logged in, we should be referred to the login page
|
||||
self.assertEqual(302, response.status_code)
|
||||
|
||||
|
||||
class CommandTest(ModuleStoreTestCase):
|
||||
'''Test management command for importing serial numbers'''
|
||||
def setUp(self):
|
||||
super(CommandTest, self).setUp()
|
||||
|
||||
course = CourseFactory.create()
|
||||
self.course_id = course.id
|
||||
|
||||
def test_import_serial_numbers(self):
|
||||
size = 20
|
||||
|
||||
log.debug('Adding one set of serials for {0}'.format(SOFTWARE_1))
|
||||
with generate_serials_file(size) as temp_file:
|
||||
args = [self.course_id.to_deprecated_string(), SOFTWARE_1, temp_file.name]
|
||||
call_command('import_serial_numbers', *args)
|
||||
|
||||
log.debug('Adding one set of serials for {0}'.format(SOFTWARE_2))
|
||||
with generate_serials_file(size) as temp_file:
|
||||
args = [self.course_id.to_deprecated_string(), SOFTWARE_2, temp_file.name]
|
||||
call_command('import_serial_numbers', *args)
|
||||
|
||||
log.debug('There should be only 2 course-software entries')
|
||||
software_count = CourseSoftware.objects.all().count()
|
||||
self.assertEqual(2, software_count)
|
||||
|
||||
log.debug('We added two sets of {0} serials'.format(size))
|
||||
licenses_count = UserLicense.objects.all().count()
|
||||
self.assertEqual(2 * size, licenses_count)
|
||||
|
||||
log.debug('Adding more serial numbers to {0}'.format(SOFTWARE_1))
|
||||
with generate_serials_file(size) as temp_file:
|
||||
args = [self.course_id.to_deprecated_string(), SOFTWARE_1, temp_file.name]
|
||||
call_command('import_serial_numbers', *args)
|
||||
|
||||
log.debug('There should be still only 2 course-software entries')
|
||||
software_count = CourseSoftware.objects.all().count()
|
||||
self.assertEqual(2, software_count)
|
||||
|
||||
log.debug(
|
||||
"Now we should have 3 sets of %s serials",
|
||||
size,
|
||||
)
|
||||
licenses_count = UserLicense.objects.all().count()
|
||||
self.assertEqual(3 * size, licenses_count)
|
||||
|
||||
software = CourseSoftware.objects.get(pk=1)
|
||||
|
||||
lics = UserLicense.objects.filter(software=software)[:size]
|
||||
known_serials = list(l.serial for l in lics)
|
||||
known_serials.extend(generate_serials(10))
|
||||
|
||||
shuffle(known_serials)
|
||||
|
||||
log.debug('Adding some new and old serials to {0}'.format(SOFTWARE_1))
|
||||
with NamedTemporaryFile() as tmpfile:
|
||||
tmpfile.write('\n'.join(known_serials))
|
||||
tmpfile.flush()
|
||||
args = [self.course_id.to_deprecated_string(), SOFTWARE_1, tmpfile.name]
|
||||
call_command('import_serial_numbers', *args)
|
||||
|
||||
log.debug('Check if we added only the new ones')
|
||||
licenses_count = UserLicense.objects.filter(software=software).count()
|
||||
self.assertEqual((2 * size) + 10, licenses_count)
|
||||
|
||||
|
||||
def generate_serials(size=20):
|
||||
'''generate a list of serial numbers'''
|
||||
return [str(uuid4()) for _ in range(size)]
|
||||
|
||||
|
||||
def generate_serials_file(size=20):
|
||||
'''output list of generated serial numbers to a temp file'''
|
||||
serials = generate_serials(size)
|
||||
|
||||
temp_file = NamedTemporaryFile()
|
||||
temp_file.write('\n'.join(serials))
|
||||
temp_file.flush()
|
||||
|
||||
return temp_file
|
||||
@@ -1,90 +0,0 @@
|
||||
import logging
|
||||
import json
|
||||
import re
|
||||
from urlparse import urlparse
|
||||
from collections import namedtuple, defaultdict
|
||||
|
||||
|
||||
from edxmako.shortcuts import render_to_string
|
||||
from opaque_keys.edx.locations import SlashSeparatedCourseKey
|
||||
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.contrib.auth.models import User
|
||||
from django.http import HttpResponse, Http404
|
||||
from django.views.decorators.csrf import requires_csrf_token
|
||||
|
||||
from licenses.models import CourseSoftware
|
||||
from licenses.models import get_courses_licenses, get_or_create_license, get_license
|
||||
|
||||
|
||||
log = logging.getLogger("edx.licenses")
|
||||
|
||||
|
||||
License = namedtuple('License', 'software serial')
|
||||
|
||||
|
||||
def get_licenses_by_course(user, courses):
|
||||
licenses = get_courses_licenses(user, courses)
|
||||
licenses_by_course = defaultdict(list)
|
||||
|
||||
# create missing licenses and group by course_id
|
||||
for software, license in licenses.iteritems():
|
||||
if license is None:
|
||||
licenses[software] = get_or_create_license(user, software)
|
||||
|
||||
course_id = software.course_id
|
||||
serial = license.serial if license else None
|
||||
licenses_by_course[course_id].append(License(software, serial))
|
||||
|
||||
# render elements
|
||||
data_by_course = {}
|
||||
for course_id, licenses in licenses_by_course.iteritems():
|
||||
context = {'licenses': licenses}
|
||||
template = 'licenses/serial_numbers.html'
|
||||
data_by_course[course_id] = render_to_string(template, context)
|
||||
|
||||
return data_by_course
|
||||
|
||||
|
||||
@login_required
|
||||
@requires_csrf_token
|
||||
def user_software_license(request):
|
||||
if request.method != 'POST' or not request.is_ajax():
|
||||
raise Http404
|
||||
|
||||
# get the course id from the referer
|
||||
url_path = urlparse(request.META.get('HTTP_REFERER', '')).path
|
||||
pattern = re.compile('^/courses/(?P<id>[^/]+/[^/]+/[^/]+)/.*/?$')
|
||||
match = re.match(pattern, url_path)
|
||||
|
||||
if not match:
|
||||
raise Http404
|
||||
course_id = match.groupdict().get('id', '')
|
||||
course_key = SlashSeparatedCourseKey.from_deprecated_string(course_id)
|
||||
|
||||
user_id = request.session.get('_auth_user_id')
|
||||
software_name = request.POST.get('software')
|
||||
generate = request.POST.get('generate', False) == 'true'
|
||||
|
||||
try:
|
||||
software = CourseSoftware.objects.get(name=software_name,
|
||||
course_id=course_key)
|
||||
except CourseSoftware.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
try:
|
||||
user = User.objects.get(id=user_id)
|
||||
except User.DoesNotExist:
|
||||
raise Http404
|
||||
|
||||
if generate:
|
||||
software_license = get_or_create_license(user, software)
|
||||
else:
|
||||
software_license = get_license(user, software)
|
||||
|
||||
if software_license:
|
||||
response = {'serial': software_license.serial}
|
||||
else:
|
||||
response = {'error': 'No serial number found'}
|
||||
|
||||
return HttpResponse(json.dumps(response), content_type='application/json')
|
||||
@@ -1831,7 +1831,6 @@ INSTALLED_APPS = (
|
||||
'instructor',
|
||||
'instructor_task',
|
||||
'open_ended_grading',
|
||||
'licenses',
|
||||
'openedx.core.djangoapps.course_groups',
|
||||
'bulk_email',
|
||||
'branding',
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<%! from django.utils.translation import ugettext as _ %>
|
||||
<dl>
|
||||
% for license in licenses:
|
||||
<dt> ${license.software.name}: </dt>
|
||||
% if license.serial:
|
||||
<dd> ${license.serial} </dd>
|
||||
% else:
|
||||
<dd> ${_("None Available")} </dd>
|
||||
% endif
|
||||
% endfor
|
||||
</dl>
|
||||
@@ -310,14 +310,6 @@ if settings.COURSEWARE_ENABLED:
|
||||
name='xblock_resource_url',
|
||||
),
|
||||
|
||||
# Software Licenses
|
||||
|
||||
# TODO: for now, this is the endpoint of an ajax replay
|
||||
# service that retrieve and assigns license numbers for
|
||||
# software assigned to a course. The numbers have to be loaded
|
||||
# into the database.
|
||||
url(r'^software-licenses$', 'licenses.views.user_software_license', name="user_software_license"),
|
||||
|
||||
url(
|
||||
r'^courses/{}/xqueue/(?P<userid>[^/]*)/(?P<mod_id>.*?)/(?P<dispatch>[^/]*)$'.format(
|
||||
settings.COURSE_ID_PATTERN
|
||||
|
||||
Reference in New Issue
Block a user