rapid-router 5.18.0__py2.py3-none-any.whl → 7.6.8__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. example_project/rapid_router_test_settings.py +19 -7
  2. example_project/settings.py +21 -8
  3. example_project/urls.py +5 -6
  4. game/__init__.py +1 -1
  5. game/admin.py +7 -2
  6. game/character.py +8 -0
  7. game/decor.py +40 -0
  8. game/end_to_end_tests/base_game_test.py +34 -27
  9. game/end_to_end_tests/editor_page.py +15 -0
  10. game/end_to_end_tests/game_page.py +88 -20
  11. game/end_to_end_tests/selenium_test_case.py +1 -20
  12. game/end_to_end_tests/test_cow_crashes.py +3 -5
  13. game/end_to_end_tests/test_level_editor.py +273 -10
  14. game/end_to_end_tests/test_level_selection.py +25 -3
  15. game/end_to_end_tests/test_play_through.py +222 -127
  16. game/end_to_end_tests/test_python_levels.py +41 -7
  17. game/end_to_end_tests/test_saving_workspace.py +2 -1
  18. game/forms.py +7 -1
  19. game/level_management.py +26 -11
  20. game/messages.py +899 -337
  21. game/migrations/0001_squashed_0025_levels_ordering_pt1.py +19 -1
  22. game/migrations/0026_levels_pt2.py +13 -2
  23. game/migrations/0032_cannot_turn_left_level.py +13 -2
  24. game/migrations/0033_recursion_level.py +13 -2
  25. game/migrations/0034_joes_level.py +13 -2
  26. game/migrations/0035_disable_route_score_level_70.py +0 -2
  27. game/migrations/0036_level_score_73.py +0 -2
  28. game/migrations/0037_level_score_79.py +0 -2
  29. game/migrations/0038_level_score_40.py +0 -1
  30. game/migrations/0042_level_score_73.py +0 -2
  31. game/migrations/0048_add_cow_field_and_blocks.py +0 -2
  32. game/migrations/0049_level_score_34.py +0 -2
  33. game/migrations/0050_level_score_40.py +0 -2
  34. game/migrations/0051_level_score_49.py +0 -1
  35. game/migrations/0086_loop_levels.py +13 -2
  36. game/migrations/0092_disable_algo_score_in_custom_levels.py +28 -0
  37. game/migrations/0093_alter_level_character_name.py +18 -0
  38. game/migrations/0094_add_hint_lesson_subtitle_to_levels.py +28 -0
  39. game/migrations/0095_level_commands.py +18 -0
  40. game/migrations/0096_alter_level_commands.py +18 -0
  41. game/migrations/0097_add_python_den_levels.py +1515 -0
  42. game/migrations/0098_add_episode_link_fields.py +44 -0
  43. game/migrations/0099_python_episodes_links.py +103 -0
  44. game/migrations/0100_reorder_python_levels.py +179 -0
  45. game/migrations/0101_rename_episodes.py +45 -0
  46. game/migrations/0102_reoder_episodes_13_14.py +136 -0
  47. game/migrations/0103_level_1015_solution.py +26 -0
  48. game/migrations/0104_remove_level_direct_drive.py +17 -0
  49. game/migrations/0105_delete_invalid_attempts.py +18 -0
  50. game/migrations/0106_fields_to_snake_case.py +48 -0
  51. game/migrations/0107_rename_worksheet_link_episode_student_worksheet_link.py +18 -0
  52. game/migrations/0108_episode_indy_worksheet_link.py +18 -0
  53. game/migrations/0109_create_episodes_23_and_24.py +99 -0
  54. game/migrations/0110_remove_episode_indy_worksheet_link_and_more.py +100 -0
  55. game/migrations/0111_create_worksheets.py +149 -0
  56. game/migrations/0112_worksheet_locked_classes.py +21 -0
  57. game/migrations/0113_level_needs_approval.py +18 -0
  58. game/migrations/0114_default_and_non_student_levels_no_approval.py +31 -0
  59. game/migrations/0115_level_level__default_does_not_need_approval.py +22 -0
  60. game/migrations/0116_update_worksheet_video_links.py +68 -0
  61. game/migrations/0117_update_solutions_to_if_else.py +61 -0
  62. game/models.py +127 -17
  63. game/permissions.py +51 -19
  64. game/python_den_urls.py +26 -0
  65. game/random_road.py +9 -9
  66. game/serializers.py +12 -17
  67. game/static/django_reverse_js/js/reverse.js +171 -0
  68. game/static/game/css/LilitaOne-Regular.ttf +0 -0
  69. game/static/game/css/backgrounds.css +8 -12
  70. game/static/game/css/dataTables.custom.css +3 -2
  71. game/static/game/css/editor.css +47 -0
  72. game/static/game/css/game.css +37 -43
  73. game/static/game/css/game_screen.css +16 -0
  74. game/static/game/css/level_editor.css +5 -0
  75. game/static/game/css/level_selection.css +17 -2
  76. game/static/game/image/Python_Den_hero_student.png +0 -0
  77. game/static/game/image/Python_levels_page.svg +1954 -0
  78. game/static/game/image/characters/front_view/Electric_van.svg +448 -0
  79. game/static/game/image/characters/top_view/Electric_van.svg +448 -0
  80. game/static/game/image/decor/city/solar_panel.svg +1200 -0
  81. game/static/game/image/decor/farm/solar_panel.svg +86 -0
  82. game/static/game/image/decor/grass/solar_panel.svg +86 -0
  83. game/static/game/image/decor/snow/solar_panel.svg +173 -0
  84. game/static/game/image/electric_van.svg +448 -0
  85. game/static/game/image/icons/description.svg +1 -0
  86. game/static/game/image/icons/hint.svg +1 -0
  87. game/static/game/image/icons/python.svg +1 -1
  88. game/static/game/image/pigeon.svg +684 -0
  89. game/static/game/image/python_den_header.svg +19 -0
  90. game/static/game/js/animation.js +65 -24
  91. game/static/game/js/blockly/msg/js/bg.js +52 -1
  92. game/static/game/js/blockly/msg/js/ca.js +52 -1
  93. game/static/game/js/blockly/msg/js/en-gb.js +2 -0
  94. game/static/game/js/blockly/msg/js/en.js +2 -0
  95. game/static/game/js/blockly/msg/js/es.js +52 -1
  96. game/static/game/js/blockly/msg/js/fr.js +2 -0
  97. game/static/game/js/blockly/msg/js/hi.js +2 -0
  98. game/static/game/js/blockly/msg/js/it.js +52 -1
  99. game/static/game/js/blockly/msg/js/pl.js +52 -1
  100. game/static/game/js/blockly/msg/js/pt-br.js +52 -1
  101. game/static/game/js/blockly/msg/js/ru.js +52 -1
  102. game/static/game/js/blockly/msg/js/ur.js +52 -1
  103. game/static/game/js/blocklyCustomBlocks.js +93 -52
  104. game/static/game/js/button.js +12 -0
  105. game/static/game/js/cow.js +11 -7
  106. game/static/game/js/drawing.js +68 -29
  107. game/static/game/js/editor.js +23 -0
  108. game/static/game/js/game.js +74 -110
  109. game/static/game/js/level_editor.js +646 -274
  110. game/static/game/js/level_moderation.js +33 -2
  111. game/static/game/js/level_selection.js +1 -1
  112. game/static/game/js/loadLanguages.js +2 -2
  113. game/static/game/js/model.js +32 -2
  114. game/static/game/js/pythonControl.js +14 -1
  115. game/static/game/js/scoreboard.js +0 -37
  116. game/static/game/js/scoreboardSharedLevels.js +48 -0
  117. game/static/game/js/skulpt/skulpt-stdlib.js +1 -1
  118. game/static/game/js/sound.js +52 -5
  119. game/static/game/raphael_image/characters/top_view/Electric_van.svg +448 -0
  120. game/static/game/raphael_image/decor/city/solar_panel.svg +1200 -0
  121. game/static/game/raphael_image/decor/farm/solar_panel.svg +86 -0
  122. game/static/game/raphael_image/decor/grass/solar_panel.svg +86 -0
  123. game/static/game/raphael_image/decor/snow/solar_panel.svg +173 -0
  124. game/static/game/raphael_image/pigeon.svg +685 -0
  125. game/static/game/sass/game.scss +2 -2
  126. game/static/game/sound/clown_horn.mp3 +0 -0
  127. game/static/game/sound/clown_horn.ogg +0 -0
  128. game/static/game/sound/electric_van_starting.mp3 +0 -0
  129. game/static/game/sound/electric_van_starting.ogg +0 -0
  130. game/static/game/sound/pigeon.mp3 +0 -0
  131. game/static/game/sound/pigeon.ogg +0 -0
  132. game/static/game/sound/sleigh_bells.mp3 +0 -0
  133. game/static/game/sound/sleigh_bells.ogg +0 -0
  134. game/static/game/sound/sleigh_crash.mp3 +0 -0
  135. game/static/game/sound/sleigh_crash.ogg +0 -0
  136. game/templates/game/base.html +34 -14
  137. game/templates/game/basenonav.html +11 -5
  138. game/templates/game/game.html +142 -38
  139. game/templates/game/level_editor.html +340 -236
  140. game/templates/game/level_moderation.html +19 -6
  141. game/templates/game/level_selection.html +18 -110
  142. game/templates/game/python_den_level_selection.html +291 -0
  143. game/templates/game/python_den_worksheet.html +101 -0
  144. game/templates/game/scoreboard.html +83 -64
  145. game/tests/test_level_editor.py +94 -26
  146. game/tests/test_level_selection.py +149 -46
  147. game/tests/test_python_den_worksheet.py +85 -0
  148. game/tests/test_scoreboard.py +34 -7
  149. game/tests/utils/level.py +32 -26
  150. game/theme.py +5 -5
  151. game/urls.py +199 -61
  152. game/views/language_code_conversions.py +86 -86
  153. game/views/level.py +155 -63
  154. game/views/level_editor.py +88 -55
  155. game/views/level_moderation.py +23 -0
  156. game/views/level_selection.py +116 -47
  157. game/views/level_solutions.py +491 -106
  158. game/views/scoreboard.py +76 -51
  159. game/views/worksheet.py +25 -0
  160. rapid_router-7.6.8.dist-info/METADATA +174 -0
  161. {rapid_router-5.18.0.dist-info → rapid_router-7.6.8.dist-info}/RECORD +164 -104
  162. {rapid_router-5.18.0.dist-info → rapid_router-7.6.8.dist-info}/WHEEL +1 -1
  163. example_project/manage.py +0 -10
  164. game/static/game/image/actions/go.svg +0 -18
  165. game/static/game/js/js-reverse.js +0 -14
  166. game/static/game/js/pqselect.min.js +0 -9
  167. game/static/game/js/widget-scroller.js +0 -906
  168. rapid_router-5.18.0.dist-info/METADATA +0 -17
  169. {rapid_router-5.18.0.dist-info → rapid_router-7.6.8.dist-info/licenses}/LICENSE.md +0 -0
  170. {rapid_router-5.18.0.dist-info → rapid_router-7.6.8.dist-info}/top_level.txt +0 -0
