-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcreate_lessons_by_topic.py
164 lines (137 loc) · 6.57 KB
/
create_lessons_by_topic.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# import kolibri and django to ensure that the script runs in kolibri shell
import kolibri # noqa F401
import django
import random
import uuid
from colors import *
from helpers import (
get_channels_in_module,
get_channels_in_level,
get_facility_or_default,
get_or_create_classroom,
get_or_create_learnergroup,
get_admins_for_facility,
)
django.setup()
# import all the helper functions
from kolibri.core.auth.models import Facility, FacilityUser # noqa E402
from kolibri.core.lessons.models import Lesson, LessonAssignment # noqa E402
from kolibri.core.content.models import ContentNode, ChannelMetadata # noqa E402
def create_lessons_by_topic(
classroomname,
facilityname=None,
levels=["Level 1", "Level 2", "Level 3", "Level 4", "Level 5", "Level 6"],
):
"""Function to create 1 Lesson for each topic in each Channel for a specified Module, then assign them to a Classroom.
The Classroom object is created if it does not exist.
Args:
modulename (string): name of the module
classroomname (string): name of the class
facilityname (string): name of the facility (default facility if not specified)
Returns:
None
"""
# get a reference to the facility to create the lessons in
facility_for_lessons = get_facility_or_default(facilityname)
# set the seed that will be used to generate the sequence of lesson_ids
seed = random.randint(1, 100)
# get or create the class to create the lessons for
# store a reference to the classroom object if it is created
class_for_lessons = get_or_create_classroom(classroomname, facilityname)
# get a list of the admin and coach accounts on the device
# use raw query because __in ORM method doesn't work with uuid data type
admin_for_lessons = get_admins_for_facility(facility_for_lessons)[0]
for level in levels:
# get all channels with the module passed in
channels = get_channels_in_level(level)
# get a list of all the channel ids for the channels in the above query
channel_ids = [channel.id for channel in channels]
# loop through the channels with the module passed in
for channel_id in channel_ids:
# get the channel name for use in the inner loop
channel_name = str(ChannelMetadata.objects.get(id=channel_id).name)
# channels are found in topics but have no parent_id and id == parent_id
# get all topics by getting all contentnodes of type topic which fulfil criteria above
topics = (
ContentNode.objects.filter(kind="topic", parent_id=channel_id)
.exclude(parent_id__isnull=True)
.order_by("sort_order")
)
# get contentnode_ids of all the topics as an array
topic_ids = [topic.id for topic in topics]
# begin looping through topics
for topic_id in topic_ids:
# create the title for the lesson using the title of the topic + the channel name
lesson_title = (
str(ContentNode.objects.get(id=topic_id).title)
+ " - "
+ channel_name
)
# lesson titles have a constraint of 50 characters
# if this is exceeded, remove the difference from the topic title
if len(lesson_title) > 50:
diff_len = len(lesson_title) - 50
lesson_title = (
str(ContentNode.objects.get(id=topic_id).title[:-diff_len])
+ " - "
+ channel_name
)
# instantiate a new lesson object for the topic
# title, collection and created by are needed to instantiate a lesson object. Other attributes can be set later
# set the title of the lesson as the title of the topic + the channel name
lesson_for_topic = Lesson.objects.create(
id=uuid.uuid1(node=None, clock_seq=seed),
title=lesson_title,
collection=class_for_lessons,
created_by=admin_for_lessons,
_morango_source_id=uuid.uuid4(),
)
# get the child nodes of the topic
child_nodes = ContentNode.objects.filter(parent_id=topic_id)
# create an array of the resources for the lesson
# structure of content resource in a lesson
# {
# contentnode_id: string,
# content_id: string,
# channel_id: string
# }
lesson_for_topic.resources = [
{
"contentnode_id": node.id,
"content_id": node.content_id,
"channel_id": node.channel_id,
}
for node in child_nodes
]
# set the morango partition the lesson
lesson_for_topic._morango_partition = (
lesson_for_topic.calculate_partition()
)
# inform the user that the lesson has been created
print_colored(
"Created Lesson {} with {} resources".format(
lesson_title, len(lesson_for_topic.resources)
),
colors.fg.lightblue,
)
# get or create a group with the same name as the channel and assign the lesson to it
group_for_lesson = get_or_create_learnergroup(
level, classroomname, facilityname
)
# create a new lesson assignment object
LessonAssignment.objects.create(
lesson=lesson_for_topic,
collection=group_for_lesson,
assigned_by=admin_for_lessons,
)
# inform the user that the lesson has been created
print_colored(
"Lesson {} successfully assigned to Group {}".format(
lesson_title, str(group_for_lesson.name)
),
colors.fg.lightblue,
)
# activate the lesson
lesson_for_topic.is_active = True
# save the lesson object
lesson_for_topic.save()