From efa7b3b8167143da1bafa9d86ccc9aafb6fc4bde Mon Sep 17 00:00:00 2001
From: Jeff LaJoie <jeffrey.lajoie@gmail.com>
Date: Tue, 19 May 2020 08:23:43 -0400
Subject: [PATCH] AA-164: Performance fixes for course home

---
 lms/djangoapps/course_blocks/transformers/start_date.py  | 5 +++++
 .../course_blocks/transformers/user_partitions.py        | 9 +++++++--
 lms/djangoapps/courseware/access_utils.py                | 5 +++--
 lms/djangoapps/courseware/courses.py                     | 3 +++
 lms/templates/courseware/info.html                       | 2 +-
 5 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/lms/djangoapps/course_blocks/transformers/start_date.py b/lms/djangoapps/course_blocks/transformers/start_date.py
index 03182e8568e..900a8b74c0d 100644
--- a/lms/djangoapps/course_blocks/transformers/start_date.py
+++ b/lms/djangoapps/course_blocks/transformers/start_date.py
@@ -2,6 +2,8 @@
 Start Date Transformer implementation.
 """
 
+from datetime import datetime
+from pytz import UTC
 
 from lms.djangoapps.courseware.access_utils import check_start_date
 from openedx.core.djangoapps.content.block_structure.transformer import (
@@ -74,10 +76,13 @@ class StartDateTransformer(FilteringTransformerMixin, BlockStructureTransformer)
         if usage_info.has_staff_access or usage_info.allow_start_dates_in_future:
             return [block_structure.create_universal_filter()]
 
+        now = datetime.now(UTC)
+
         removal_condition = lambda block_key: not check_start_date(
             usage_info.user,
             block_structure.get_xblock_field(block_key, 'days_early_for_beta'),
             self._get_merged_start_date(block_structure, block_key),
             usage_info.course_key,
+            now=now,
         )
         return [block_structure.create_removal_filter(removal_condition)]
diff --git a/lms/djangoapps/course_blocks/transformers/user_partitions.py b/lms/djangoapps/course_blocks/transformers/user_partitions.py
index 529e76b154e..d25caf886eb 100644
--- a/lms/djangoapps/course_blocks/transformers/user_partitions.py
+++ b/lms/djangoapps/course_blocks/transformers/user_partitions.py
@@ -81,6 +81,11 @@ class UserPartitionTransformer(FilteringTransformerMixin, BlockStructureTransfor
     def transform_block_filters(self, usage_info, block_structure):
         user = usage_info.user
         result_list = SplitTestTransformer().transform_block_filters(usage_info, block_structure)
+        staff_access = has_access(user, 'staff', usage_info.course_key)
+
+        # If you have staff access, you are allowed access to the entire result list
+        if staff_access:
+            return result_list
 
         user_partitions = block_structure.get_transformer_data(self, 'user_partitions')
         if not user_partitions:
@@ -97,7 +102,7 @@ class UserPartitionTransformer(FilteringTransformerMixin, BlockStructureTransfor
             )
             access_denying_partition = get_partition_from_id(user_partitions, access_denying_partition_id)
 
-            if not has_access(user, 'staff', block_key) and access_denying_partition:
+            if access_denying_partition:
                 user_group = user_groups.get(access_denying_partition.id)
                 allowed_groups = transformer_block_field.get_allowed_groups()[access_denying_partition.id]
                 access_denied_message = access_denying_partition.access_denied_message(
@@ -112,7 +117,6 @@ class UserPartitionTransformer(FilteringTransformerMixin, BlockStructureTransfor
 
         group_access_filter = block_structure.create_removal_filter(
             lambda block_key: (
-                not has_access(user, 'staff', block_key) and
                 block_structure.get_transformer_block_field(
                     block_key, self, 'merged_group_access'
                 ).get_access_denying_partition(user_groups) is not None and
@@ -120,6 +124,7 @@ class UserPartitionTransformer(FilteringTransformerMixin, BlockStructureTransfor
             )
         )
         result_list.append(group_access_filter)
+
         return result_list
 
 
diff --git a/lms/djangoapps/courseware/access_utils.py b/lms/djangoapps/courseware/access_utils.py
index 43b9a2520f5..17534049eab 100644
--- a/lms/djangoapps/courseware/access_utils.py
+++ b/lms/djangoapps/courseware/access_utils.py
@@ -65,7 +65,7 @@ def adjust_start_date(user, days_early_for_beta, start, course_key):
     return start
 
 
-def check_start_date(user, days_early_for_beta, start, course_key, display_error_to_user=True):
+def check_start_date(user, days_early_for_beta, start, course_key, display_error_to_user=True, now=None):
     """
     Verifies whether the given user is allowed access given the
     start date and the Beta offset for the given course.
@@ -82,10 +82,11 @@ def check_start_date(user, days_early_for_beta, start, course_key, display_error
     if start_dates_disabled and not masquerading_as_student:
         return ACCESS_GRANTED
     else:
-        now = datetime.now(UTC)
         if start is None or in_preview_mode() or get_course_masquerade(user, course_key):
             return ACCESS_GRANTED
 
+        if now is None:
+            now = datetime.now(UTC)
         effective_start = adjust_start_date(user, days_early_for_beta, start, course_key)
         if now > effective_start:
             return ACCESS_GRANTED
diff --git a/lms/djangoapps/courseware/courses.py b/lms/djangoapps/courseware/courses.py
index 3836ed9fc10..d060ef481f6 100644
--- a/lms/djangoapps/courseware/courses.py
+++ b/lms/djangoapps/courseware/courses.py
@@ -22,6 +22,8 @@ from opaque_keys.edx.keys import UsageKey
 from path import Path as path
 from six import text_type
 
+from openedx.core.lib.cache_utils import request_cached
+
 import branding
 from course_modes.models import CourseMode
 from lms.djangoapps.courseware.access import has_access
@@ -511,6 +513,7 @@ def get_course_assignment_date_blocks(course, user, request, num_return=None,
     return date_blocks
 
 
+@request_cached()
 def get_course_assignments(course_key, user, request, include_access=False):
     """
     Returns a list of assignment (at the subsection/sequential level) due dates for the given course.
diff --git a/lms/templates/courseware/info.html b/lms/templates/courseware/info.html
index 4fea8989a9c..022ef48669c 100644
--- a/lms/templates/courseware/info.html
+++ b/lms/templates/courseware/info.html
@@ -9,7 +9,7 @@ from pytz import timezone, utc
 from django.urls import reverse
 from django.utils.translation import ugettext as _
 
-from lms.djangoapps.courseware.courses import get_course_info_section, get_course_date_blocks
+from lms.djangoapps.courseware.courses import get_course_info_section
 from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
 from openedx.core.djangolib.markup import HTML, Text
 %>
-- 
GitLab