<commit_before>"""
Courseware views functions
"""

import json
import logging
import urllib
from collections import OrderedDict
from datetime import datetime

import analytics
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User, AnonymousUser
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
from django.core.context_processors import csrf
from django.db import transaction, connection
from django.db.models import Q, F
from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponseForbidden
from django.shortcuts import redirect
from django.utils.decorators import method_decorator
from django.utils.timezone import UTC
from django.utils.translation import ugettext as _
from django.views.decorators.cache import cache_control
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_GET, require_POST, require_http_methods
from django.views.generic import View
from eventtracking import tracker
from ipware.ip import get_ip
from markupsafe import escape
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey, UsageKey
from opaque_keys.edx.locations import SlashSeparatedCourseKey
from rest_framework import status
from instructor.views.api import require_global_staff

import shoppingcart
import survey.utils
import survey.views
from lms.djangoapps.ccx.utils import prep_course_for_grading
from certificates import api as certs_api
from course_blocks.api import get_course_blocks
from openedx.core.djangoapps.models.course_details import CourseDetails
from commerce.utils import EcommerceService
from enrollment.api import add_enrollment
from course_modes.models import CourseMode
from courseware import grades
from courseware.access import has_access, has_ccx_coach_role, _adjust_start_date_for_beta_testers
from courseware.access_response import StartDateError
from courseware.access_utils import in_preview_mode
from courseware.courses import (
    get_courses,
    get_course,
    get_course_by_id,
    get_permission_for_course_about,
    get_studio_url,
    get_course_overview_with_access,
    get_course_with_access,
    sort_by_announcement,
    sort_by_start_date,
    UserNotEnrolled
)
from courseware.masquerade import setup_masquerade
from courseware.model_data import FieldDataCache, ScoresClient
from courseware.models import StudentModule, BaseStudentModuleHistory
from courseware.url_helpers import get_redirect_url, get_redirect_url_for_global_staff
from courseware.user_state_client import DjangoXBlockUserStateClient
from edxmako.shortcuts import render_to_response, render_to_string, marketing_link
from instructor.enrollment import uses_shib
from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.coursetalk.helpers import inject_coursetalk_keys_into_context
from openedx.core.djangoapps.credit.api import (
    get_credit_requirement_status,
    is_user_eligible_for_credit,
    is_credit_course
)
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from shoppingcart.utils import is_shopping_cart_enabled
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
from student.models import UserTestGroup, CourseEnrollment
from student.roles import GlobalStaff
from util.cache import cache, cache_if_anonymous
from util.date_utils import strftime_localized
from util.db import outer_atomic
from util.milestones_helpers import get_prerequisite_courses_display
from util.views import _record_feedback_in_zendesk
from util.views import ensure_valid_course_key
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError, NoPathToItem
from xmodule.tabs import CourseTabList
from xmodule.x_module import STUDENT_VIEW
from lms.djangoapps.ccx.custom_exception import CCXLocatorValidationException
from ..entrance_exams import user_must_complete_entrance_exam
from ..module_render import get_module_for_descriptor, get_module, get_module_by_usage_id
from lms.djangoapps.ccx.models import CustomCourseForEdX
from openedx.core.djangoapps.bookmarks.models import Bookmark
from search.api import perform_search
from ccx.views import get_ccx_schedule
from openedx.core.lib.xblock_utils import get_course_update_items
from lms.envs.common import STATE_CHOICES
from ccx_keys.locator import CCXLocator


log = logging.getLogger("edx.courseware")


# Only display the requirements on learner dashboard for
# credit and verified modes.
REQUIREMENTS_DISPLAY_MODES = CourseMode.CREDIT_MODES + [CourseMode.VERIFIED]


def user_groups(user):
    """
    TODO (vshnayder): This is not used. When we have a new plan for groups, adjust appropriately.
    """
    if not user.is_authenticated():
        return []

    # TODO: Rewrite in Django
    key = 'user_group_names_{user.id}'.format(user=user)
    cache_expiration = 60 * 60  # one hour

    # Kill caching on dev machines -- we switch groups a lot
    group_names = cache.get(key)  # pylint: disable=no-member
    if settings.DEBUG:
        group_names = None

    if group_names is None:
        group_names = [u.name for u in UserTestGroup.objects.filter(users=user)]
        cache.set(key, group_names, cache_expiration)  # pylint: disable=no-member

    return group_names


