From 7d79f4fe3757a08e676bd906a392dd4bdf20961d Mon Sep 17 00:00:00 2001 From: Calen Pennington <cale@edx.org> Date: Tue, 27 Aug 2013 15:52:14 -0400 Subject: [PATCH] Move mitxmako initialization to a startup module, called by lms.startup and cms.startup for both management commands and when run via wsgi [DEVPAIN-7] --- common/djangoapps/mitxmako/middleware.py | 25 ------------------------- common/djangoapps/mitxmako/shortcuts.py | 8 ++++---- common/djangoapps/mitxmako/startup.py | 33 +++++++++++++++++++++++++++++++++ common/djangoapps/mitxmako/template.py | 9 +++++---- common/djangoapps/student/management/commands/6002exportusers.py | 4 ---- common/djangoapps/student/management/commands/6002importusers.py | 4 ---- common/djangoapps/student/management/commands/assigngroups.py | 3 --- common/djangoapps/student/management/commands/emaillist.py | 4 ---- common/djangoapps/student/management/commands/massemail.py | 8 +++----- common/djangoapps/student/management/commands/massemailtxt.py | 8 +++----- common/djangoapps/student/management/commands/userinfo.py | 3 --- common/lib/django_startup.py | 2 +- lms/djangoapps/certificates/queue.py | 9 --------- lms/djangoapps/courseware/management/commands/check_course.py | 2 -- lms/djangoapps/courseware/tests/test_views.py | 5 +++++ lms/djangoapps/instructor_task/tasks_helper.py | 21 --------------------- 16 files changed, 54 insertions(+), 94 deletions(-) create mode 100644 common/djangoapps/mitxmako/startup.py diff --git a/common/djangoapps/mitxmako/middleware.py b/common/djangoapps/mitxmako/middleware.py index 5646d2f..daaddf6 100644 --- a/common/djangoapps/mitxmako/middleware.py +++ b/common/djangoapps/mitxmako/middleware.py @@ -12,36 +12,11 @@ # See the License for the specific language governing permissions and # limitations under the License. -from mako.lookup import TemplateLookup -import tempdir from django.template import RequestContext -from django.conf import settings requestcontext = None -lookup = {} - class MakoMiddleware(object): - def __init__(self): - """Setup mako variables and lookup object""" - # Set all mako variables based on django settings - template_locations = settings.MAKO_TEMPLATES - module_directory = getattr(settings, 'MAKO_MODULE_DIR', None) - - if module_directory is None: - module_directory = tempdir.mkdtemp_clean() - - for location in template_locations: - lookup[location] = TemplateLookup(directories=template_locations[location], - module_directory=module_directory, - output_encoding='utf-8', - input_encoding='utf-8', - default_filters=['decode.utf8'], - encoding_errors='replace', - ) - - import mitxmako - mitxmako.lookup = lookup def process_request(self, request): global requestcontext diff --git a/common/djangoapps/mitxmako/shortcuts.py b/common/djangoapps/mitxmako/shortcuts.py index 3c68fa8..974eaef 100644 --- a/common/djangoapps/mitxmako/shortcuts.py +++ b/common/djangoapps/mitxmako/shortcuts.py @@ -16,7 +16,7 @@ from django.template import Context from django.http import HttpResponse import logging -from . import middleware +import mitxmako from django.conf import settings from django.core.urlresolvers import reverse log = logging.getLogger(__name__) @@ -80,15 +80,15 @@ def render_to_string(template_name, dictionary, context=None, namespace='main'): context_instance['marketing_link'] = marketing_link # In various testing contexts, there might not be a current request context. - if middleware.requestcontext is not None: - for d in middleware.requestcontext: + if mitxmako.middleware.requestcontext is not None: + for d in mitxmako.middleware.requestcontext: context_dictionary.update(d) for d in context_instance: context_dictionary.update(d) if context: context_dictionary.update(context) # fetch and render template - template = middleware.lookup[namespace].get_template(template_name) + template = mitxmako.lookup[namespace].get_template(template_name) return template.render_unicode(**context_dictionary) diff --git a/common/djangoapps/mitxmako/startup.py b/common/djangoapps/mitxmako/startup.py new file mode 100644 index 0000000..db9483b --- /dev/null +++ b/common/djangoapps/mitxmako/startup.py @@ -0,0 +1,33 @@ +""" +Initialize the mako template lookup +""" + +import tempdir +from django.conf import settings +from mako.lookup import TemplateLookup + +import mitxmako + + +def run(): + """Setup mako variables and lookup object""" + # Set all mako variables based on django settings + template_locations = settings.MAKO_TEMPLATES + module_directory = getattr(settings, 'MAKO_MODULE_DIR', None) + + if module_directory is None: + module_directory = tempdir.mkdtemp_clean() + + lookup = {} + + for location in template_locations: + lookup[location] = TemplateLookup( + directories=template_locations[location], + module_directory=module_directory, + output_encoding='utf-8', + input_encoding='utf-8', + default_filters=['decode.utf8'], + encoding_errors='replace', + ) + + mitxmako.lookup = lookup diff --git a/common/djangoapps/mitxmako/template.py b/common/djangoapps/mitxmako/template.py index 5becfbf..7dfc6de 100644 --- a/common/djangoapps/mitxmako/template.py +++ b/common/djangoapps/mitxmako/template.py @@ -16,7 +16,8 @@ from django.conf import settings from mako.template import Template as MakoTemplate from mitxmako.shortcuts import marketing_link -from mitxmako import middleware +import mitxmako +import mitxmako.middleware django_variables = ['lookup', 'output_encoding', 'encoding_errors'] @@ -33,7 +34,7 @@ class Template(MakoTemplate): def __init__(self, *args, **kwargs): """Overrides base __init__ to provide django variable overrides""" if not kwargs.get('no_django', False): - overrides = dict([(k, getattr(middleware, k, None),) for k in django_variables]) + overrides = dict([(k, getattr(mitxmako, k, None),) for k in django_variables]) overrides['lookup'] = overrides['lookup']['main'] kwargs.update(overrides) super(Template, self).__init__(*args, **kwargs) @@ -47,8 +48,8 @@ class Template(MakoTemplate): context_dictionary = {} # In various testing contexts, there might not be a current request context. - if middleware.requestcontext is not None: - for d in middleware.requestcontext: + if mitxmako.middleware.requestcontext is not None: + for d in mitxmako.middleware.requestcontext: context_dictionary.update(d) for d in context_instance: context_dictionary.update(d) diff --git a/common/djangoapps/student/management/commands/6002exportusers.py b/common/djangoapps/student/management/commands/6002exportusers.py index a92bb0a..a36d6e8 100644 --- a/common/djangoapps/student/management/commands/6002exportusers.py +++ b/common/djangoapps/student/management/commands/6002exportusers.py @@ -16,10 +16,6 @@ from django.contrib.auth.models import User from student.models import UserProfile -import mitxmako.middleware as middleware - -middleware.MakoMiddleware() - class Command(BaseCommand): help = \ diff --git a/common/djangoapps/student/management/commands/6002importusers.py b/common/djangoapps/student/management/commands/6002importusers.py index 1f98bd7..93d86df 100644 --- a/common/djangoapps/student/management/commands/6002importusers.py +++ b/common/djangoapps/student/management/commands/6002importusers.py @@ -12,10 +12,6 @@ from django.contrib.auth.models import User from student.models import UserProfile -import mitxmako.middleware as middleware - -middleware.MakoMiddleware() - def import_user(u): user_info = u['u'] diff --git a/common/djangoapps/student/management/commands/assigngroups.py b/common/djangoapps/student/management/commands/assigngroups.py index 3e36bf3..cbd5cfa 100644 --- a/common/djangoapps/student/management/commands/assigngroups.py +++ b/common/djangoapps/student/management/commands/assigngroups.py @@ -1,7 +1,6 @@ from django.core.management.base import BaseCommand from django.contrib.auth.models import User -import mitxmako.middleware as middleware from student.models import UserTestGroup import random @@ -11,8 +10,6 @@ import datetime import json from pytz import UTC -middleware.MakoMiddleware() - def group_from_value(groups, v): ''' Given group: (('a',0.3),('b',0.4),('c',0.3)) And random value diff --git a/common/djangoapps/student/management/commands/emaillist.py b/common/djangoapps/student/management/commands/emaillist.py index d391192..e69b072 100644 --- a/common/djangoapps/student/management/commands/emaillist.py +++ b/common/djangoapps/student/management/commands/emaillist.py @@ -1,10 +1,6 @@ from django.core.management.base import BaseCommand from django.contrib.auth.models import User -import mitxmako.middleware as middleware - -middleware.MakoMiddleware() - class Command(BaseCommand): help = \ diff --git a/common/djangoapps/student/management/commands/massemail.py b/common/djangoapps/student/management/commands/massemail.py index 1bb65fd..a1864f0 100644 --- a/common/djangoapps/student/management/commands/massemail.py +++ b/common/djangoapps/student/management/commands/massemail.py @@ -1,9 +1,7 @@ from django.core.management.base import BaseCommand from django.contrib.auth.models import User -import mitxmako.middleware as middleware - -middleware.MakoMiddleware() +import mitxmako class Command(BaseCommand): @@ -17,8 +15,8 @@ body, and an _subject.txt for the subject. ''' #text = open(args[0]).read() #subject = open(args[1]).read() users = User.objects.all() - text = middleware.lookup['main'].get_template('email/' + args[0] + ".txt").render() - subject = middleware.lookup['main'].get_template('email/' + args[0] + "_subject.txt").render().strip() + text = mitxmako.lookup['main'].get_template('email/' + args[0] + ".txt").render() + subject = mitxmako.lookup['main'].get_template('email/' + args[0] + "_subject.txt").render().strip() for user in users: if user.is_active: user.email_user(subject, text) diff --git a/common/djangoapps/student/management/commands/massemailtxt.py b/common/djangoapps/student/management/commands/massemailtxt.py index ae25430..0228acf 100644 --- a/common/djangoapps/student/management/commands/massemailtxt.py +++ b/common/djangoapps/student/management/commands/massemailtxt.py @@ -4,15 +4,13 @@ import time from django.core.management.base import BaseCommand from django.conf import settings -import mitxmako.middleware as middleware +import mitxmako from django.core.mail import send_mass_mail import sys import datetime -middleware.MakoMiddleware() - def chunks(l, n): """ Yield successive n-sized chunks from l. @@ -41,8 +39,8 @@ rate -- messages per second users = [u.strip() for u in open(user_file).readlines()] - message = middleware.lookup['main'].get_template('emails/' + message_base + "_body.txt").render() - subject = middleware.lookup['main'].get_template('emails/' + message_base + "_subject.txt").render().strip() + message = mitxmako.lookup['main'].get_template('emails/' + message_base + "_body.txt").render() + subject = mitxmako.lookup['main'].get_template('emails/' + message_base + "_subject.txt").render().strip() rate = int(ratestr) self.log_file = open(logfilename, "a+", buffering=0) diff --git a/common/djangoapps/student/management/commands/userinfo.py b/common/djangoapps/student/management/commands/userinfo.py index 5467db1..8656fb9 100644 --- a/common/djangoapps/student/management/commands/userinfo.py +++ b/common/djangoapps/student/management/commands/userinfo.py @@ -1,13 +1,10 @@ from django.core.management.base import BaseCommand from django.contrib.auth.models import User -import mitxmako.middleware as middleware import json from student.models import UserProfile -middleware.MakoMiddleware() - class Command(BaseCommand): help = \ diff --git a/common/lib/django_startup.py b/common/lib/django_startup.py index 1987d02..1432ea0 100644 --- a/common/lib/django_startup.py +++ b/common/lib/django_startup.py @@ -7,7 +7,7 @@ def autostartup(): """ for app in settings.INSTALLED_APPS: try: - mod = import_module('{}.startup') + mod = import_module(app + '.startup') if hasattr(mod, 'run'): mod.run() except ImportError: diff --git a/lms/djangoapps/certificates/queue.py b/lms/djangoapps/certificates/queue.py index 78e786e..bc7bbc0 100644 --- a/lms/djangoapps/certificates/queue.py +++ b/lms/djangoapps/certificates/queue.py @@ -3,7 +3,6 @@ from certificates.models import certificate_status_for_student from certificates.models import CertificateStatuses as status from certificates.models import CertificateWhitelist -from mitxmako.middleware import MakoMiddleware from courseware import grades, courses from django.test.client import RequestFactory from capa.xqueue_interface import XQueueInterface @@ -52,14 +51,6 @@ class XQueueCertInterface(object): """ def __init__(self, request=None): - # MakoMiddleware Note: - # Line below has the side-effect of writing to a module level lookup - # table that will allow problems to render themselves. If this is not - # present, problems that a student hasn't seen will error when loading, - # causing the grading system to under-count the possible score and - # inflate their grade. This dependency is bad and was probably recently - # introduced. This is the bandage until we can trace the root cause. - m = MakoMiddleware() # Get basic auth (username/password) for # xqueue connection if it's in the settings diff --git a/lms/djangoapps/courseware/management/commands/check_course.py b/lms/djangoapps/courseware/management/commands/check_course.py index 58f8933..a4f2bcc 100644 --- a/lms/djangoapps/courseware/management/commands/check_course.py +++ b/lms/djangoapps/courseware/management/commands/check_course.py @@ -10,8 +10,6 @@ from django.contrib.auth.models import User import xmodule -import mitxmako.middleware as middleware -middleware.MakoMiddleware() from xmodule.modulestore.django import modulestore from courseware.model_data import ModelDataCache from courseware.module_render import get_module diff --git a/lms/djangoapps/courseware/tests/test_views.py b/lms/djangoapps/courseware/tests/test_views.py index c6c382c..b4e835d 100644 --- a/lms/djangoapps/courseware/tests/test_views.py +++ b/lms/djangoapps/courseware/tests/test_views.py @@ -12,6 +12,7 @@ from django.core.urlresolvers import reverse from student.models import CourseEnrollment from student.tests.factories import AdminFactory +from mitxmako.middleware import MakoMiddleware from xmodule.modulestore.django import modulestore @@ -135,6 +136,10 @@ class ViewsTestCase(TestCase): def verify_end_date(self, course_id, expected_end_text=None): request = self.request_factory.get("foo") request.user = self.user + + # TODO: Remove the dependency on MakoMiddleware (by making the views explicitly supply a RequestContext) + MakoMiddleware().process_request(request) + result = views.course_about(request, course_id) if expected_end_text is not None: self.assertContains(result, "Classes End") diff --git a/lms/djangoapps/instructor_task/tasks_helper.py b/lms/djangoapps/instructor_task/tasks_helper.py index c5a9b4d..6ee72ec 100644 --- a/lms/djangoapps/instructor_task/tasks_helper.py +++ b/lms/djangoapps/instructor_task/tasks_helper.py @@ -20,7 +20,6 @@ from dogapi import dog_stats_api from xmodule.modulestore.django import modulestore -import mitxmako.middleware as middleware from track.views import task_track from courseware.models import StudentModule @@ -35,26 +34,6 @@ TASK_LOG = get_task_logger(__name__) UNKNOWN_TASK_ID = 'unknown-task_id' -def initialize_mako(sender=None, conf=None, **kwargs): - """ - Get mako templates to work on celery worker server's worker thread. - - The initialization of Mako templating is usually done when Django is - initializing middleware packages as part of processing a server request. - When this is run on a celery worker server, no such initialization is - called. - - To make sure that we don't load this twice (just in case), we look for the - result: the defining of the lookup paths for templates. - """ - if 'main' not in middleware.lookup: - TASK_LOG.info("Initializing Mako middleware explicitly") - middleware.MakoMiddleware() - -# Actually make the call to define the hook: -worker_process_init.connect(initialize_mako) - - class UpdateProblemModuleStateError(Exception): """ Error signaling a fatal condition while updating problem modules. -- libgit2 0.26.0