Skip to content

Commit d7067ef

Browse files
authored
Merge pull request #5782 from learningequality/hotfixes
2026.03.25 Patch release
2 parents 0d3365b + c2f2777 commit d7067ef

7 files changed

Lines changed: 58 additions & 13 deletions

File tree

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ migrate:
3838
# 4) Remove the management command from this `deploy-migrate` recipe
3939
# 5) Repeat!
4040
deploy-migrate:
41-
python contentcuration/manage.py fix_exercise_extra_fields
41+
echo "Nothing to do here!"
4242

4343
contentnodegc:
4444
python contentcuration/manage.py garbage_collect

contentcuration/contentcuration/frontend/shared/leUtils/Languages.js

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ const LanguagesMap = new Map([
184184
lang_subcode: null,
185185
readable_name: 'Brahui',
186186
native_name: 'Brahui',
187-
lang_direction: 'ltr',
187+
lang_direction: 'rtl',
188188
},
189189
],
190190
[
@@ -1130,7 +1130,7 @@ const LanguagesMap = new Map([
11301130
lang_subcode: null,
11311131
readable_name: 'Northern Pashto',
11321132
native_name: 'Northern Pashto',
1133-
lang_direction: 'ltr',
1133+
lang_direction: 'rtl',
11341134
},
11351135
],
11361136
[
@@ -1471,7 +1471,7 @@ const LanguagesMap = new Map([
14711471
lang_subcode: null,
14721472
readable_name: 'Southern Balochi',
14731473
native_name: 'Southern Balochi',
1474-
lang_direction: 'ltr',
1474+
lang_direction: 'rtl',
14751475
},
14761476
],
14771477
[
@@ -1626,7 +1626,7 @@ const LanguagesMap = new Map([
16261626
lang_subcode: null,
16271627
readable_name: 'Uighur; Uyghur',
16281628
native_name: 'Uy\u01a3urq\u0259, \u0626\u06c7\u064a\u063a\u06c7\u0631\u0686\u06d5\u200e',
1629-
lang_direction: 'ltr',
1629+
lang_direction: 'rtl',
16301630
},
16311631
],
16321632
[
@@ -2540,6 +2540,17 @@ const LanguagesMap = new Map([
25402540
lang_direction: 'rtl',
25412541
},
25422542
],
2543+
[
2544+
'prs',
2545+
{
2546+
id: 'prs',
2547+
lang_code: 'prs',
2548+
lang_subcode: null,
2549+
readable_name: 'Dari',
2550+
native_name: '\u062f\u0631\u06cc',
2551+
lang_direction: 'rtl',
2552+
},
2553+
],
25432554
[
25442555
'arq',
25452556
{
@@ -2604,7 +2615,7 @@ const LanguagesMap = new Map([
26042615
readable_name: 'Kashmiri',
26052616
native_name:
26062617
'\u0915\u0936\u094d\u092e\u0940\u0930\u0940, \u0643\u0634\u0645\u064a\u0631\u064a\u200e',
2607-
lang_direction: 'ltr',
2618+
lang_direction: 'rtl',
26082619
},
26092620
],
26102621
[
@@ -2740,7 +2751,7 @@ const LanguagesMap = new Map([
27402751
readable_name: 'Sindhi',
27412752
native_name:
27422753
'\u0938\u093f\u0928\u094d\u0927\u0940, \u0633\u0646\u068c\u064a\u060c \u0633\u0646\u062f\u06be\u06cc\u200e',
2743-
lang_direction: 'ltr',
2754+
lang_direction: 'rtl',
27442755
},
27452756
],
27462757
[
@@ -2784,7 +2795,7 @@ const LanguagesMap = new Map([
27842795
lang_subcode: null,
27852796
readable_name: 'Punjabi',
27862797
native_name: '\u0a2a\u0a70\u0a1c\u0a3e\u0a2c\u0a40',
2787-
lang_direction: 'ltr',
2798+
lang_direction: 'rtl',
27882799
},
27892800
],
27902801
[
@@ -3390,6 +3401,7 @@ export const LanguagesNames = {
33903401
HE: 'he',
33913402
UR: 'ur',
33923403
AR: 'ar',
3404+
PRS: 'prs',
33933405
ARQ: 'arq',
33943406
FA: 'fa',
33953407
PS: 'ps',

contentcuration/contentcuration/frontend/shared/leUtils/MasteryModels.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
const MasteryModels = new Set([
33
'do_all',
44
'm_of_n',
5+
'pre_post_test',
56
'num_correct_in_a_row_2',
67
'num_correct_in_a_row_3',
78
'num_correct_in_a_row_5',
@@ -15,6 +16,7 @@ export const MasteryModelsList = Array.from(MasteryModels);
1516
export const MasteryModelsNames = {
1617
DO_ALL: 'do_all',
1718
M_OF_N: 'm_of_n',
19+
PRE_POST_TEST: 'pre_post_test',
1820
NUM_CORRECT_IN_A_ROW_2: 'num_correct_in_a_row_2',
1921
NUM_CORRECT_IN_A_ROW_3: 'num_correct_in_a_row_3',
2022
NUM_CORRECT_IN_A_ROW_5: 'num_correct_in_a_row_5',

contentcuration/contentcuration/tests/test_contentnodes.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -824,6 +824,27 @@ def test_sync_after_no_changes(self):
824824
)
825825
self._assert_same_files(orig_video, cloned_video)
826826

827+
def test_sync_but_incomplete(self):
828+
orig_video, cloned_video = self._setup_original_and_deriative_nodes()
829+
orig_video.license_id = None
830+
orig_video.mark_complete()
831+
self.assertFalse(orig_video.complete)
832+
orig_video.save()
833+
834+
self.assertTrue(cloned_video.complete)
835+
836+
sync_node(
837+
cloned_video,
838+
sync_titles_and_descriptions=True,
839+
sync_resource_details=True,
840+
sync_files=True,
841+
sync_assessment_items=True,
842+
)
843+
844+
self.assertIsNotNone(cloned_video.license_id)
845+
cloned_video.mark_complete()
846+
self.assertTrue(cloned_video.complete)
847+
827848
def test_sync_with_subs(self):
828849
orig_video, cloned_video = self._setup_original_and_deriative_nodes()
829850
self._add_subs_to_video_node(orig_video, "fr")
@@ -868,6 +889,13 @@ def _create_video_node(self, title, parent, withsubs=False):
868889
node_id="aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
869890
)
870891
video_node = testdata.node(data, parent=parent)
892+
video_node.license_id = 9 # Special Permissions
893+
video_node.license_description = "Special permissions for testing"
894+
video_node.copyright_holder = "LE"
895+
# ensure the node is complete according to our logic
896+
video_node.mark_complete()
897+
self.assertTrue(video_node.complete)
898+
video_node.save()
871899

872900
if withsubs:
873901
self._add_subs_to_video_node(video_node, "fr")

contentcuration/contentcuration/utils/sync.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,14 @@ def sync_node(
5353
sync_assessment_items=False,
5454
):
5555
original_node = node.get_original_node()
56+
if not original_node.complete:
57+
logging.warning(
58+
f"Refusing to sync node {node.pk} from incomplete source node: {original_node.pk}"
59+
)
60+
return node
5661
if original_node.node_id != node.node_id: # Only update if node is not original
5762
logging.info(
58-
"----- Syncing: {} from {}".format(
59-
node.title, original_node.get_channel().name
60-
)
63+
f"----- Syncing: {node.title} from {original_node.get_channel().name}"
6164
)
6265
if sync_titles_and_descriptions:
6366
fields = [

requirements.in

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ djangorestframework==3.15.1
55
psycopg2-binary==2.9.10
66
django-js-reverse==0.10.2
77
django-registration==3.4
8-
le-utils==0.2.14
8+
le-utils==0.2.16
99
gunicorn==23.0.0
1010
django-postmark==0.1.6
1111
jsonfield==3.1.0

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ language-data==1.3.0
162162
# via langcodes
163163
latex2mathml==3.78.0
164164
# via -r requirements.in
165-
le-utils==0.2.14
165+
le-utils==0.2.16
166166
# via -r requirements.in
167167
marisa-trie==1.2.1
168168
# via language-data

0 commit comments

Comments
 (0)