This introduces two admin actions: * Dump to CourseGraph (respect cache), and * Dump to CourseGraph (override cache) which allow admins to select a collection of courses from Django admin and dump them to the Neo4j instance specified by settings.COURSEGRAPH_CONNECTION, with or without respecting the cache (that is: whether the course has already been dumped since its last publishing).
124 lines
4.3 KiB
Python
124 lines
4.3 KiB
Python
"""
|
|
Admin site bindings for coursegraph
|
|
"""
|
|
import logging
|
|
|
|
from django.contrib import admin, messages
|
|
from django.utils.translation import gettext as _
|
|
from edx_django_utils.admin.mixins import ReadOnlyAdminMixin
|
|
|
|
from .models import CourseGraphCourseDump
|
|
from .tasks import ModuleStoreSerializer
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
|
|
@admin.action(
|
|
permissions=['change'],
|
|
description=_("Dump courses to CourseGraph (respect cache)"),
|
|
)
|
|
def dump_courses(modeladmin, request, queryset):
|
|
"""
|
|
Admin action to enqueue Dump-to-CourseGraph tasks for a set of courses,
|
|
excluding courses that haven't been published since they were last dumped.
|
|
|
|
queryset is a QuerySet of CourseGraphCourseDump objects, which are just
|
|
CourseOverview objects under the hood.
|
|
"""
|
|
all_course_keys = queryset.values_list('id', flat=True)
|
|
serializer = ModuleStoreSerializer(all_course_keys)
|
|
try:
|
|
submitted, skipped = serializer.dump_courses_to_neo4j()
|
|
# Unfortunately there is no unified base class for the reasonable
|
|
# exceptions we could expect from py2neo (connection unavailable, bolt protocol
|
|
# error, and so on), so we just catch broadly, show a generic error banner,
|
|
# and then log the exception for site operators to look at.
|
|
except Exception as err: # pylint: disable=broad-except
|
|
log.exception(
|
|
"Failed to enqueue CourseGraph dumps to Neo4j (respecting cache): %s",
|
|
", ".join(str(course_key) for course_key in all_course_keys),
|
|
)
|
|
modeladmin.message_user(
|
|
request,
|
|
_("Error enqueueing dumps for {} course(s): {}").format(
|
|
len(all_course_keys), str(err)
|
|
),
|
|
level=messages.ERROR,
|
|
)
|
|
return
|
|
if submitted:
|
|
modeladmin.message_user(
|
|
request,
|
|
_(
|
|
"Enqueued dumps for {} course(s). Skipped {} unchanged course(s)."
|
|
).format(len(submitted), len(skipped)),
|
|
level=messages.SUCCESS,
|
|
)
|
|
else:
|
|
modeladmin.message_user(
|
|
request,
|
|
_(
|
|
"Skipped all {} course(s), as they were unchanged.",
|
|
).format(len(skipped)),
|
|
level=messages.WARNING,
|
|
)
|
|
|
|
|
|
@admin.action(
|
|
permissions=['change'],
|
|
description=_("Dump courses to CourseGraph (override cache)")
|
|
)
|
|
def dump_courses_overriding_cache(modeladmin, request, queryset):
|
|
"""
|
|
Admin action to enqueue Dump-to-CourseGraph tasks for a set of courses
|
|
(whether or not they have been published recently).
|
|
|
|
queryset is a QuerySet of CourseGraphCourseDump objects, which are just
|
|
CourseOverview objects under the hood.
|
|
"""
|
|
all_course_keys = queryset.values_list('id', flat=True)
|
|
serializer = ModuleStoreSerializer(all_course_keys)
|
|
try:
|
|
submitted, _skipped = serializer.dump_courses_to_neo4j(override_cache=True)
|
|
# Unfortunately there is no unified base class for the reasonable
|
|
# exceptions we could expect from py2neo (connection unavailable, bolt protocol
|
|
# error, and so on), so we just catch broadly, show a generic error banner,
|
|
# and then log the exception for site operators to look at.
|
|
except Exception as err: # pylint: disable=broad-except
|
|
log.exception(
|
|
"Failed to enqueue CourseGraph Neo4j course dumps (overriding cache): %s",
|
|
", ".join(str(course_key) for course_key in all_course_keys),
|
|
)
|
|
modeladmin.message_user(
|
|
request,
|
|
_("Error enqueueing dumps for {} course(s): {}").format(
|
|
len(all_course_keys), str(err)
|
|
),
|
|
level=messages.ERROR,
|
|
)
|
|
return
|
|
modeladmin.message_user(
|
|
request,
|
|
_("Enqueued dumps for {} course(s).").format(len(submitted)),
|
|
level=messages.SUCCESS,
|
|
)
|
|
|
|
|
|
@admin.register(CourseGraphCourseDump)
|
|
class CourseGraphCourseDumpAdmin(ReadOnlyAdminMixin, admin.ModelAdmin):
|
|
"""
|
|
Model admin for "Course graph course dumps".
|
|
|
|
Just a read-only table with some useful metadata, allowing admin users to
|
|
select courses to be dumped to CourseGraph.
|
|
"""
|
|
list_display = [
|
|
'id',
|
|
'display_name',
|
|
'modified',
|
|
'enrollment_start',
|
|
'enrollment_end',
|
|
]
|
|
search_fields = ['id', 'display_name']
|
|
actions = [dump_courses, dump_courses_overriding_cache]
|