@@ -1,7 +1,6 @@
1
1
  /* global showPopupConfirmation */
2
2
 
3
3
  var levelID;
4
- var classID;
5
4
  var students;
6
5
 
7
6
  var saving = new ocargo.Saving();
@@ -57,6 +56,27 @@ jQuery.extend(jQuery.fn.dataTableExt.oSort, {
57
56
  },
58
57
  });
59
58
 
59
+ approveLevel = function (id, callback, errorCallback) {
60
+ csrftoken = Cookies.get('csrftoken');
61
+ $.ajax({
62
+ url: Urls.approve_level(id),
63
+ type: 'POST',
64
+ dataType: 'json',
65
+ data: {csrfmiddlewaretoken: csrftoken},
66
+ beforeSend: function (xhr, settings) {
67
+ if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
68
+ xhr.setRequestHeader("X-CSRFToken", csrftoken);
69
+ }
70
+ },
71
+ success: function (json) {
72
+ callback();
73
+ },
74
+ error: function (xhr, errmsg, err) {
75
+ errorCallback(xhr.status + ": " + errmsg + " " + err + " " + xhr.responseText);
76
+ }
77
+ });
78
+ };
79
+
60
80
  $(document).ready(function () {
61
81
  $(".delete").click(function () {
62
82
  levelID = this.getAttribute("value");
@@ -67,6 +87,17 @@ $(document).ready(function () {
67
87
  window.location.href = Urls.play_custom_level(this.getAttribute("value"));
68
88
  });
69
89
 
90
+ $(".approve").click(function () {
91
+ levelID = this.getAttribute("value");
92
+ approveLevel(levelID)
93
+ // Waiting half a second before redirecting because otherwise the Approve button doesn't become disabled
94
+ setTimeout(
95
+ function(){
96
+ window.location.href = Urls.level_moderation();
97
+ },
98
+ 500);
99
+ });
100
+
70
101
  $("#clear-classes").on("click", () => {
71
102
  $('[id^="id_classes_"],#select-all-classes').prop("checked", false);
72
103
  });
@@ -105,7 +136,7 @@ $(document).ready(function () {
105
136
  {
106
137
  orderable: false,
107
138
  searchable: false,
108
- targets: [-1, -2], // Play and Delete columns
139
+ targets: [-1, -2, -3], // Play, Approve and Delete columns
109
140
  },
110
141
  {
111
142
  type: "student-with-teacher",
@@ -106,4 +106,4 @@ document.addEventListener("DOMContentLoaded", function() {
106
106
  });
107
107
  });
108
108
 
109
- });
109
+ });
@@ -11,11 +11,11 @@ function loadLanguage(path, langStr, callback) {
11
11
  }
12
12
  };
