Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
E
edx-platform
Overview
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
edx
edx-platform
Commits
c4175c7d
Commit
c4175c7d
authored
Jun 09, 2015
by
Matt Drayer
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #8363 from edx/ziafazal/SOL-861
refactored code to make certificate PDF generation optional
parents
fee8f6db
20800ea5
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
253 additions
and
53 deletions
+253
-53
lms/djangoapps/certificates/api.py
+49
-2
lms/djangoapps/certificates/management/commands/regenerate_user.py
+4
-8
lms/djangoapps/certificates/management/commands/ungenerated_certs.py
+7
-5
lms/djangoapps/certificates/queue.py
+33
-29
lms/djangoapps/certificates/tests/test_api.py
+38
-1
lms/djangoapps/certificates/tests/test_cert_management.py
+70
-3
lms/djangoapps/certificates/tests/test_queue.py
+11
-0
lms/djangoapps/certificates/tests/test_views.py
+39
-2
lms/djangoapps/certificates/views.py
+2
-3
No files found.
lms/djangoapps/certificates/api.py
View file @
c4175c7d
...
...
@@ -6,8 +6,11 @@ rather than importing Django models directly.
"""
import
logging
from
django.conf
import
settings
from
django.core.urlresolvers
import
reverse
from
xmodule.modulestore.django
import
modulestore
from
certificates.models
import
(
CertificateStatuses
as
cert_status
,
certificate_status_for_student
,
...
...
@@ -21,7 +24,7 @@ from certificates.queue import XQueueCertInterface
log
=
logging
.
getLogger
(
"edx.certificate"
)
def
generate_user_certificates
(
student
,
course_key
,
course
=
None
):
def
generate_user_certificates
(
student
,
course_key
,
course
=
None
,
insecure
=
False
):
"""
It will add the add-cert request into the xqueue.
...
...
@@ -36,9 +39,41 @@ def generate_user_certificates(student, course_key, course=None):
Keyword Arguments:
course (Course): Optionally provide the course object; if not provided
it will be loaded.
insecure - (Boolean)
"""
xqueue
=
XQueueCertInterface
()
xqueue
.
add_cert
(
student
,
course_key
,
course
=
course
)
if
insecure
:
xqueue
.
use_https
=
False
generate_pdf
=
not
has_html_certificates_enabled
(
course_key
,
course
)
return
xqueue
.
add_cert
(
student
,
course_key
,
course
=
course
,
generate_pdf
=
generate_pdf
)
def
regenerate_user_certificates
(
student
,
course_key
,
course
=
None
,
forced_grade
=
None
,
template_file
=
None
,
insecure
=
False
):
"""
It will add the regen-cert request into the xqueue.
A new record will be created to track the certificate
generation task. If an error occurs while adding the certificate
to the queue, the task will have status 'error'.
Args:
student (User)
course_key (CourseKey)
Keyword Arguments:
course (Course): Optionally provide the course object; if not provided
it will be loaded.
grade_value - The grade string, such as "Distinction"
template_file - The template file used to render this certificate
insecure - (Boolean)
"""
xqueue
=
XQueueCertInterface
()
if
insecure
:
xqueue
.
use_https
=
False
generate_pdf
=
not
has_html_certificates_enabled
(
course_key
,
course
)
return
xqueue
.
regen_cert
(
student
,
course_key
,
course
,
forced_grade
,
template_file
,
generate_pdf
)
def
certificate_downloadable_status
(
student
,
course_key
):
...
...
@@ -156,6 +191,18 @@ def generate_example_certificates(course_key):
xqueue
.
add_example_cert
(
cert
)
def
has_html_certificates_enabled
(
course_key
,
course
=
None
):
"""
It determines if course has html certificates enabled
"""
html_certificates_enabled
=
False
if
settings
.
FEATURES
.
get
(
'CERTIFICATES_HTML_VIEW'
,
False
):
course
=
course
if
course
else
modulestore
()
.
get_course
(
course_key
,
depth
=
0
)
if
get_active_web_certificate
(
course
)
is
not
None
:
html_certificates_enabled
=
True
return
html_certificates_enabled
def
example_certificates_status
(
course_key
):
"""Check the status of example certificates for a course.
...
...
lms/djangoapps/certificates/management/commands/regenerate_user.py
View file @
c4175c7d
...
...
@@ -9,9 +9,8 @@ from opaque_keys import InvalidKeyError
from
opaque_keys.edx.keys
import
CourseKey
from
opaque_keys.edx.locations
import
SlashSeparatedCourseKey
from
xmodule.modulestore.django
import
modulestore
from
certificates.queue
import
XQueueCertInterface
from
certificates.models
import
BadgeAssertion
from
certificates.api
import
regenerate_user_certificates
LOGGER
=
logging
.
getLogger
(
__name__
)
...
...
@@ -107,14 +106,11 @@ class Command(BaseCommand):
)
# Add the certificate request to the queue
xqueue_interface
=
XQueueCertInterface
()
if
options
[
'insecure'
]:
xqueue_interface
.
use_https
=
False
ret
=
xqueue_interface
.
regen_cert
(
ret
=
regenerate_user_certificates
(
student
,
course_id
,
course
=
course
,
forced_grade
=
options
[
'grade_value'
],
template_file
=
options
[
'template_file'
]
template_file
=
options
[
'template_file'
],
insecure
=
options
[
'insecure'
]
)
try
:
...
...
lms/djangoapps/certificates/management/commands/ungenerated_certs.py
View file @
c4175c7d
...
...
@@ -7,7 +7,7 @@ import datetime
from
pytz
import
UTC
from
django.core.management.base
import
BaseCommand
,
CommandError
from
certificates.models
import
certificate_status_for_student
from
certificates.
queue
import
XQueueCertInterface
from
certificates.
api
import
generate_user_certificates
from
django.contrib.auth.models
import
User
from
optparse
import
make_option
from
opaque_keys
import
InvalidKeyError
...
...
@@ -108,9 +108,6 @@ class Command(BaseCommand):
courseenrollment__course_id
=
course_key
)
xq
=
XQueueCertInterface
()
if
options
[
'insecure'
]:
xq
.
use_https
=
False
total
=
enrolled_students
.
count
()
count
=
0
start
=
datetime
.
datetime
.
now
(
UTC
)
...
...
@@ -144,7 +141,12 @@ class Command(BaseCommand):
if
not
options
[
'noop'
]:
# Add the certificate request to the queue
ret
=
xq
.
add_cert
(
student
,
course_key
,
course
=
course
)
ret
=
generate_user_certificates
(
student
,
course_key
,
course
=
course
,
insecure
=
options
[
'insecure'
]
)
if
ret
==
'generating'
:
LOGGER
.
info
(
...
...
lms/djangoapps/certificates/queue.py
View file @
c4175c7d
...
...
@@ -104,7 +104,7 @@ class XQueueCertInterface(object):
self
.
restricted
=
UserProfile
.
objects
.
filter
(
allow_certificate
=
False
)
self
.
use_https
=
True
def
regen_cert
(
self
,
student
,
course_id
,
course
=
None
,
forced_grade
=
None
,
template_file
=
None
):
def
regen_cert
(
self
,
student
,
course_id
,
course
=
None
,
forced_grade
=
None
,
template_file
=
None
,
generate_pdf
=
True
):
"""(Re-)Make certificate for a particular student in a particular course
Arguments:
...
...
@@ -154,7 +154,7 @@ class XQueueCertInterface(object):
except
GeneratedCertificate
.
DoesNotExist
:
pass
return
self
.
add_cert
(
student
,
course_id
,
course
,
forced_grade
,
template_file
)
return
self
.
add_cert
(
student
,
course_id
,
course
,
forced_grade
,
template_file
,
generate_pdf
)
def
del_cert
(
self
,
student
,
course_id
):
...
...
@@ -173,7 +173,9 @@ class XQueueCertInterface(object):
raise
NotImplementedError
def
add_cert
(
self
,
student
,
course_id
,
course
=
None
,
forced_grade
=
None
,
template_file
=
None
,
title
=
'None'
):
# pylint: disable=too-many-statements
def
add_cert
(
self
,
student
,
course_id
,
course
=
None
,
forced_grade
=
None
,
template_file
=
None
,
title
=
'None'
,
generate_pdf
=
True
):
"""
Request a new certificate for a student.
...
...
@@ -183,6 +185,7 @@ class XQueueCertInterface(object):
forced_grade - a string indicating a grade parameter to pass with
the certificate request. If this is given, grading
will be skipped.
generate_pdf - Boolean should a message be sent in queue to generate certificate PDF
Will change the certificate status to 'generating'.
...
...
@@ -340,35 +343,36 @@ class XQueueCertInterface(object):
}
if
template_file
:
contents
[
'template_pdf'
]
=
template_file
new_status
=
status
.
generating
new_status
=
status
.
generating
if
generate_pdf
else
status
.
downloadable
cert
.
status
=
new_status
cert
.
save
()
try
:
self
.
_send_to_xqueue
(
contents
,
key
)
except
XQueueAddToQueueError
as
exc
:
new_status
=
ExampleCertificate
.
STATUS_ERROR
cert
.
status
=
new_status
cert
.
error_reason
=
unicode
(
exc
)
cert
.
save
()
LOGGER
.
critical
(
(
u"Could not add certificate task to XQueue. "
u"The course was '
%
s' and the student was '
%
s'."
u"The certificate task status has been marked as 'error' "
u"and can be re-submitted with a management command."
),
student
.
id
,
course_id
)
else
:
LOGGER
.
info
(
(
u"The certificate status has been set to '
%
s'. "
u"Sent a certificate grading task to the XQueue "
u"with the key '
%
s'. "
),
key
,
new_status
)
if
generate_pdf
:
try
:
self
.
_send_to_xqueue
(
contents
,
key
)
except
XQueueAddToQueueError
as
exc
:
new_status
=
ExampleCertificate
.
STATUS_ERROR
cert
.
status
=
new_status
cert
.
error_reason
=
unicode
(
exc
)
cert
.
save
()
LOGGER
.
critical
(
(
u"Could not add certificate task to XQueue. "
u"The course was '
%
s' and the student was '
%
s'."
u"The certificate task status has been marked as 'error' "
u"and can be re-submitted with a management command."
),
course_id
,
student
.
id
)
else
:
LOGGER
.
info
(
(
u"The certificate status has been set to '
%
s'. "
u"Sent a certificate grading task to the XQueue "
u"with the key '
%
s'. "
),
new_status
,
key
)
else
:
new_status
=
status
.
notpassing
cert
.
status
=
new_status
...
...
lms/djangoapps/certificates/tests/test_api.py
View file @
c4175c7d
...
...
@@ -4,6 +4,7 @@ import ddt
from
django.test
import
TestCase
,
RequestFactory
from
django.test.utils
import
override_settings
from
django.conf
import
settings
from
mock
import
patch
from
nose.plugins.attrib
import
attr
...
...
@@ -25,6 +26,9 @@ from certificates.models import (
from
certificates.queue
import
XQueueCertInterface
,
XQueueAddToQueueError
from
certificates.tests.factories
import
GeneratedCertificateFactory
FEATURES_WITH_CERTS_ENABLED
=
settings
.
FEATURES
.
copy
()
FEATURES_WITH_CERTS_ENABLED
[
'CERTIFICATES_HTML_VIEW'
]
=
True
@attr
(
'shard_1'
)
class
CertificateDownloadableStatusTests
(
ModuleStoreTestCase
):
...
...
@@ -134,7 +138,7 @@ class GenerateUserCertificatesTest(ModuleStoreTestCase):
# Verify that the certificate has status 'generating'
cert
=
GeneratedCertificate
.
objects
.
get
(
user
=
self
.
student
,
course_id
=
self
.
course
.
id
)
self
.
assertEqual
(
cert
.
status
,
'generating'
)
self
.
assertEqual
(
cert
.
status
,
CertificateStatuses
.
generating
)
def
test_xqueue_submit_task_error
(
self
):
with
self
.
_mock_passing_grade
():
...
...
@@ -146,6 +150,19 @@ class GenerateUserCertificatesTest(ModuleStoreTestCase):
self
.
assertEqual
(
cert
.
status
,
'error'
)
self
.
assertIn
(
self
.
ERROR_REASON
,
cert
.
error_reason
)
@override_settings
(
FEATURES
=
FEATURES_WITH_CERTS_ENABLED
)
def
test_new_cert_requests_returns_generating_for_html_certificate
(
self
):
"""
Test no message sent to Xqueue if HTML certificate view is enabled
"""
self
.
_setup_course_certificate
()
with
self
.
_mock_passing_grade
():
certs_api
.
generate_user_certificates
(
self
.
student
,
self
.
course
.
id
)
# Verify that the certificate has status 'downloadable'
cert
=
GeneratedCertificate
.
objects
.
get
(
user
=
self
.
student
,
course_id
=
self
.
course
.
id
)
self
.
assertEqual
(
cert
.
status
,
CertificateStatuses
.
downloadable
)
@contextmanager
def
_mock_passing_grade
(
self
):
"""Mock the grading function to always return a passing grade. """
...
...
@@ -166,6 +183,26 @@ class GenerateUserCertificatesTest(ModuleStoreTestCase):
yield
mock_send_to_queue
def
_setup_course_certificate
(
self
):
"""
Creates certificate configuration for course
"""
certificates
=
[
{
'id'
:
1
,
'name'
:
'Test Certificate Name'
,
'description'
:
'Test Certificate Description'
,
'course_title'
:
'tes_course_title'
,
'org_logo_path'
:
'/t4x/orgX/testX/asset/org-logo.png'
,
'signatories'
:
[],
'version'
:
1
,
'is_active'
:
True
}
]
self
.
course
.
certificates
=
{
'certificates'
:
certificates
}
self
.
course
.
save
()
self
.
store
.
update_item
(
self
.
course
,
self
.
user
.
id
)
@attr
(
'shard_1'
)
@ddt.ddt
...
...
lms/djangoapps/certificates/tests/test_cert_management.py
View file @
c4175c7d
"""Tests for the resubmit_error_certificates management command. """
import
ddt
from
contextlib
import
contextmanager
from
django.core.management.base
import
CommandError
from
nose.plugins.attrib
import
attr
from
django.test.utils
import
override_settings
...
...
@@ -10,7 +11,7 @@ from certificates.tests.factories import BadgeAssertionFactory
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
,
check_mongo_calls
from
student.tests.factories
import
UserFactory
,
CourseEnrollmentFactory
from
certificates.management.commands
import
resubmit_error_certificates
,
regenerate_user
from
certificates.management.commands
import
resubmit_error_certificates
,
regenerate_user
,
ungenerated_certs
from
certificates.models
import
GeneratedCertificate
,
CertificateStatuses
,
BadgeAssertion
...
...
@@ -157,7 +158,7 @@ class RegenerateCertificatesTest(CertificateManagementTest):
self
.
course
=
self
.
courses
[
0
]
@override_settings
(
CERT_QUEUE
=
'test-queue'
)
@patch
(
'certificates.
management.commands.regenerate_user
.XQueueCertInterface'
,
spec
=
True
)
@patch
(
'certificates.
api
.XQueueCertInterface'
,
spec
=
True
)
def
test_clear_badge
(
self
,
xqueue
):
"""
Given that I have a user with a badge
...
...
@@ -174,6 +175,72 @@ class RegenerateCertificatesTest(CertificateManagementTest):
grade_value
=
None
)
xqueue
.
return_value
.
regen_cert
.
assert_called_with
(
self
.
user
,
key
,
course
=
self
.
course
,
forced_grade
=
None
,
template_file
=
Non
e
self
.
user
,
key
,
self
.
course
,
None
,
None
,
Tru
e
)
self
.
assertFalse
(
BadgeAssertion
.
objects
.
filter
(
user
=
self
.
user
,
course_id
=
key
))
@override_settings
(
CERT_QUEUE
=
'test-queue'
)
@patch
(
'capa.xqueue_interface.XQueueInterface.send_to_queue'
,
spec
=
True
)
def
test_regenerating_certificate
(
self
,
mock_send_to_queue
):
"""
Given that I have a user who has not passed course
If I run regeneration for that user
Then certificate generation will be not be requested
"""
key
=
self
.
course
.
location
.
course_key
self
.
_create_cert
(
key
,
self
.
user
,
CertificateStatuses
.
downloadable
)
self
.
_run_command
(
username
=
self
.
user
.
email
,
course
=
unicode
(
key
),
noop
=
False
,
insecure
=
True
,
template_file
=
None
,
grade_value
=
None
)
certificate
=
GeneratedCertificate
.
objects
.
get
(
user
=
self
.
user
,
course_id
=
key
)
self
.
assertEqual
(
certificate
.
status
,
CertificateStatuses
.
notpassing
)
self
.
assertFalse
(
mock_send_to_queue
.
called
)
@attr
(
'shard_1'
)
class
UngenerateCertificatesTest
(
CertificateManagementTest
):
"""
Tests for generating certificates.
"""
command
=
ungenerated_certs
def
setUp
(
self
):
"""
We just need one course here.
"""
super
(
UngenerateCertificatesTest
,
self
)
.
setUp
()
self
.
course
=
self
.
courses
[
0
]
@override_settings
(
CERT_QUEUE
=
'test-queue'
)
@patch
(
'capa.xqueue_interface.XQueueInterface.send_to_queue'
,
spec
=
True
)
def
test_ungenerated_certificate
(
self
,
mock_send_to_queue
):
"""
Given that I have ended course
If I run ungenerated certs command
Then certificates should be generated for all users who passed course
"""
mock_send_to_queue
.
return_value
=
(
0
,
"Successfully queued"
)
key
=
self
.
course
.
location
.
course_key
self
.
_create_cert
(
key
,
self
.
user
,
CertificateStatuses
.
unavailable
)
with
self
.
_mock_passing_grade
():
self
.
_run_command
(
course
=
unicode
(
key
),
noop
=
False
,
insecure
=
True
,
force
=
False
)
self
.
assertTrue
(
mock_send_to_queue
.
called
)
certificate
=
GeneratedCertificate
.
objects
.
get
(
user
=
self
.
user
,
course_id
=
key
)
self
.
assertEqual
(
certificate
.
status
,
CertificateStatuses
.
generating
)
@contextmanager
def
_mock_passing_grade
(
self
):
"""Mock the grading function to always return a passing grade. """
symbol
=
'courseware.grades.grade'
with
patch
(
symbol
)
as
mock_grade
:
mock_grade
.
return_value
=
{
'grade'
:
'Pass'
,
'percent'
:
0.75
}
yield
lms/djangoapps/certificates/tests/test_queue.py
View file @
c4175c7d
...
...
@@ -54,6 +54,17 @@ class XQueueCertInterfaceAddCertificateTest(ModuleStoreTestCase):
actual_header
=
json
.
loads
(
kwargs
[
'header'
])
self
.
assertIn
(
'https://edx.org/update_certificate?key='
,
actual_header
[
'lms_callback_url'
])
def
test_no_create_action_in_queue_for_html_view_certs
(
self
):
"""
Tests there is no certificate create message in the queue if generate_pdf is False
"""
with
patch
(
'courseware.grades.grade'
,
Mock
(
return_value
=
{
'grade'
:
'Pass'
,
'percent'
:
0.75
})):
with
patch
.
object
(
XQueueInterface
,
'send_to_queue'
)
as
mock_send
:
self
.
xqueue
.
add_cert
(
self
.
user
,
self
.
course
.
id
,
generate_pdf
=
False
)
# Verify that add_cert method does not add message to queue
self
.
assertFalse
(
mock_send
.
called
)
@attr
(
'shard_1'
)
@override_settings
(
CERT_QUEUE
=
'certificates'
)
...
...
lms/djangoapps/certificates/tests/test_views.py
View file @
c4175c7d
...
...
@@ -4,6 +4,7 @@ import json
import
ddt
from
uuid
import
uuid4
from
nose.plugins.attrib
import
attr
from
mock
import
patch
from
django.conf
import
settings
from
django.core.cache
import
cache
...
...
@@ -14,13 +15,20 @@ from django.test.utils import override_settings
from
opaque_keys.edx.locator
import
CourseLocator
from
openedx.core.lib.tests.assertions.events
import
assert_event_matches
from
student.tests.factories
import
UserFactory
from
student.tests.factories
import
UserFactory
,
CourseEnrollmentFactory
from
track.tests
import
EventTrackingTestCase
from
xmodule.modulestore.tests.factories
import
CourseFactory
from
xmodule.modulestore.tests.django_utils
import
ModuleStoreTestCase
from
certificates.api
import
get_certificate_url
from
certificates.models
import
ExampleCertificateSet
,
ExampleCertificate
,
GeneratedCertificate
,
BadgeAssertion
from
certificates.models
import
(
ExampleCertificateSet
,
ExampleCertificate
,
GeneratedCertificate
,
BadgeAssertion
,
CertificateStatuses
)
from
certificates.tests.factories
import
(
CertificateHtmlViewConfigurationFactory
,
LinkedInAddToProfileConfigurationFactory
,
...
...
@@ -210,6 +218,10 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
mode
=
'honor'
,
name
=
self
.
user
.
profile
.
name
,
)
CourseEnrollmentFactory
.
create
(
user
=
self
.
user
,
course_id
=
self
.
course_id
)
CertificateHtmlViewConfigurationFactory
.
create
()
LinkedInAddToProfileConfigurationFactory
.
create
()
...
...
@@ -454,6 +466,31 @@ class CertificatesViewsTests(ModuleStoreTestCase, EventTrackingTestCase):
self
.
get_event
()
)
@override_settings
(
FEATURES
=
FEATURES_WITH_CERTS_DISABLED
)
def
test_request_certificate_without_passing
(
self
):
self
.
cert
.
status
=
CertificateStatuses
.
unavailable
self
.
cert
.
save
()
request_certificate_url
=
reverse
(
'certificates.views.request_certificate'
)
response
=
self
.
client
.
post
(
request_certificate_url
,
{
'course_id'
:
unicode
(
self
.
course
.
id
)})
self
.
assertEqual
(
response
.
status_code
,
200
)
response_json
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
CertificateStatuses
.
notpassing
,
response_json
[
'add_status'
])
@override_settings
(
FEATURES
=
FEATURES_WITH_CERTS_DISABLED
)
@override_settings
(
CERT_QUEUE
=
'test-queue'
)
def
test_request_certificate_after_passing
(
self
):
self
.
cert
.
status
=
CertificateStatuses
.
unavailable
self
.
cert
.
save
()
request_certificate_url
=
reverse
(
'certificates.views.request_certificate'
)
with
patch
(
'capa.xqueue_interface.XQueueInterface.send_to_queue'
)
as
mock_queue
:
mock_queue
.
return_value
=
(
0
,
"Successfully queued"
)
with
patch
(
'courseware.grades.grade'
)
as
mock_grade
:
mock_grade
.
return_value
=
{
'grade'
:
'Pass'
,
'percent'
:
0.75
}
response
=
self
.
client
.
post
(
request_certificate_url
,
{
'course_id'
:
unicode
(
self
.
course
.
id
)})
self
.
assertEqual
(
response
.
status_code
,
200
)
response_json
=
json
.
loads
(
response
.
content
)
self
.
assertEqual
(
CertificateStatuses
.
generating
,
response_json
[
'add_status'
])
class
TrackShareRedirectTest
(
ModuleStoreTestCase
,
EventTrackingTestCase
):
"""
...
...
lms/djangoapps/certificates/views.py
View file @
c4175c7d
...
...
@@ -16,7 +16,7 @@ from django.views.decorators.csrf import csrf_exempt
from
django.views.decorators.http
import
require_POST
from
capa.xqueue_interface
import
XQUEUE_METRIC_NAME
from
certificates.api
import
get_active_web_certificate
,
get_certificate_url
from
certificates.api
import
get_active_web_certificate
,
get_certificate_url
,
generate_user_certificates
from
certificates.models
import
(
certificate_status_for_student
,
CertificateStatuses
,
...
...
@@ -56,7 +56,6 @@ def request_certificate(request):
"""
if
request
.
method
==
"POST"
:
if
request
.
user
.
is_authenticated
():
xqci
=
XQueueCertInterface
()
username
=
request
.
user
.
username
student
=
User
.
objects
.
get
(
username
=
username
)
course_key
=
SlashSeparatedCourseKey
.
from_deprecated_string
(
request
.
POST
.
get
(
'course_id'
))
...
...
@@ -66,7 +65,7 @@ def request_certificate(request):
if
status
in
[
CertificateStatuses
.
unavailable
,
CertificateStatuses
.
notpassing
,
CertificateStatuses
.
error
]:
log_msg
=
u'Grading and certification requested for user
%
s in course
%
s via /request_certificate call'
logger
.
info
(
log_msg
,
username
,
course_key
)
status
=
xqci
.
add_cert
(
student
,
course_key
,
course
=
course
)
status
=
generate_user_certificates
(
student
,
course_key
,
course
=
course
)
return
HttpResponse
(
json
.
dumps
({
'add_status'
:
status
}),
mimetype
=
'application/json'
)
return
HttpResponse
(
json
.
dumps
({
'add_status'
:
'ERRORANONYMOUSUSER'
}),
mimetype
=
'application/json'
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment