示例#1
0
    def get_queryset(self):
        """ List one course run
        ---
        parameters:
            - name: include_deleted_programs
              description: Will include deleted programs in the associated programs array
              required: false
              type: integer
              paramType: query
              multiple: false
        """
        q = self.request.query_params.get('q')
        partner = self.request.site.partner
        edit_mode = get_query_param(self.request, 'editable') or self.request.method not in SAFE_METHODS

        if edit_mode and q:
            raise EditableAndQUnsupported()

        if edit_mode:
            queryset = CourseRun.objects.filter_drafts()
            queryset = CourseEditor.editable_course_runs(self.request.user, queryset)
        else:
            queryset = self.queryset

        if q:
            queryset = CourseRun.search(q, queryset=queryset)

        queryset = queryset.filter(course__partner=partner)
        return self.get_serializer_class().prefetch_queryset(queryset=queryset)
示例#2
0
    def get_queryset(self):
        """ List one course run
        ---
        parameters:
            - name: include_deleted_programs
              description: Will include deleted programs in the associated programs array
              required: false
              type: integer
              paramType: query
              multiple: false
        """
        q = self.request.query_params.get('q')
        partner = self.request.site.partner
        edit_mode = get_query_param(self.request, 'editable') or self.request.method not in SAFE_METHODS

        if edit_mode and q:
            raise EditableAndQUnsupported()

        if edit_mode and (not self.request.user.is_staff and not is_publisher_user(self.request.user)):
            raise PermissionDenied

        if edit_mode:
            queryset = CourseRun.objects.filter_drafts()
            queryset = CourseEditor.editable_course_runs(self.request.user, queryset)
        else:
            queryset = self.queryset

        if q:
            qs = SearchQuerySetWrapper(CourseRun.search(q).filter(partner=partner.short_code))
            # This is necessary to avoid issues with the filter backend.
            qs.model = self.queryset.model
            return qs

        queryset = queryset.filter(course__partner=partner)
        return self.get_serializer_class().prefetch_queryset(queryset=queryset)
示例#3
0
    def create(self, request):
        comment_creation_fields = {
            'course_uuid': request.data.get('course_uuid'),
            'comment': request.data.get('comment'),
        }

        missing_values = [k for k, v in comment_creation_fields.items() if v is None]
        error_message = ''
        if missing_values:
            error_message += ''.join([_('Missing value for: [{name}]. ').format(name=name) for name in missing_values])
        if error_message:
            return Response((_('Incorrect data sent. ') + error_message).strip(), status=status.HTTP_400_BAD_REQUEST)

        partner = self.request.site.partner
        course = self._get_course_or_404(partner, comment_creation_fields.get('course_uuid'))

        if not CourseEditor.is_course_editable(request.user, course):
            raise PermissionDenied

        util = self._get_salesforce_util_or_404(partner)
        try:
            comment = util.create_comment_for_course_case(
                course,
                request.user,
                comment_creation_fields.get('comment'),
                course_run_key=request.data.get('course_run_key')
            )
            send_email_for_comment(comment, course, request.user)
            return Response(comment, status=status.HTTP_201_CREATED)
        except SalesforceMissingCaseException as ex:
            return Response(ex.message, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
示例#4
0
    def get_queryset(self):
        partner = self.request.site.partner
        q = self.request.query_params.get('q')
        # We don't want to create an additional elasticsearch index right now for draft courses, so we
        # try to implement a basic search behavior with this pubq parameter here against key and name.
        pub_q = self.request.query_params.get('pubq')
        edit_method = self.request.method not in SAFE_METHODS
        edit_mode = get_query_param(self.request, 'editable') or edit_method

        if edit_mode and q:
            raise EditableAndQUnsupported()

        if edit_mode and (not self.request.user.is_staff and not is_publisher_user(self.request.user)):
            raise PermissionDenied

        if edit_mode:
            # Start with either draft versions or real versions of the courses
            queryset = Course.objects.filter_drafts()
            queryset = CourseEditor.editable_courses(self.request.user, queryset, check_editors=edit_method)
        else:
            queryset = self.queryset

        if q:
            queryset = Course.search(q, queryset=queryset)
            queryset = self.get_serializer_class().prefetch_queryset(queryset=queryset, partner=partner)
        else:
            if edit_mode:
                course_runs = CourseRun.objects.filter_drafts(course__partner=partner)
            else:
                course_runs = CourseRun.objects.filter(course__partner=partner)

            if not get_query_param(self.request, 'include_hidden_course_runs'):
                course_runs = course_runs.exclude(hidden=True)

            if get_query_param(self.request, 'marketable_course_runs_only'):
                course_runs = course_runs.marketable().active()

            if get_query_param(self.request, 'marketable_enrollable_course_runs_with_archived'):
                course_runs = course_runs.marketable().enrollable()

            if get_query_param(self.request, 'published_course_runs_only'):
                course_runs = course_runs.filter(status=CourseRunStatus.Published)

            if get_query_param(self.request, 'include_deleted_programs'):
                programs = Program.objects.all()
            else:
                programs = Program.objects.exclude(status=ProgramStatus.Deleted)

            queryset = self.get_serializer_class().prefetch_queryset(
                queryset=queryset,
                course_runs=course_runs,
                partner=partner,
                programs=programs,
            )
        if pub_q and edit_mode:
            return queryset.filter(Q(key__icontains=pub_q) | Q(title__icontains=pub_q)).order_by(Lower('key'))

        return queryset.order_by(Lower('key'))
示例#5
0
 def has_permission(self, request, view):
     if request.method == 'POST':
         org = request.data.get('org')
         if not org:
             # Fail happily because OPTIONS goes down this path too with a fake POST.
             # If this is a real POST, we'll complain about the missing org in the view.
             return True
         return CourseEditor.can_create_course(request.user, org)
     else:
         return True  # other write access attempts will be caught by object permissions below
示例#6
0
 def has_permission(self, request, view):
     if request.method in SAFE_METHODS:
         return True
     else:
         org = request.data.get('org')
         if not org:
             # Fail happily because OPTIONS goes down this path too with a fake POST.
             # If this is a real POST, we'll complain about the missing org in the view.
             return True
         return CourseEditor.can_create_course(request.user, org)
示例#7
0
 def has_permission(self, request, view):
     if self.django_perms.has_permission(request, view):
         return True
     elif request.user.is_staff:
         return True
     elif request.method == 'POST':
         course = request.data.get('course')
         if not course:
             return False
         org, _ = parse_course_key_fragment(course)
         return org and CourseEditor.can_create_course(request.user, org)
     else:
         return True  # other write access attempts will be caught by object permissions below
示例#8
0
    def has_permission(self, request, view):
        if request.method in SAFE_METHODS:
            return True
        else:
            course = request.data.get('course')
            if not course:
                # Fail happily because OPTIONS goes down this path too with a fake POST.
                # If this is a real POST, we'll complain about the missing course in the view.
                return True

            # We could do a lookup on the course from the request above, but the logic already exists in the view so we
            # use that to avoid writing it twice
            return CourseEditor.is_course_editable(request.user, view.course)
示例#9
0
def send_email_to_editors(course_run, template_name, subject, context=None):
    """ Send a specific email template to all editors for a course run.

        Arguments:
            course_run (Object): CourseRun object
            template_name (str): path to template without filename extension
            subject (str): subject line for the email
            context (dict): additional context for the template
    """
    # Model imports here to avoid a circular import
    from course_discovery.apps.course_metadata.models import CourseEditor  # pylint: disable=import-outside-toplevel

    editors = CourseEditor.course_editors(course_run.course)
    send_email(template_name, subject, editors, _('course team'), context=context, course_run=course_run)
示例#10
0
    def get_queryset(self):
        partner = self.request.site.partner
        q = self.request.query_params.get('q')
        edit_mode = get_query_param(
            self.request,
            'editable') or self.request.method not in SAFE_METHODS

        if edit_mode and q:
            raise EditableAndQUnsupported()

        # Start with either draft versions or real versions of the courses
        if edit_mode:
            # TODO: For now hardcode in draft=True until we choose to roll this out live, DISCO-818
            queryset = Course.objects.filter_drafts(draft=True)
            queryset = CourseEditor.editable_courses(self.request.user,
                                                     queryset)
        else:
            queryset = self.queryset

        if q:
            queryset = Course.search(q, queryset=queryset)
            queryset = self.get_serializer_class().prefetch_queryset(
                queryset=queryset, partner=partner)
        else:
            if edit_mode:
                course_runs = CourseRun.objects.filter_drafts(
                    course__partner=partner)
            else:
                course_runs = CourseRun.objects.filter(course__partner=partner)

            if not get_query_param(self.request, 'include_hidden_course_runs'):
                course_runs = course_runs.exclude(hidden=True)

            if get_query_param(self.request, 'marketable_course_runs_only'):
                course_runs = course_runs.marketable().active()

            if get_query_param(
                    self.request,
                    'marketable_enrollable_course_runs_with_archived'):
                course_runs = course_runs.marketable().enrollable()

            if get_query_param(self.request, 'published_course_runs_only'):
                course_runs = course_runs.filter(
                    status=CourseRunStatus.Published)

            queryset = self.get_serializer_class().prefetch_queryset(
                queryset=queryset, course_runs=course_runs, partner=partner)

        return queryset.order_by(Lower('key'))
示例#11
0
 def has_permission(self, request, view):
     if self.django_perms.has_permission(request, view):
         return True
     elif request.user.is_staff:
         return True
     elif request.method == 'POST':
         course = request.data.get('course')
         if not course:
             # Fail happily because OPTIONS goes down this path too with a fake POST.
             # If this is a real POST, we'll complain about the missing course in the view.
             return True
         org, _ = parse_course_key_fragment(course)
         return org and CourseEditor.can_create_course(request.user, org)
     else:
         return True  # other write access attempts will be caught by object permissions below
示例#12
0
def send_email_for_comment(comment, course, author):
    """ Send the emails for a comment.

        Arguments:
            comment (Dict): Comment dict returned from salesforce.py
            course (Course): Course object for the comment
            author (User): User object who made the post request
    """
    # Model imports here to avoid a circular import
    from course_discovery.apps.course_metadata.models import CourseEditor

    subject = _('Comment added: {title}').format(title=course.title)

    org = course.authoring_organizations.first()
    project_coordinator = get_project_coordinator(org)
    recipients = list(CourseEditor.course_editors(course))
    if project_coordinator:
        recipients.append(project_coordinator)

    # remove email of comment owner if exists
    recipients = filter(lambda x: x.email != author.email, recipients)

    context = {
        'comment_message':
        comment.get('comment'),
        'user_name':
        author.username,
        'course_name':
        course.title,
        'comment_date':
        dateutil.parser.parse(comment.get('created')),
        'page_url':
        '{url}/courses/{path}'.format(
            url=course.partner.publisher_url.strip('/'), path=course.uuid)
    }

    try:
        send_email('course_metadata/email/comment',
                   subject,
                   recipients,
                   '',
                   course=course,
                   context=context,
                   project_coordinator=project_coordinator)
    except Exception:  # pylint: disable=broad-except
        logger.exception(
            'Failed to send email notifications for comment on course %s',
            course.uuid)
示例#13
0
 def has_object_permission(self, request, view, obj):
     if request.method in SAFE_METHODS:
         return True
     else:
         return CourseEditor.is_course_editable(request.user, obj.course)
示例#14
0
 def has_permission(self, request, view):
     if request.method == 'POST':
         org = request.data.get('org')
         return org and CourseEditor.can_create_course(request.user, org)
     else:
         return True  # other write access attempts will be caught by object permissions below
 def get_queryset(self):
     return CourseEditor.editors_for_user(self.request.user)