Very rough cut at generating a course outline after publishing.
This commit is contained in:
committed by
Clinton Blackburn
parent
b3cc2f576f
commit
24fcab7f24
0
openedx/core/djangoapps/content/__init__.py
Normal file
0
openedx/core/djangoapps/content/__init__.py
Normal file
@@ -0,0 +1,5 @@
|
||||
from ratelimitbackend import admin
|
||||
|
||||
from .models import CourseStructure
|
||||
|
||||
admin.site.register(CourseStructure)
|
||||
@@ -0,0 +1,40 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
# Adding model 'CourseStructure'
|
||||
db.create_table('course_structures_coursestructure', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('created', self.gf('model_utils.fields.AutoCreatedField')(default=datetime.datetime.now)),
|
||||
('modified', self.gf('model_utils.fields.AutoLastModifiedField')(default=datetime.datetime.now)),
|
||||
('course_id', self.gf('xmodule_django.models.CourseKeyField')(max_length=255, db_index=True)),
|
||||
('version', self.gf('django.db.models.fields.CharField')(max_length=255)),
|
||||
('structure_json', self.gf('django.db.models.fields.TextField')()),
|
||||
))
|
||||
db.send_create_signal('course_structures', ['CourseStructure'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
# Deleting model 'CourseStructure'
|
||||
db.delete_table('course_structures_coursestructure')
|
||||
|
||||
|
||||
models = {
|
||||
'course_structures.coursestructure': {
|
||||
'Meta': {'object_name': 'CourseStructure'},
|
||||
'course_id': ('xmodule_django.models.CourseKeyField', [], {'max_length': '255', 'db_index': 'True'}),
|
||||
'created': ('model_utils.fields.AutoCreatedField', [], {'default': 'datetime.datetime.now'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'modified': ('model_utils.fields.AutoLastModifiedField', [], {'default': 'datetime.datetime.now'}),
|
||||
'structure_json': ('django.db.models.fields.TextField', [], {}),
|
||||
'version': ('django.db.models.fields.CharField', [], {'max_length': '255'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['course_structures']
|
||||
62
openedx/core/djangoapps/content/course_structures/models.py
Normal file
62
openedx/core/djangoapps/content/course_structures/models.py
Normal file
@@ -0,0 +1,62 @@
|
||||
import json
|
||||
|
||||
from django.db import models
|
||||
from django.dispatch import receiver
|
||||
from celery.task import task
|
||||
from model_utils.models import TimeStampedModel
|
||||
|
||||
from opaque_keys.edx.keys import CourseKey
|
||||
|
||||
from xmodule.modulestore.django import modulestore, SignalHandler
|
||||
from xmodule_django.models import CourseKeyField
|
||||
|
||||
class CourseStructure(TimeStampedModel):
|
||||
|
||||
course_id = CourseKeyField(max_length=255, db_index=True)
|
||||
version = models.CharField(max_length=255, blank=True, default="")
|
||||
|
||||
# Right now the only thing we do with the structure doc is store it and
|
||||
# send it on request. If we need to store a more complex data model later,
|
||||
# we can do so and build a migration. The only problem with a normalized
|
||||
# data model for this is that it will likely involve hundreds of rows, and
|
||||
# we'd have to be careful about caching.
|
||||
structure_json = models.TextField()
|
||||
|
||||
# Index together:
|
||||
# (course_id, version)
|
||||
# (course_id, created)
|
||||
|
||||
|
||||
def course_structure(course_key):
|
||||
course = modulestore().get_course(course_key, depth=None)
|
||||
blocks_stack = [course]
|
||||
blocks_dict = {}
|
||||
while blocks_stack:
|
||||
curr_block = blocks_stack.pop()
|
||||
children = curr_block.get_children() if curr_block.has_children else []
|
||||
blocks_dict[unicode(curr_block.scope_ids.usage_id)] = {
|
||||
"usage_key": unicode(curr_block.scope_ids.usage_id),
|
||||
"block_type": curr_block.category,
|
||||
"display_name": curr_block.display_name,
|
||||
"graded": curr_block.graded,
|
||||
"format": curr_block.format,
|
||||
"children": [unicode(ch.scope_ids.usage_id) for ch in children]
|
||||
}
|
||||
blocks_stack.extend(children)
|
||||
return {
|
||||
"root": unicode(course.scope_ids.usage_id),
|
||||
"blocks": blocks_dict
|
||||
}
|
||||
|
||||
@receiver(SignalHandler.course_published)
|
||||
def listen_for_course_publish(sender, course_key, **kwargs):
|
||||
update_course_structure(course_key)
|
||||
|
||||
@task()
|
||||
def update_course_structure(course_key):
|
||||
structure = course_structure(course_key)
|
||||
CourseStructure.objects.create(
|
||||
course_id=unicode(course_key),
|
||||
structure_json=json.dumps(structure),
|
||||
version="",
|
||||
)
|
||||
Reference in New Issue
Block a user