prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Coach Reports - change when progress starts being measured in coach reports
  ## Summary
  
  Implementations team members were confused as to why some exercises were showing up as having progress in Recent but there ended up being no data for it when they clicked into it.
  
  **Suggestion:** 
  On coach reports, log that an exercise has been engaged with only when the learner clicked "check answer". 
  
  That way, we avoid having exercises display on the coach's end because of learners who happen to click into an exercise and leave the page without interacting with the exercise.
  
  A potential problem area in the future is overloading the Recent tab with content that has 0 data because of learners who like to click around & explore. 
  
  ## System information
  
   - Version: Kolibri 0.4.0alpha6 http://192.237.248.135:8088/
   - Operating system: Mac
   - Browser: Chrome
  
  ## Screenshots
  
  ![apr-27-2017 16-46-51](https://cloud.githubusercontent.com/assets/6668144/25508810/7782926e-2b69-11e7-90b5-5ebc6dc3543b.gif)
  
  Exercises should log as "in progress" as soon as there's an interaction with it
  ## Summary
  
  Marking incorrect answers and getting hints does not log it as "in progress"
  The first correct answer on an exercise logs it as "in progress"
  
  ## System information
  
   - Version: Kolibri 0.4.0alpha1.dev915
   - Operating system: MacOS Sierra
   - Browser: Chrome
  
  ![apr-27-2017 18-03-18](https://cloud.githubusercontent.com/assets/6668144/25510591/234e5e28-2b76-11e7-966a-3ea42938845b.gif)
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `kolibri/plugins/coach/api.py`
  Content:
  ```
  1 import datetime
  2 from dateutil.parser import parse
  3 
  4 from django.utils import timezone
  5 
  6 from kolibri.auth.constants import role_kinds
  7 from kolibri.auth.models import Collection, FacilityUser
  8 from kolibri.content.models import ContentNode
  9 from kolibri.logger.models import ContentSummaryLog
  10 from rest_framework import pagination, permissions, viewsets
  11 
  12 from .serializers import ContentReportSerializer, ContentSummarySerializer, UserReportSerializer
  13 from .utils.return_users import get_members_or_user
  14 
  15 
  16 class OptionalPageNumberPagination(pagination.PageNumberPagination):
  17     """
  18     Pagination class that allows for page number-style pagination, when requested.
  19     To activate, the `page_size` argument must be set. For example, to request the first 20 records:
  20     `?page_size=20&page=1`
  21     """
  22     page_size = None
  23     page_size_query_param = "page_size"
  24 
  25 
  26 class KolibriReportPermissions(permissions.BasePermission):
  27 
  28     # check if requesting user has permission for collection or user
  29     def has_permission(self, request, view):
  30         collection_kind = view.kwargs.get('collection_kind', 'user')
  31         collection_or_user_pk = view.kwargs.get('collection_id', view.kwargs.get('pk'))
  32 
  33         allowed_roles = [role_kinds.ADMIN, role_kinds.COACH]
  34         if 'user' == collection_kind:
  35             return request.user.has_role_for(allowed_roles, FacilityUser.objects.get(pk=collection_or_user_pk))
  36         else:
  37             return request.user.has_role_for(allowed_roles, Collection.objects.get(pk=collection_or_user_pk))
  38 
  39 
  40 class UserReportViewSet(viewsets.ModelViewSet):
  41 
  42     permission_classes = (KolibriReportPermissions,)
  43     pagination_class = OptionalPageNumberPagination
  44     serializer_class = UserReportSerializer
  45 
  46     def get_queryset(self):
  47         assert 'user' != self.kwargs['collection_kind'], 'only a `collection` should be passed to this endpoint'
  48         return get_members_or_user(self.kwargs['collection_kind'], self.kwargs['collection_id'])
  49 
  50 
  51 class ContentReportViewSet(viewsets.ModelViewSet):
  52 
  53     permission_classes = (KolibriReportPermissions,)
  54     pagination_class = OptionalPageNumberPagination
  55     serializer_class = ContentReportSerializer
  56 
  57     def get_queryset(self):
  58         content_node_id = self.kwargs['content_node_id']
  59         return ContentNode.objects.filter(parent=content_node_id)
  60 
  61 
  62 class ContentSummaryViewSet(viewsets.ModelViewSet):
  63 
  64     permission_classes = (KolibriReportPermissions,)
  65     serializer_class = ContentSummarySerializer
  66 
  67     def get_queryset(self):
  68         return ContentNode.objects.all()
  69 
  70 
  71 class UserSummaryViewSet(viewsets.ModelViewSet):
  72 
  73     permission_classes = (KolibriReportPermissions,)
  74     serializer_class = UserReportSerializer
  75 
  76     def get_queryset(self):
  77         return FacilityUser.objects.all()
  78 
  79 
  80 class RecentReportViewSet(viewsets.ModelViewSet):
  81 
  82     permission_classes = (KolibriReportPermissions,)
  83     pagination_class = OptionalPageNumberPagination
  84     serializer_class = ContentReportSerializer
  85 
  86     def get_queryset(self):
  87         query_node = ContentNode.objects.get(pk=self.kwargs['content_node_id'])
  88         if self.request.query_params.get('last_active_time'):
  89             # Last active time specified
  90             datetime_cutoff = parse(self.request.query_params.get('last_active_time'))
  91         else:
  92             datetime_cutoff = timezone.now() - datetime.timedelta(7)
  93         # Set on the kwargs to pass into the serializer
  94         self.kwargs['last_active_time'] = datetime_cutoff.isoformat()
  95         recent_content_items = ContentSummaryLog.objects.filter_by_topic(query_node).filter(
  96             user__in=get_members_or_user(self.kwargs['collection_kind'], self.kwargs['collection_id']),
  97             end_timestamp__gte=datetime_cutoff).values_list('content_id')
  98         return ContentNode.objects.filter(content_id__in=recent_content_items)
  99
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/kolibri/plugins/coach/api.py b/kolibri/plugins/coach/api.py
  --- a/kolibri/plugins/coach/api.py
  +++ b/kolibri/plugins/coach/api.py
  @@ -1,12 +1,13 @@
   import datetime
   from dateutil.parser import parse
   
  +from django.db.models import Q
   from django.utils import timezone
   
   from kolibri.auth.constants import role_kinds
   from kolibri.auth.models import Collection, FacilityUser
   from kolibri.content.models import ContentNode
  -from kolibri.logger.models import ContentSummaryLog
  +from kolibri.logger.models import ContentSummaryLog, MasteryLog
   from rest_framework import pagination, permissions, viewsets
   
   from .serializers import ContentReportSerializer, ContentSummarySerializer, UserReportSerializer
  @@ -84,6 +85,7 @@
       serializer_class = ContentReportSerializer
   
       def get_queryset(self):
  +        attempted_mastery_logs = MasteryLog.objects.filter(attemptlogs__isnull=False)
           query_node = ContentNode.objects.get(pk=self.kwargs['content_node_id'])
           if self.request.query_params.get('last_active_time'):
               # Last active time specified
  @@ -93,6 +95,7 @@
           # Set on the kwargs to pass into the serializer
           self.kwargs['last_active_time'] = datetime_cutoff.isoformat()
           recent_content_items = ContentSummaryLog.objects.filter_by_topic(query_node).filter(
  +            Q(progress__gt=0) | Q(masterylogs__in=attempted_mastery_logs),
               user__in=get_members_or_user(self.kwargs['collection_kind'], self.kwargs['collection_id']),
               end_timestamp__gte=datetime_cutoff).values_list('content_id')
           return ContentNode.objects.filter(content_id__in=recent_content_items)
  
verification_info: {"golden_diff": "diff --git a/kolibri/plugins/coach/api.py b/kolibri/plugins/coach/api.py\n--- a/kolibri/plugins/coach/api.py\n+++ b/kolibri/plugins/coach/api.py\n@@ -1,12 +1,13 @@\n import datetime\n from dateutil.parser import parse\n \n+from django.db.models import Q\n from django.utils import timezone\n \n from kolibri.auth.constants import role_kinds\n from kolibri.auth.models import Collection, FacilityUser\n from kolibri.content.models import ContentNode\n-from kolibri.logger.models import ContentSummaryLog\n+from kolibri.logger.models import ContentSummaryLog, MasteryLog\n from rest_framework import pagination, permissions, viewsets\n \n from .serializers import ContentReportSerializer, ContentSummarySerializer, UserReportSerializer\n@@ -84,6 +85,7 @@\n     serializer_class = ContentReportSerializer\n \n     def get_queryset(self):\n+        attempted_mastery_logs = MasteryLog.objects.filter(attemptlogs__isnull=False)\n         query_node = ContentNode.objects.get(pk=self.kwargs['content_node_id'])\n         if self.request.query_params.get('last_active_time'):\n             # Last active time specified\n@@ -93,6 +95,7 @@\n         # Set on the kwargs to pass into the serializer\n         self.kwargs['last_active_time'] = datetime_cutoff.isoformat()\n         recent_content_items = ContentSummaryLog.objects.filter_by_topic(query_node).filter(\n+            Q(progress__gt=0) | Q(masterylogs__in=attempted_mastery_logs),\n             user__in=get_members_or_user(self.kwargs['collection_kind'], self.kwargs['collection_id']),\n             end_timestamp__gte=datetime_cutoff).values_list('content_id')\n         return ContentNode.objects.filter(content_id__in=recent_content_items)\n", "issue": "Coach Reports - change when progress starts being measured in coach reports\n## Summary\r\n\r\nImplementations team members were confused as to why some exercises were showing up as having progress in Recent but there ended up being no data for it when they clicked into it.\r\n\r\n**Suggestion:** \r\nOn coach reports, log that an exercise has been engaged with only when the learner clicked \"check answer\". \r\n\r\nThat way, we avoid having exercises display on the coach's end because of learners who happen to click into an exercise and leave the page without interacting with the exercise.\r\n\r\nA potential problem area in the future is overloading the Recent tab with content that has 0 data because of learners who like to click around & explore. \r\n\r\n## System information\r\n\r\n - Version: Kolibri 0.4.0alpha6 http://192.237.248.135:8088/\r\n - Operating system: Mac\r\n - Browser: Chrome\r\n\r\n## Screenshots\r\n\r\n![apr-27-2017 16-46-51](https://cloud.githubusercontent.com/assets/6668144/25508810/7782926e-2b69-11e7-90b5-5ebc6dc3543b.gif)\r\n\nExercises should log as \"in progress\" as soon as there's an interaction with it\n## Summary\r\n\r\nMarking incorrect answers and getting hints does not log it as \"in progress\"\r\nThe first correct answer on an exercise logs it as \"in progress\"\r\n\r\n## System information\r\n\r\n - Version: Kolibri 0.4.0alpha1.dev915\r\n - Operating system: MacOS Sierra\r\n - Browser: Chrome\r\n\r\n![apr-27-2017 18-03-18](https://cloud.githubusercontent.com/assets/6668144/25510591/234e5e28-2b76-11e7-966a-3ea42938845b.gif)\r\n\n", "before_files": [{"content": "import datetime\nfrom dateutil.parser import parse\n\nfrom django.utils import timezone\n\nfrom kolibri.auth.constants import role_kinds\nfrom kolibri.auth.models import Collection, FacilityUser\nfrom kolibri.content.models import ContentNode\nfrom kolibri.logger.models import ContentSummaryLog\nfrom rest_framework import pagination, permissions, viewsets\n\nfrom .serializers import ContentReportSerializer, ContentSummarySerializer, UserReportSerializer\nfrom .utils.return_users import get_members_or_user\n\n\nclass OptionalPageNumberPagination(pagination.PageNumberPagination):\n    \"\"\"\n    Pagination class that allows for page number-style pagination, when requested.\n    To activate, the `page_size` argument must be set. For example, to request the first 20 records:\n    `?page_size=20&page=1`\n    \"\"\"\n    page_size = None\n    page_size_query_param = \"page_size\"\n\n\nclass KolibriReportPermissions(permissions.BasePermission):\n\n    # check if requesting user has permission for collection or user\n    def has_permission(self, request, view):\n        collection_kind = view.kwargs.get('collection_kind', 'user')\n        collection_or_user_pk = view.kwargs.get('collection_id', view.kwargs.get('pk'))\n\n        allowed_roles = [role_kinds.ADMIN, role_kinds.COACH]\n        if 'user' == collection_kind:\n            return request.user.has_role_for(allowed_roles, FacilityUser.objects.get(pk=collection_or_user_pk))\n        else:\n            return request.user.has_role_for(allowed_roles, Collection.objects.get(pk=collection_or_user_pk))\n\n\nclass UserReportViewSet(viewsets.ModelViewSet):\n\n    permission_classes = (KolibriReportPermissions,)\n    pagination_class = OptionalPageNumberPagination\n    serializer_class = UserReportSerializer\n\n    def get_queryset(self):\n        assert 'user' != self.kwargs['collection_kind'], 'only a `collection` should be passed to this endpoint'\n        return get_members_or_user(self.kwargs['collection_kind'], self.kwargs['collection_id'])\n\n\nclass ContentReportViewSet(viewsets.ModelViewSet):\n\n    permission_classes = (KolibriReportPermissions,)\n    pagination_class = OptionalPageNumberPagination\n    serializer_class = ContentReportSerializer\n\n    def get_queryset(self):\n        content_node_id = self.kwargs['content_node_id']\n        return ContentNode.objects.filter(parent=content_node_id)\n\n\nclass ContentSummaryViewSet(viewsets.ModelViewSet):\n\n    permission_classes = (KolibriReportPermissions,)\n    serializer_class = ContentSummarySerializer\n\n    def get_queryset(self):\n        return ContentNode.objects.all()\n\n\nclass UserSummaryViewSet(viewsets.ModelViewSet):\n\n    permission_classes = (KolibriReportPermissions,)\n    serializer_class = UserReportSerializer\n\n    def get_queryset(self):\n        return FacilityUser.objects.all()\n\n\nclass RecentReportViewSet(viewsets.ModelViewSet):\n\n    permission_classes = (KolibriReportPermissions,)\n    pagination_class = OptionalPageNumberPagination\n    serializer_class = ContentReportSerializer\n\n    def get_queryset(self):\n        query_node = ContentNode.objects.get(pk=self.kwargs['content_node_id'])\n        if self.request.query_params.get('last_active_time'):\n            # Last active time specified\n            datetime_cutoff = parse(self.request.query_params.get('last_active_time'))\n        else:\n            datetime_cutoff = timezone.now() - datetime.timedelta(7)\n        # Set on the kwargs to pass into the serializer\n        self.kwargs['last_active_time'] = datetime_cutoff.isoformat()\n        recent_content_items = ContentSummaryLog.objects.filter_by_topic(query_node).filter(\n            user__in=get_members_or_user(self.kwargs['collection_kind'], self.kwargs['collection_id']),\n            end_timestamp__gte=datetime_cutoff).values_list('content_id')\n        return ContentNode.objects.filter(content_id__in=recent_content_items)\n", "path": "kolibri/plugins/coach/api.py"}], "after_files": [{"content": "import datetime\nfrom dateutil.parser import parse\n\nfrom django.db.models import Q\nfrom django.utils import timezone\n\nfrom kolibri.auth.constants import role_kinds\nfrom kolibri.auth.models import Collection, FacilityUser\nfrom kolibri.content.models import ContentNode\nfrom kolibri.logger.models import ContentSummaryLog, MasteryLog\nfrom rest_framework import pagination, permissions, viewsets\n\nfrom .serializers import ContentReportSerializer, ContentSummarySerializer, UserReportSerializer\nfrom .utils.return_users import get_members_or_user\n\n\nclass OptionalPageNumberPagination(pagination.PageNumberPagination):\n    \"\"\"\n    Pagination class that allows for page number-style pagination, when requested.\n    To activate, the `page_size` argument must be set. For example, to request the first 20 records:\n    `?page_size=20&page=1`\n    \"\"\"\n    page_size = None\n    page_size_query_param = \"page_size\"\n\n\nclass KolibriReportPermissions(permissions.BasePermission):\n\n    # check if requesting user has permission for collection or user\n    def has_permission(self, request, view):\n        collection_kind = view.kwargs.get('collection_kind', 'user')\n        collection_or_user_pk = view.kwargs.get('collection_id', view.kwargs.get('pk'))\n\n        allowed_roles = [role_kinds.ADMIN, role_kinds.COACH]\n        if 'user' == collection_kind:\n            return request.user.has_role_for(allowed_roles, FacilityUser.objects.get(pk=collection_or_user_pk))\n        else:\n            return request.user.has_role_for(allowed_roles, Collection.objects.get(pk=collection_or_user_pk))\n\n\nclass UserReportViewSet(viewsets.ModelViewSet):\n\n    permission_classes = (KolibriReportPermissions,)\n    pagination_class = OptionalPageNumberPagination\n    serializer_class = UserReportSerializer\n\n    def get_queryset(self):\n        assert 'user' != self.kwargs['collection_kind'], 'only a `collection` should be passed to this endpoint'\n        return get_members_or_user(self.kwargs['collection_kind'], self.kwargs['collection_id'])\n\n\nclass ContentReportViewSet(viewsets.ModelViewSet):\n\n    permission_classes = (KolibriReportPermissions,)\n    pagination_class = OptionalPageNumberPagination\n    serializer_class = ContentReportSerializer\n\n    def get_queryset(self):\n        content_node_id = self.kwargs['content_node_id']\n        return ContentNode.objects.filter(parent=content_node_id)\n\n\nclass ContentSummaryViewSet(viewsets.ModelViewSet):\n\n    permission_classes = (KolibriReportPermissions,)\n    serializer_class = ContentSummarySerializer\n\n    def get_queryset(self):\n        return ContentNode.objects.all()\n\n\nclass UserSummaryViewSet(viewsets.ModelViewSet):\n\n    permission_classes = (KolibriReportPermissions,)\n    serializer_class = UserReportSerializer\n\n    def get_queryset(self):\n        return FacilityUser.objects.all()\n\n\nclass RecentReportViewSet(viewsets.ModelViewSet):\n\n    permission_classes = (KolibriReportPermissions,)\n    pagination_class = OptionalPageNumberPagination\n    serializer_class = ContentReportSerializer\n\n    def get_queryset(self):\n        attempted_mastery_logs = MasteryLog.objects.filter(attemptlogs__isnull=False)\n        query_node = ContentNode.objects.get(pk=self.kwargs['content_node_id'])\n        if self.request.query_params.get('last_active_time'):\n            # Last active time specified\n            datetime_cutoff = parse(self.request.query_params.get('last_active_time'))\n        else:\n            datetime_cutoff = timezone.now() - datetime.timedelta(7)\n        # Set on the kwargs to pass into the serializer\n        self.kwargs['last_active_time'] = datetime_cutoff.isoformat()\n        recent_content_items = ContentSummaryLog.objects.filter_by_topic(query_node).filter(\n            Q(progress__gt=0) | Q(masterylogs__in=attempted_mastery_logs),\n            user__in=get_members_or_user(self.kwargs['collection_kind'], self.kwargs['collection_id']),\n            end_timestamp__gte=datetime_cutoff).values_list('content_id')\n        return ContentNode.objects.filter(content_id__in=recent_content_items)\n", "path": "kolibri/plugins/coach/api.py"}]}