@ensure_csrf_cookie
def courses(request):
    """
    Render "find courses" page.
    """
    ccx_filters = build_ccx_filters(request)
    ccxs = CustomCourseForEdX.objects.filter(**ccx_filters)
    ccx_keys = []

    for ccx in ccxs:
        ccx_course_id = unicode(CCXLocator.from_course_locator(ccx.course.id, ccx.id))
        ccx_course_key = CourseKey.from_string(ccx_course_id)
        ccx_keys.append(ccx_course_key)

    should_hide_master_course = get_should_hide_master_course(request)

    if should_hide_master_course:
        courses = CourseOverview.objects.filter(id__in=ccx_keys)
    else:
        courses = CourseOverview.objects.filter(Q(id__in=ccx_keys) | ~Q(id__startswith='ccx')).filter(invitation_only=0)

    return render_to_response(
        "courseware/courses.html",
        {
            'courses': courses,
            'affiliates': set([c.coach for c in ccxs]),
            'state_choices': STATE_CHOICES,
            'delivery_mode_choices': CustomCourseForEdX.DELIVERY_MODE_CHOICES,
            'filter_states': ccx_filters,
            'date_from': request.POST.get('date_from', ''),
            'date_to': request.POST.get('date_to', '')
        }
    )

def get_should_hide_master_course(request):
    location_city = request.POST.get('location_city')
    location_state = request.POST.get('location_state')
    delivery_mode = request.POST.get('delivery_mode')
    coach_id = request.POST.get('coach_id')

    # the master course needs to be hidden if
    # city isn't Kansas, state isn't Missouri
    # delivery_mode isn't Online
    # or we selected a coach

    return ((location_city and not location_city.startswith('Kansas'))
        or (location_state and location_state != 'MO')
        or (delivery_mode and delivery_mode != CustomCourseForEdX.ONLINE_ONLY)
        or coach_id)


def build_ccx_filters(request):
    filter_fields = ['location_city', 'location_state', 'delivery_mode', 'coach_id']
    filters = {
        'id': F('original_ccx_id'),
        'enrollment_type': CustomCourseForEdX.PUBLIC
    }

    for field in filter_fields:
        value = request.POST.get(field)
        if value:
            filters[field] = value

    date_from = request.POST.get('date_from')
    date_to = request.POST.get('date_to')

    if date_from:
        filters['time__gte'] = datetime.strptime(date_from, '%m/%d/%Y')<commit_msg>update ccx filters to take user into account (#255)<commit_after>"""
Courseware views functions
"""

import json
import logging
import urllib
from collections import OrderedDict
from datetime import datetime

import analytics
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User, AnonymousUser
from django.core.exceptions import PermissionDenied
from django.core.urlresolvers import reverse
from django.core.context_processors import csrf
from django.db import transaction, connection
from django.db.models import Q, F
from django.http import Http404, HttpResponse, HttpResponseBadRequest, HttpResponseForbidden
from django.shortcuts import redirect
from django.utils.decorators import method_decorator
from django.utils.timezone import UTC
from django.utils.translation import ugettext as _
from django.views.decorators.cache import cache_control
from django.views.decorators.csrf import ensure_csrf_cookie
from django.views.decorators.http import require_GET, require_POST, require_http_methods
from django.views.generic import View
from eventtracking import tracker
from ipware.ip import get_ip
from markupsafe import escape
from opaque_keys import InvalidKeyError
from opaque_keys.edx.keys import CourseKey, UsageKey
from opaque_keys.edx.locations import SlashSeparatedCourseKey
from rest_framework import status
from instructor.views.api import require_global_staff

import shoppingcart
import survey.utils
import survey.views
from lms.djangoapps.ccx.utils import prep_course_for_grading
from certificates import api as certs_api
from course_blocks.api import get_course_blocks
from openedx.core.djangoapps.models.course_details import CourseDetails
from commerce.utils import EcommerceService
from enrollment.api import add_enrollment
from course_modes.models import CourseMode
from courseware import grades
from courseware.access import has_access, has_ccx_coach_role, _adjust_start_date_for_beta_testers
from courseware.access_response import StartDateError
from courseware.access_utils import in_preview_mode
from courseware.courses import (
    get_courses,
    get_course,
    get_course_by_id,
    get_permission_for_course_about,
    get_studio_url,
    get_course_overview_with_access,
    get_course_with_access,
    sort_by_announcement,
    sort_by_start_date,
    UserNotEnrolled
)
from courseware.masquerade import setup_masquerade
from courseware.model_data import FieldDataCache, ScoresClient
from courseware.models import StudentModule, BaseStudentModuleHistory
from courseware.url_helpers import get_redirect_url, get_redirect_url_for_global_staff
from courseware.user_state_client import DjangoXBlockUserStateClient
from edxmako.shortcuts import render_to_response, render_to_string, marketing_link
from instructor.enrollment import uses_shib
from lms.djangoapps.verify_student.models import SoftwareSecurePhotoVerification
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
from openedx.core.djangoapps.coursetalk.helpers import inject_coursetalk_keys_into_context
from openedx.core.djangoapps.credit.api import (
    get_credit_requirement_status,
    is_user_eligible_for_credit,
    is_credit_course
)
from openedx.core.djangoapps.site_configuration import helpers as configuration_helpers
from shoppingcart.utils import is_shopping_cart_enabled
from openedx.core.djangoapps.self_paced.models import SelfPacedConfiguration
from student.models import UserTestGroup, CourseEnrollment
from student.roles import GlobalStaff
from util.cache import cache, cache_if_anonymous
from util.date_utils import strftime_localized
from util.db import outer_atomic
from util.milestones_helpers import get_prerequisite_courses_display
from util.views import _record_feedback_in_zendesk
from util.views import ensure_valid_course_key
from xmodule.modulestore.django import modulestore
from xmodule.modulestore.exceptions import ItemNotFoundError, NoPathToItem
from xmodule.tabs import CourseTabList
from xmodule.x_module import STUDENT_VIEW
from lms.djangoapps.ccx.custom_exception import CCXLocatorValidationException
from ..entrance_exams import user_must_complete_entrance_exam
from ..module_render import get_module_for_descriptor, get_module, get_module_by_usage_id
from lms.djangoapps.ccx.models import CustomCourseForEdX
from openedx.core.djangoapps.bookmarks.models import Bookmark
from search.api import perform_search
from ccx.views import get_ccx_schedule
from openedx.core.lib.xblock_utils import get_course_update_items
from lms.envs.common import STATE_CHOICES
from ccx_keys.locator import CCXLocator


log = logging.getLogger("edx.courseware")


# Only display the requirements on learner dashboard for
# credit and verified modes.
REQUIREMENTS_DISPLAY_MODES = CourseMode.CREDIT_MODES + [CourseMode.VERIFIED]


def user_groups(user):
    """
    TODO (vshnayder): This is not used. When we have a new plan for groups, adjust appropriately.
    """
    if not user.is_authenticated():
        return []

    # TODO: Rewrite in Django
    key = 'user_group_names_{user.id}'.format(user=user)
    cache_expiration = 60 * 60  # one hour

    # Kill caching on dev machines -- we switch groups a lot
    group_names = cache.get(key)  # pylint: disable=no-member
    if settings.DEBUG:
        group_names = None

    if group_names is None:
        group_names = [u.name for u in UserTestGroup.objects.filter(users=user)]
        cache.set(key, group_names, cache_expiration)  # pylint: disable=no-member

    return group_names


@ensure_csrf_cookie
def courses(request):
    """
    Render "find courses" page.
    """
    ccx_filters = build_ccx_filters(request)
    ccxs = CustomCourseForEdX.objects.filter(**ccx_filters)
    ccx_keys = []

    for ccx in ccxs:
        ccx_course_id = unicode(CCXLocator.from_course_locator(ccx.course.id, ccx.id))
        ccx_course_key = CourseKey.from_string(ccx_course_id)
        ccx_keys.append(ccx_course_key)

    should_hide_master_course = get_should_hide_master_course(request)

    if should_hide_master_course:
        courses = CourseOverview.objects.filter(id__in=ccx_keys)
    else:
        courses = CourseOverview.objects.filter(Q(id__in=ccx_keys) | ~Q(id__startswith='ccx')).filter(invitation_only=0)

    return render_to_response(
        "courseware/courses.html",
        {
            'courses': courses,
            'affiliates': set([c.coach for c in ccxs]),
            'state_choices': STATE_CHOICES,
            'delivery_mode_choices': CustomCourseForEdX.DELIVERY_MODE_CHOICES,
            'filter_states': ccx_filters,
            'date_from': request.POST.get('date_from', ''),
            'date_to': request.POST.get('date_to', '')
        }
    )

def get_should_hide_master_course(request):
    location_city = request.POST.get('location_city')
    location_state = request.POST.get('location_state')
    delivery_mode = request.POST.get('delivery_mode')
    coach_id = request.POST.get('coach_id')

    # the master course needs to be hidden if
    # city isn't Kansas, state isn't Missouri
    # delivery_mode isn't Online
    # or we selected a coach

    return ((location_city and not location_city.startswith('Kansas'))
        or (location_state and location_state != 'MO')
        or (delivery_mode and delivery_mode != CustomCourseForEdX.ONLINE_ONLY)
        or coach_id)


def build_ccx_filters(request):
    filter_fields = ['location_city', 'location_state', 'delivery_mode', 'coach_id']
    filters = {
        'id': F('original_ccx_id')
    }

    if not request.user.is_staff:
        filters['enrollment_type'] = CustomCourseForEdX.PUBLIC

    for field in filter_fields:
        value = request.POST.get(field)
        if value:
            filters[field] = value

    date_from = request.POST.get('date_from')
    date_to = request.POST.get('date_to')

    if date_from:
        filters['time__gte'] = datetime.strptime(date_from, '%m/%d/%Y')
{'fraction_non_alphanumeric': 0.06630078223568003, 'fraction_numerical': 0.0011985869290941206, 'mean_word_length': 4.959774436090226, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2353070', 'n_tokens_mistral': 4828, 'n_tokens_neox': 4680, 'n_words': 1156}