13
13
  xobj.send(null);
14
- };
14
+ }
15
15
 
16
16
  function reloadWorkspace(workspace) {
17
17
  var blocklyDom = Blockly.Xml.workspaceToDom(workspace);
18
18
  workspace.clear();
19
19
  Blockly.Xml.domToWorkspace(blocklyDom, workspace);
20
20
  workspace.updateToolbox(BLOCKLY_XML);
21
- };
21
+ }
@@ -127,7 +127,8 @@ ocargo.Model.prototype.getPreviousCoordinate = function() {
127
127
 
128
128
  ocargo.Model.prototype.moveVan = function(nextNode, action) {
129
129
  // Crash?
130
- let currentNodeHasCow = this.getCowForNode(this.van.getPosition().currentNode, [ocargo.Cow.ACTIVE, ocargo.Cow.READY]);
130
+ let checkedNode = action == "WAIT" ? this.van.getPosition().previousNode : this.van.getPosition().currentNode
131
+ let currentNodeHasCow = this.getCowForNode(checkedNode, [ocargo.Cow.ACTIVE, ocargo.Cow.READY]);
131
132
 
132
133
  if (currentNodeHasCow) {
133
134
  handleCrash(this, gettext('You ran into a cow! '),
@@ -161,11 +162,13 @@ ocargo.Model.prototype.moveVan = function(nextNode, action) {
161
162
 
162
163
  ocargo.game.sendAttempt(0);
163
164
 
165
+ let noFuelMessage = CHARACTER_NAME == "Electric van" ? 'Your battery ran out of charge!' : 'You ran out of fuel!'
166
+
164
167
  ocargo.animation.appendAnimation({
165
168
  type: 'popup',
166
169
  popupType: 'FAIL',
167
170
  failSubtype: 'OUT_OF_FUEL',
168
- popupMessage: gettext('You ran out of fuel! Try to find a shorter route to the destination.'),
171
+ popupMessage: gettext(noFuelMessage + ' Try to find a shorter route to the destination.'),
169
172
  popupHint: ocargo.game.registerFailure(),
170
173
  description: 'no fuel popup'
171
174
  });
@@ -384,6 +387,32 @@ ocargo.Model.prototype.deliver = function() {
384
387
  return false;
385
388
  }
386
389
  this.makeDelivery(destination, 'DELIVER');
390
+ } else {
391
+ ocargo.game.sendAttempt(0);
392
+ ocargo.animation.appendAnimation({
393
+ type: 'popup',
394
+ popupType: 'FAIL',
395
+ failSubtype: 'DELIVER_NON_DESTINATION',
396
+ popupMessage: gettext("You tried to deliver to a destination that doesn't exist."),
397
+ popupHint: ocargo.game.registerFailure(),
398
+ description: 'tried to deliver at non-destination'
399
+ });
400
+
401
+ ocargo.animation.appendAnimation({
402
+ type: 'callable',
403
+ functionType: 'playSound',
404
+ functionCall: ocargo.sound.failure,
405
+ description: 'failure sound'
406
+ });
407
+
408
+ ocargo.event.sendEvent("DeliverNonDestination", { levelName: LEVEL_NAME,
409
+ defaultLevel: DEFAULT_LEVEL,
410
+ workspace: ocargo.blocklyControl.serialize(),
411
+ failures: this.failures,
412
+ pythonWorkspace: ocargo.pythonControl.getCode()
413
+ });
414
+ this.reasonForTermination = 'DELIVER_AT_NON_DESTINATION';
415
+ return false;
387
416
  }
388
417
  return destination;
389
418
  };
@@ -401,6 +430,7 @@ ocargo.Model.prototype.sound_horn = function() {
401
430
  cow.queueLeaveAnimation(this, currentNode);
402
431
  cow.setInactive(this, currentNode);
403
432
  }
433
+ this.moveVan(this.van.getPosition().currentNode, 'SOUND_HORN');
404
434
  return true;
405
435
  };
406
436
 
@@ -129,9 +129,22 @@ ocargo.PythonControl = function () {
129
129
  }
130
130
 
131
131
  function outf(outputText) {
132
+ /** @type {string} */
133
+ let text = outputText
134
+
135
+ if (text.startsWith("ParseError: ")) {
136
+ text += "\nThis may be because your code has not been formatted correctly or you have not indented your code correctly."
137
+ } else if (text.startsWith("AttributeError: ")) {
138
+ text += "\nEnsure that the object has the method or property. Review the PY commands for help.\nYou may also be trying to import something that doesn't exist."
139
+ } else if (text.startsWith("NameError: ")) {
140
+ text += "\nName errors usually happen because you have misspelt a variable name. Double check your spelling."
141
+ } else if (text.startsWith("TypeError: ")) {
142
+ text += "\nType errors usually happen because you are trying to perform an illegal action on an object."
143
+ }
144
+
132
145
  ocargo.animation.appendAnimation({
133
146
  type: 'console',
134
- text: outputText
147
+ text
135
148
  });
136
149
  }
137
150
 
@@ -69,49 +69,12 @@ $(document).ready(function () {
69
69
  $(".previous").removeClass("paginate_button");
70
70
  });
71
71
 
72
- // Setup shared levels table
73
- let sharedLevelsTable = $("#sharedLevelsTable").DataTable({
74
- scrollY: false,
75
- scrollX: true,
76
- scrollCollapse: false,
77
- paging: true,
78
- deferRender: true,
79
- language: {
80
- emptyTable: "No data available in table",
81
- loadingRecords: "Loading...",
82
- processing: "Processing...",
83
- search: "Search:",
84
- zeroRecords: "No matching records found"
85
- },
86
- columnDefs: [
87
- {
88
- orderable: false,
89
- targets: "no-sort"
90
- }
91
- ]
92
- });
93
-
94
- new $.fn.dataTable.FixedColumns(sharedLevelsTable, {
95
- leftColumns: 2,
96
- });
97
-
98
- $("#sharedLevelsTable_next").append(" >");
99
-
100
- sharedLevelsTable.on("draw", () => {
101
- $("#sharedLevelsTable_next").append(" >");
102
- $("#sharedLevelsTable_previous").prepend("< ");
103
- $(".next").removeClass("paginate_button");
104
- $(".previous").removeClass("paginate_button");
105
- });
106
-
107
72
  $("#scoreboardSearch").on("keyup", function () {
108
73
  table.search(this.value).draw();
109
- sharedLevelsTable.search(this.value).draw();
110
74
  });
111
75
 
112
76
  $(window).on("load", function () {
113
77
  table.columns.adjust();
114
- sharedLevelsTable.columns.adjust();
115
78
  });
116
79
  }
117
80
 
@@ -0,0 +1,48 @@
1
+ $(document).ready(function () {
2
+ let scoreboardPresent = document.getElementById("scoreboardTable") !== null;
3
+
4
+ if (scoreboardPresent) {
5
+ // Setup shared levels table
6
+ let sharedLevelsTable = $("#sharedLevelsTable").DataTable({
7
+ scrollY: false,
8
+ scrollX: true,
9
+ scrollCollapse: false,
10
+ paging: true,
11
+ deferRender: true,
12
+ language: {
13
+ emptyTable: "No data available in table",
14
+ loadingRecords: "Loading...",
15
+ processing: "Processing...",
16
+ search: "Search:",
17
+ zeroRecords: "No matching records found"
18
+ },
19
+ columnDefs: [
20
+ {
21
+ orderable: false,
22
+ targets: "no-sort"
23
+ }
24
+ ]
25
+ });
26
+
27
+ new $.fn.dataTable.FixedColumns(sharedLevelsTable, {
28
+ leftColumns: 2,
29
+ });
30
+
31
+ $("#sharedLevelsTable_next").append(" >");
32
+
33
+ sharedLevelsTable.on("draw", () => {
34
+ $("#sharedLevelsTable_next").append(" >");
35
+ $("#sharedLevelsTable_previous").prepend("< ");
36
+ $(".next").removeClass("paginate_button");
37
+ $(".previous").removeClass("paginate_button");
38
+ });
39
+
40
+ $("#scoreboardSearch").on("keyup", function () {
41
+ sharedLevelsTable.search(this.value).draw();
42
+ });
43
+
44
+ $(window).on("load", function () {
45
+ sharedLevelsTable.columns.adjust();
46
+ });
47
+ }
48
+ });