Skip to content
Snippets Groups Projects
Commit 087250cf authored by Amit's avatar Amit Committed by Jeremy Bowman
Browse files

INCR-250: Make compatible with Python 3.x without breaking Python 2.7… (#20534)

* INCR-250: Make compatible with Python 3.x without breaking Python 2.7 support --> openedx/core/djangoapps/programs

* INCR-250: Disable pylint warning and replace _f placeholder with actual name

* INCR-250: pylint format correction and fix over length line limit
parent de5d25ec
No related merge requests found
......@@ -8,7 +8,9 @@ if and only if the service is deployed in the Open edX installation.
To ensure maximum separation of concerns, and a minimum of interdependencies,
this package should be kept small, thin, and stateless.
"""
from openedx.core.djangoapps.waffle_utils import (WaffleSwitch, WaffleSwitchNamespace)
from __future__ import absolute_import
from openedx.core.djangoapps.waffle_utils import WaffleSwitch, WaffleSwitchNamespace
PROGRAMS_WAFFLE_SWITCH_NAMESPACE = WaffleSwitchNamespace(name='programs')
......
"""
django admin pages for program support models
"""
from __future__ import absolute_import
from config_models.admin import ConfigurationModelAdmin
from django.contrib import admin
......
"""
Programs Configuration
"""
from __future__ import absolute_import
from django.apps import AppConfig
......
"""Models providing Programs support for the LMS and Studio."""
from __future__ import absolute_import
from config_models.models import ConfigurationModel
from django.db import models
from django.utils.translation import ugettext_lazy as _
......
"""
This module contains signals / handlers related to programs.
"""
from __future__ import absolute_import
import logging
from django.dispatch import receiver
......
# -*- coding: utf-8 -*-
"""Helper functions for working with Programs."""
from __future__ import absolute_import
import datetime
import logging
from collections import defaultdict
from copy import deepcopy
from itertools import chain
from urlparse import urljoin, urlparse, urlunparse
import six
from six.moves.urllib.parse import urljoin, urlparse, urlunparse # pylint: disable=import-error
from dateutil.parser import parse
from django.conf import settings
from django.contrib.auth import get_user_model
......@@ -25,7 +28,7 @@ from lms.djangoapps.certificates.models import GeneratedCertificate
from lms.djangoapps.commerce.utils import EcommerceService
from lms.djangoapps.courseware.access import has_access
from lms.djangoapps.grades.api import CourseGradeFactory
from openedx.core.djangoapps.catalog.utils import get_programs, get_fulfillable_course_runs_for_entitlement
from openedx.core.djangoapps.catalog.utils import get_fulfillable_course_runs_for_entitlement, get_programs
from openedx.core.djangoapps.certificates.api import available_date_for_certificate
from openedx.core.djangoapps.commerce.utils import ecommerce_api_client
from openedx.core.djangoapps.content.course_overviews.models import CourseOverview
......@@ -95,7 +98,7 @@ class ProgramProgressMeter(object):
self.course_run_ids = []
for enrollment in self.enrollments:
# enrollment.course_id is really a CourseKey (╯ಠ_ಠ)╯︵ ┻━┻
enrollment_id = unicode(enrollment.course_id)
enrollment_id = six.text_type(enrollment.course_id)
mode = enrollment.mode
if mode == CourseMode.NO_ID_PROFESSIONAL_MODE:
mode = CourseMode.PROFESSIONAL
......@@ -140,7 +143,7 @@ class ProgramProgressMeter(object):
program_list.append(program)
# Sort programs by title for consistent presentation.
for program_list in inverted_programs.itervalues():
for program_list in six.itervalues(inverted_programs):
program_list.sort(key=lambda p: p['title'])
return inverted_programs
......@@ -326,14 +329,16 @@ class ProgramProgressMeter(object):
if modes_match and certificate_api.is_passing_status(certificate.status):
course_overview = CourseOverview.get_from_id(key)
available_date = available_date_for_certificate(course_overview, certificate)
earliest_course_run_date = min(filter(None, [available_date, earliest_course_run_date]))
earliest_course_run_date = min(
[date for date in [available_date, earliest_course_run_date] if date]
)
# If we're missing a cert for a course, the program isn't completed and we should just bail now
if earliest_course_run_date is None:
return None
# Keep the catalog course date if it's the latest one
program_available_date = max(filter(None, [earliest_course_run_date, program_available_date]))
program_available_date = max([date for date in [earliest_course_run_date, program_available_date] if date])
return program_available_date
......@@ -427,7 +432,7 @@ class ProgramProgressMeter(object):
completed_runs, failed_runs = [], []
for certificate in course_run_certificates:
course_data = {
'course_run_id': unicode(certificate['course_key']),
'course_run_id': six.text_type(certificate['course_key']),
'type': self._certificate_mode_translation(certificate['type']),
}
......@@ -592,7 +597,7 @@ class ProgramDataExtender(object):
# Here we check the entitlements' expired_at_datetime property rather than filter by the expired_at attribute
# to ensure that the expiration status is as up to date as possible
entitlements = [e for e in entitlements if not e.expired_at_datetime]
courses_with_entitlements = set(unicode(entitlement.course_uuid) for entitlement in entitlements)
courses_with_entitlements = set(six.text_type(entitlement.course_uuid) for entitlement in entitlements)
return [course for course in courses if course['uuid'] not in courses_with_entitlements]
def _filter_out_courses_with_enrollments(self, courses):
......@@ -610,10 +615,10 @@ class ProgramDataExtender(object):
is_active=True,
mode__in=self.data['applicable_seat_types']
)
course_runs_with_enrollments = set(unicode(enrollment.course_id) for enrollment in enrollments)
course_runs_with_enrollments = set(six.text_type(enrollment.course_id) for enrollment in enrollments)
courses_without_enrollments = []
for course in courses:
if all(unicode(run['key']) not in course_runs_with_enrollments for run in course['course_runs']):
if all(six.text_type(run['key']) not in course_runs_with_enrollments for run in course['course_runs']):
courses_without_enrollments.append(course)
return courses_without_enrollments
......@@ -805,7 +810,7 @@ class ProgramMarketingDataExtender(ProgramDataExtender):
self.data['instructor_ordering'] = []
sorted_instructor_names = [
' '.join(filter(None, (instructor['given_name'], instructor['family_name'])))
' '.join([name for name in (instructor['given_name'], instructor['family_name']) if name])
for instructor in self.data['instructor_ordering']
]
instructors_to_be_sorted = [
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment