Unverified Commit 3d884d6c by John Eskew Committed by GitHub

Merge pull request #16428 from edx/jeskew/email_mkting_lti_prov_to_appconfig_ready

Move lti_provider/email_marketing startup to AppConfig ready.
parents 333e1ccb 878d3eff
"""
Configuration for the edxmako Django application.
"""
from django.apps import AppConfig
from django.conf import settings
from . import add_lookup, clear_lookups
class EdxMakoConfig(AppConfig):
"""
Configuration class for the edxmako Django application.
"""
name = 'edxmako'
verbose_name = "edX Mako Templating"
......
"""
Configuration for the email_marketing Django application.
"""
from django.apps import AppConfig
class EmailMarketingConfig(AppConfig):
"""
Configuration class for the email_marketing Django application.
"""
name = 'email_marketing'
verbose_name = "Email Marketing"
def ready(self):
# Register the signal handlers.
from . import signals # pylint: disable=unused-import
""" email_marketing app. """
# this is here to support registering the signals in signals.py
from email_marketing import signals # pylint: disable=unused-import
"""
Configuration for the lti_provider Django application.
"""
from django.apps import AppConfig
class LtiProviderConfig(AppConfig):
"""
Configuration class for the lti_provider Django application.
"""
name = 'lti_provider'
verbose_name = "LTI Provider"
def ready(self):
# Import the tasks module to ensure that signal handlers are registered.
from . import signals # pylint: disable=unused-import
"""
Signals handlers for the lti_provider Django app.
"""
from __future__ import absolute_import
import logging
from django.conf import settings
from django.dispatch import receiver
import lti_provider.outcomes as outcomes
from lms.djangoapps.grades.signals.signals import PROBLEM_WEIGHTED_SCORE_CHANGED
from lti_provider.views import parse_course_and_usage_keys
from xmodule.modulestore.django import modulestore
from .tasks import send_composite_outcome, send_leaf_outcome
log = logging.getLogger(__name__)
def increment_assignment_versions(course_key, usage_key, user_id):
"""
Update the version numbers for all assignments that are affected by a score
change event. Returns a list of all affected assignments.
"""
problem_descriptor = modulestore().get_item(usage_key)
# Get all assignments involving the current problem for which the campus LMS
# is expecting a grade. There may be many possible graded assignments, if
# a problem has been added several times to a course at different
# granularities (such as the unit or the vertical).
assignments = outcomes.get_assignments_for_problem(
problem_descriptor, user_id, course_key
)
for assignment in assignments:
assignment.version_number += 1
assignment.save()
return assignments
@receiver(PROBLEM_WEIGHTED_SCORE_CHANGED)
def score_changed_handler(sender, **kwargs): # pylint: disable=unused-argument
"""
Consume signals that indicate score changes. See the definition of
PROBLEM_WEIGHTED_SCORE_CHANGED for a description of the signal.
"""
points_possible = kwargs.get('weighted_possible', None)
points_earned = kwargs.get('weighted_earned', None)
user_id = kwargs.get('user_id', None)
course_id = kwargs.get('course_id', None)
usage_id = kwargs.get('usage_id', None)
if None not in (points_earned, points_possible, user_id, course_id):
course_key, usage_key = parse_course_and_usage_keys(course_id, usage_id)
assignments = increment_assignment_versions(course_key, usage_key, user_id)
for assignment in assignments:
if assignment.usage_key == usage_key:
send_leaf_outcome.delay(
assignment.id, points_earned, points_possible
)
else:
send_composite_outcome.apply_async(
(user_id, course_id, assignment.id, assignment.version_number),
countdown=settings.LTI_AGGREGATE_SCORE_PASSBACK_DELAY
)
else:
log.error(
"Outcome Service: Required signal parameter is None. "
"points_possible: %s, points_earned: %s, user_id: %s, "
"course_id: %s, usage_id: %s",
points_possible, points_earned, user_id, course_id, usage_id
)
"""Code run at server start up to initialize the lti_provider app."""
# Import the tasks module to ensure that signal handlers are registered.
import lms.djangoapps.lti_provider.tasks # pylint: disable=unused-import
......@@ -4,73 +4,16 @@ Asynchronous tasks for the LTI provider app.
import logging
from django.conf import settings
from django.contrib.auth.models import User
from django.dispatch import receiver
from opaque_keys.edx.keys import CourseKey
import lti_provider.outcomes as outcomes
from lms import CELERY_APP
from lms.djangoapps.grades.course_grade_factory import CourseGradeFactory
from lms.djangoapps.grades.signals.signals import PROBLEM_WEIGHTED_SCORE_CHANGED
from lti_provider.models import GradedAssignment
from lti_provider.views import parse_course_and_usage_keys
from xmodule.modulestore.django import modulestore
log = logging.getLogger("edx.lti_provider")
@receiver(PROBLEM_WEIGHTED_SCORE_CHANGED)
def score_changed_handler(sender, **kwargs): # pylint: disable=unused-argument
"""
Consume signals that indicate score changes. See the definition of
PROBLEM_WEIGHTED_SCORE_CHANGED for a description of the signal.
"""
points_possible = kwargs.get('weighted_possible', None)
points_earned = kwargs.get('weighted_earned', None)
user_id = kwargs.get('user_id', None)
course_id = kwargs.get('course_id', None)
usage_id = kwargs.get('usage_id', None)
if None not in (points_earned, points_possible, user_id, course_id):
course_key, usage_key = parse_course_and_usage_keys(course_id, usage_id)
assignments = increment_assignment_versions(course_key, usage_key, user_id)
for assignment in assignments:
if assignment.usage_key == usage_key:
send_leaf_outcome.delay(
assignment.id, points_earned, points_possible
)
else:
send_composite_outcome.apply_async(
(user_id, course_id, assignment.id, assignment.version_number),
countdown=settings.LTI_AGGREGATE_SCORE_PASSBACK_DELAY
)
else:
log.error(
"Outcome Service: Required signal parameter is None. "
"points_possible: %s, points_earned: %s, user_id: %s, "
"course_id: %s, usage_id: %s",
points_possible, points_earned, user_id, course_id, usage_id
)
def increment_assignment_versions(course_key, usage_key, user_id):
"""
Update the version numbers for all assignments that are affected by a score
change event. Returns a list of all affected assignments.
"""
problem_descriptor = modulestore().get_item(usage_key)
# Get all assignments involving the current problem for which the campus LMS
# is expecting a grade. There may be many possible graded assignments, if
# a problem has been added several times to a course at different
# granularities (such as the unit or the vertical).
assignments = outcomes.get_assignments_for_problem(
problem_descriptor, user_id, course_key
)
for assignment in assignments:
assignment.version_number += 1
assignment.save()
return assignments
log = logging.getLogger(__name__)
@CELERY_APP.task(name='lti_provider.tasks.send_composite_outcome')
......
......@@ -869,7 +869,7 @@ CREDIT_PROVIDER_SECRET_KEYS = AUTH_TOKENS.get("CREDIT_PROVIDER_SECRET_KEYS", {})
##################### LTI Provider #####################
if FEATURES.get('ENABLE_LTI_PROVIDER'):
INSTALLED_APPS.append('lti_provider')
INSTALLED_APPS.append('lti_provider.apps.LtiProviderConfig')
AUTHENTICATION_BACKENDS.append('lti_provider.users.LtiBackend')
LTI_USER_EMAIL_DOMAIN = ENV_TOKENS.get('LTI_USER_EMAIL_DOMAIN', 'lti.example.com')
......
......@@ -2289,7 +2289,7 @@ INSTALLED_APPS = [
'django_sites_extensions',
# Email marketing integration
'email_marketing',
'email_marketing.apps.EmailMarketingConfig',
# additional release utilities to ease automation
'release_util',
......
......@@ -571,7 +571,7 @@ PROFILE_IMAGE_MIN_BYTES = 100
# Enable the LTI provider feature for testing
FEATURES['ENABLE_LTI_PROVIDER'] = True
INSTALLED_APPS.append('lti_provider')
INSTALLED_APPS.append('lti_provider.apps.LtiProviderConfig')
AUTHENTICATION_BACKENDS.append('lti_provider.users.LtiBackend')
# ORGANIZATIONS
......
......@@ -319,7 +319,7 @@ if FEATURES.get('INDIVIDUAL_DUE_DATES'):
##################### LTI Provider #####################
if FEATURES.get('ENABLE_LTI_PROVIDER'):
INSTALLED_APPS.append('lti_provider')
INSTALLED_APPS.append('lti_provider.apps.LtiProviderConfig')
AUTHENTICATION_BACKENDS.append('lti_provider.users.LtiBackend')
################################ Settings for Credentials Service ################################
......
......@@ -231,14 +231,7 @@ class TestUserPreferenceMiddleware(TestCase):
# No preference yet, should write to the database
self.assertEqual(get_user_preference(self.user, LANGUAGE_KEY), None)
# The 'email_marketing' app is installed in the LMS env but not the CMS env. It listens for the
# USER_FIELD_CHANGED signal (utils.model_utils) and does a query to check the EmailMarketingConfiguration
# table to see if Sailthru integreation is enabled.
expected_queries = 6 if 'email_marketing' in settings.INSTALLED_APPS else 5
with self.assertNumQueries(expected_queries):
self.middleware.process_request(self.request)
self.middleware.process_request(self.request)
self.assertEqual(get_user_preference(self.user, LANGUAGE_KEY), 'es')
response = mock.Mock(spec=HttpResponse)
......@@ -261,14 +254,7 @@ class TestUserPreferenceMiddleware(TestCase):
# Cookie changed, should write to the database again
self.request.COOKIES[settings.LANGUAGE_COOKIE] = 'en'
# The 'email_marketing' app is installed in the LMS env but not the CMS env. It listens for the
# USER_FIELD_CHANGED signal (utils.model_utils) and does a query to check the EmailMarketingConfiguration
# table to see if Sailthru integreation is enabled.
expected_queries = 6 if 'email_marketing' in settings.INSTALLED_APPS else 5
with self.assertNumQueries(expected_queries):
self.middleware.process_request(self.request)
self.middleware.process_request(self.request)
self.assertEqual(get_user_preference(self.user, LANGUAGE_KEY), 'en')
with self.assertNumQueries(1):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment