Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions openedx/plugins/subscriber/MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include README.rst
include openedx.yaml
recursive-include subscriber *.py
5 changes: 5 additions & 0 deletions openedx/plugins/subscriber/openedx.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
lms:
django_apps:
- subscriber
urls:
- subscriber.urls
16 changes: 16 additions & 0 deletions openedx/plugins/subscriber/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from setuptools import setup, find_packages

setup(
name="platform-plugin-subscriber",
version="0.1.0",
packages=find_packages(),
include_package_data=True,
package_data={
"": ["openedx.yaml"],
},
entry_points={
"lms.djangoapp": [
"subscriber = subscriber.apps:SubscriberConfig",
],
},
)
1 change: 1 addition & 0 deletions openedx/plugins/subscriber/subscriber/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
default_app_config = "subscriber.apps.SubscriberConfig"
15 changes: 15 additions & 0 deletions openedx/plugins/subscriber/subscriber/apps.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
from django.apps import AppConfig


class SubscriberConfig(AppConfig):
name = "subscriber"

plugin_app = {
"url_config": {
"lms.djangoapp": {
"namespace": "subscriber",
"regex": "^api/subscriber/",
"relative_path": "urls",
}
}
}
42 changes: 42 additions & 0 deletions openedx/plugins/subscriber/subscriber/services.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
from common.djangoapps.student.models import CourseEnrollment

# POC-only: hardcoded subscription catalog
SUBSCRIPTION_COURSE_IDS = [
"course-v1:edX+DemoX+Demo_Course",
]


def get_categorized_courses(user):
"""
Fetch user's enrolled courses and categorize them
for the Subscriber Learner Dashboard.
"""

enrollments = CourseEnrollment.objects.filter(
user=user,
is_active=True
)

subscription_courses = []
upgradeable_courses = []
non_upgradeable_courses = []

# POC assumption: user is already a subscriber
user_is_subscriber = True

for enrollment in enrollments:
course_id = str(enrollment.course_id)

if course_id in SUBSCRIPTION_COURSE_IDS:
if user_is_subscriber:
subscription_courses.append(course_id)
else:
upgradeable_courses.append(course_id)
else:
non_upgradeable_courses.append(course_id)
Comment on lines +30 to +36
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the part that we should clarify.

Assume that SUBSCRIPTION_COURSE_IDS will eventually be an API call that we make to the Subscription catalog that another team will create.

From that payload, we'll need to check for each course enrollment:

  1. Is the course part of the Subscription catalog? If yes:
    a. Did the user fulfill either enrolling in the course after becoming a Subscriber or upgrading their audited course into their Subscription? (This is likely to mean that in the Enrollments payload we will know if the course is upgraded to a full-access.)
    • If yes to either, then this course falls under subscription_courses.
    • If no to either, then this course falls under upgradeable_courses
  2. If no, then the course falls under non_upgradeable_courses.

There's an additional tricky part that I haven't confirmed with Kelly, which is what happens if prior to being a Subscriber the user fully upgraded a course. Where does that course live in these three categories? If the course technically is part of the Subscription catalog, does it go under subscription_courses? If it doesn't, does it go under non_upgradeable_courses even though it indeed is upgraded already? Maybe that 3rd category would be more accurately called non_subscription_courses. I don't know yet.


return {
"subscription_courses": subscription_courses,
"upgradeable_courses": upgradeable_courses,
"non_upgradeable_courses": non_upgradeable_courses,
}
10 changes: 10 additions & 0 deletions openedx/plugins/subscriber/subscriber/urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
from django.urls import path
from .views import subscriber_courses

urlpatterns = [
path(
"dashboard/courses/",
subscriber_courses,
name="subscriber-dashboard-courses",
),
]
13 changes: 13 additions & 0 deletions openedx/plugins/subscriber/subscriber/views.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from django.http import JsonResponse
from django.contrib.auth.decorators import login_required
from .services import get_categorized_courses


@login_required
def subscriber_courses(request):
"""
API endpoint for Subscriber Learner Dashboard.
Returns user's enrolled courses grouped into categories.
"""
data = get_categorized_courses(request.user)
return JsonResponse(data)
Loading