Skip to content

Instantly share code, notes, and snippets.

@awaisdar001
Last active July 6, 2021 12:26
Show Gist options
  • Save awaisdar001/13a62d5ed7f81afc2da6f3863db6cfcc to your computer and use it in GitHub Desktop.
Save awaisdar001/13a62d5ed7f81afc2da6f3863db6cfcc to your computer and use it in GitHub Desktop.
# Tasks
# Get course apps for a course [read]
# Backfill data for courses [first read call]
# Update a single app in the model.
# Update course apps whenever the course is published.
# Process => How this should work?
# CourseApps API => Update course app
# Course apps should update settings in the *modulestore* which will trigger
# course published signal.
from edx_django_utils.plugins import PluginManager
from course_apps.plugins import CourseAppsPluginManager
from django.db.models import Model
from django.dispatch import receiver
from xmodule.modulestore.django import SignalHandler, modulestore
class CourseAppsConfiguration(Model):
"""
Data model for Course Apps
"""
app_id: str = ''
course_id: str = ''
status: bool = False
updated_at = ''
updated_by = ''
@property
def plugin(self):
return CourseAppsPluginManager().get_plugin(self.app_id)
@property
def name(self):
return self.plugin.name
@property
def description(self):
return self.plugin.description
@property
def allowed_oprations(self):
return self.plugin.allowed_oprations
@property
def is_available(self):
return self.plugin.is_available
def get_all_available_apps_for_course(self, course_id):
available_course_apps = []
all_course_apps = self.get_all_apps_for_course(course_id, to_json=False)
for course_app in all_course_apps:
if course_app.plugin.is_available:
available_course_apps.append(course_app)
return available_course_apps
def get_all_apps_for_course(self, course_id, to_json=True, verify=True):
course_apps = self.objects.filter(course_id=course_id)
if not course_apps and verify:
self.backfill_course_apps(course_id)
course_apps = self.objects.filter(course_id=course_id)
if to_json:
return [app.to_json() for app in course_apps]
return course_apps
def get_app_for_course(self, app_id, course_id):
try:
return self.objects.get(app_id=app_id, course_id=course_id)
except CourseAppsConfiguration.DoesNotExist:
return self.backfill_course_app(app_id, course_id)
def update_app_status_for_course(self, app_id, course_id, status):
course_app = self.get_app_for_course(app_id, course_id)
course_app.status = status
course_app.save()
def to_json(self):
app = CourseAppsPluginManager().get_plugin(self.app_id)
return {
'app_id': self.app_id,
'app_name': app.name,
'status': self.status,
'app_description': app.description,
'is_available': app.is_available(self.course_id)
}
@classmethod
def backfill_course_apps(cls, course_id):
"""Use this method to backfill course apps in the model."""
# app = plugin(course_id, user_id)
for plugin in CourseAppsPluginManager.get_available_plugins().values():
course_app, __ = cls.backfill_course_app(
app_id=plugin.app_id,
course_id=course_id,
status=plugin.is_enabled(course_id),
)
@classmethod
def backfill_course_app(cls, app_id, course_id, **kwargs):
return cls().objects.get_or_create(
app_id=app_id,
course_id=course_id,
defaults=kwargs
)
# Signals.py
@receiver(SignalHandler.course_published)
def update_course_apps(sender, course_key, **kwargs): # pylint: disable=unused-argument
"""
Whenever the course is published, check for these changes
and sync them in the course apps model.
"""
course = modulestore().get_course(course_key)
course_apps = CourseAppsConfiguration().get_all_apps_for_course(course_key).order_by('app_id')
check_for_progress_tab_toggle(course, course_apps)
check_for_calculator_toggle(course, course_apps)
check_for_teams_toggle(course, course_apps)
check_for_notes_toggle(course, course_apps)
def check_for_progress_tab_toggle(course, course_apps):
"""Update course progress tab status."""
if course.hide_progress_tab != course_apps.get(app_id='progress').status:
CourseAppsConfiguration().update_app_status_for_course('progress', course.id, course.hide_progress_tab)
def check_for_calculator_toggle(course, course_apps):
"""Update course calculator tool status."""
def check_for_teams_toggle(course, course_apps):
"""Update course calculator tool status."""
def check_for_notes_toggle(course, course_apps):
"""Update course calculator tool status."""
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment